From 2c40cc7868265137b8b8e0bbfc16f004d792c8cf Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 14:17:47 +0000 Subject: [PATCH 0001/1414] 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 0002/1414] 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 0003/1414] 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 0004/1414] 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 0005/1414] 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 0006/1414] 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 0007/1414] 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 0008/1414] 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 0009/1414] 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 0010/1414] 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 0011/1414] 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 0012/1414] 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 4931b0984b1a526c6c86a47b200c2dbb58d2fa50 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 3 Mar 2010 20:09:48 +0100 Subject: [PATCH 0013/1414] Network infrastructure --- commands/net.c | 296 ++++++++++++++++++++++++++++++++++++++++++ commands/probe.c | 2 +- conf/common.rmk | 6 + include/grub/device.h | 6 +- include/grub/err.h | 5 +- include/grub/net.h | 248 +++++++++++++++++++++++++++++------ kern/fs.c | 2 +- 7 files changed, 522 insertions(+), 43 deletions(-) create mode 100644 commands/net.c diff --git a/commands/net.c b/commands/net.c new file mode 100644 index 000000000..288ba4c2a --- /dev/null +++ b/commands/net.c @@ -0,0 +1,296 @@ +/* + * 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 + +struct grub_net_route *grub_net_routes = NULL; +struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; +struct grub_net_card *grub_net_cards = NULL; +struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; + +grub_err_t +grub_net_resolve_address (struct grub_net_network_level_protocol **prot, + char *name, + grub_net_network_level_address_t *addr) +{ + FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot) + { + grub_err_t err; + err = grub_net_resolve_address_in_protocol (*prot, name, addr); + if (err == GRUB_ERR_NET_BAD_ADDRESS) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("Unrecognised address %s"), + name); +} + +grub_err_t +grub_net_route_address (grub_net_network_level_address_t addr, + grub_net_network_level_address_t *gateway, + struct grub_net_network_level_interface **interf) +{ + struct grub_net_route *route; + int depth = 0; + int routecnt = 0; + struct grub_net_network_level_protocol *prot = NULL; + grub_net_network_level_address_t curtarget = addr; + + *gateway = addr; + + FOR_NET_ROUTES(route) + routecnt++; + + for (depth = 0; depth < routecnt + 2; depth++) + { + FOR_NET_ROUTES(route) + { + if (depth && prot != route->prot) + continue; + prot = route->prot; + if (!route->prot->match_net (route->target, curtarget)) + continue; + + if (route->is_gateway) + { + if (depth == 0) + *gateway = route->gw; + curtarget = route->gw; + break; + } + *interf = route->interface; + return GRUB_ERR_NONE; + } + if (route == NULL) + return grub_error (GRUB_ERR_NET_NO_ROUTE, "destination unreachable"); + } + + return grub_error (GRUB_ERR_NET_ROUTE_LOOP, "route loop detected"); +} + +static grub_err_t +grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_interface *inter; + + if (argc != 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[1])) + break; + if (inter == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); + + inter->protocol->fini (inter); + grub_net_network_level_interface_unregister (inter); + grub_free (inter->name); + grub_free (inter); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_card *card; + struct grub_net_network_level_protocol *prot; + grub_err_t err; + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inter; + + if (argc != 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); + + FOR_NET_CARDS (card) + if (grub_strcmp (card->name, args[1])) + break; + if (card == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); + + FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot) + if (grub_strcmp (prot->name, args[2])) + break; + + if (card == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); + + err = grub_net_resolve_address_in_protocol (prot, args[3], &addr); + if (err) + return err; + + inter = grub_zalloc (sizeof (*inter)); + if (!inter) + return grub_errno; + + inter->name = grub_strdup (args[0]); + inter->protocol = prot; + grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); + inter->card = card; + + err = prot->init (inter); + if (err) + { + grub_free (inter->name); + grub_free (inter); + return err; + } + grub_net_network_level_interface_register (inter); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_route *route; + struct grub_net_route **prev; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + for (prev = &grub_net_routes, route = *prev; route; prev = &((*prev)->next), + route = *prev) + if (grub_strcmp (route->name, args[0]) == 0) + { + *prev = route->next; + grub_free (route->name); + grub_free (route); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_protocol *prot; + struct grub_net_route *route; + + if (argc < 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("At least 3 arguments are expected")); + + route = grub_zalloc (sizeof (*route)); + if (!route) + return grub_errno; + + route->name = grub_strdup (args[0]); + if (!route->name) + { + grub_free (route); + return grub_errno; + } + + FOR_NET_NETWORK_LEVEL_PROTOCOLS(prot) + { + grub_err_t err; + err = prot->net_ntoa (args[1], &(route->target)); + if (err == GRUB_ERR_NET_BAD_ADDRESS) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + break; + } + + if (!prot) + { + grub_free (route->name); + grub_free (route); + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, + N_("Unrecognised address %s"), args[1]); + } + + if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) + { + grub_err_t err; + route->is_gateway = 1; + err = grub_net_resolve_address_in_protocol (prot, + args[3], &(route->gw)); + if (err) + { + grub_free (route->name); + grub_free (route); + return err; + } + } + else + { + struct grub_net_network_level_interface *inter; + route->is_gateway = 0; + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[2])) + break; + + if (!inter) + { + grub_free (route->name); + grub_free (route); + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Unrecognised interface %s"), args[2]); + } + route->interface = inter; + } + + grub_net_route_register (route); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; + +GRUB_MOD_INIT(net) +{ + cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, + "SHORTNAME CARD PROTOCOL ADDRESS", + N_("Add a network address.")); + cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, + "SHORTNAME", + N_("Delete a network address.")); + cmd_addroute = grub_register_command ("net_add_route", grub_cmd_addroute, + "SHORTNAME NET [INTERFACE| gw GATEWAY]", + N_("Add a network route.")); + cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, + "SHORTNAME", + N_("Delete a network route.")); +} + +GRUB_MOD_FINI(net) +{ + grub_unregister_command (cmd_addaddr); + grub_unregister_command (cmd_deladdr); + grub_unregister_command (cmd_addroute); + grub_unregister_command (cmd_delroute); +} diff --git a/commands/probe.c b/commands/probe.c index c2cc599e9..002ede85e 100644 --- a/commands/probe.c +++ b/commands/probe.c @@ -72,7 +72,7 @@ grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args) { const char *val = "none"; if (dev->net) - val = dev->net->dev->name; + val = dev->net->name; if (dev->disk) val = dev->disk->dev->name; if (state[0].set) diff --git a/conf/common.rmk b/conf/common.rmk index 0f67622b5..cee808a35 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -828,4 +828,10 @@ bin_UTILITIES += grub-mkpasswd-pbkdf2 grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 +pkglib_MODULES += net.mod +net_mod_SOURCES = commands/net.c +net_mod_CFLAGS = $(COMMON_CFLAGS) +net_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/gcry.mk + diff --git a/include/grub/device.h b/include/grub/device.h index f0e8a8ca8..d68c26e66 100644 --- a/include/grub/device.h +++ b/include/grub/device.h @@ -24,8 +24,12 @@ #include struct grub_disk; -struct grub_net; struct grub_fs; +struct grub_net +{ + char *name; + struct grub_fs *fs; +}; struct grub_device { diff --git a/include/grub/err.h b/include/grub/err.h index e44705389..493796d62 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -54,7 +54,10 @@ typedef enum GRUB_ERR_MENU, GRUB_ERR_TIMEOUT, GRUB_ERR_IO, - GRUB_ERR_ACCESS_DENIED + GRUB_ERR_ACCESS_DENIED, + GRUB_ERR_NET_BAD_ADDRESS, + GRUB_ERR_NET_ROUTE_LOOP, + GRUB_ERR_NET_NO_ROUTE } grub_err_t; diff --git a/include/grub/net.h b/include/grub/net.h index c6d71d5b6..4ca873f74 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * 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 @@ -19,54 +19,224 @@ #ifndef GRUB_NET_HEADER #define GRUB_NET_HEADER 1 -#include -#include #include +#include +#include -struct grub_net; +struct grub_net_card; -struct grub_net_dev +struct grub_net_card_driver { - /* The device name. */ - const char *name; - - /* FIXME: Just a template. */ - int (*probe) (struct grub_net *net, const void *addr); - void (*reset) (struct grub_net *net); - int (*poll) (struct grub_net *net); - void (*transmit) (struct grub_net *net, const void *destip, - unsigned srcsock, unsigned destsock, const void *packet); - void (*disable) (struct grub_net *net); - - /* The next net device. */ - struct grub_net_dev *next; + grub_err_t (*send) (struct grub_net_card *dev, void *buf, + grub_size_t buflen); + grub_size_t (*recv) (struct grub_net_card *dev, void *buf, + grub_size_t buflen); }; -typedef struct grub_net_dev *grub_net_dev_t; -struct grub_fs; - -struct grub_net +struct grub_net_card { - /* The net name. */ - const char *name; - - /* The underlying disk device. */ - grub_net_dev_t dev; - - /* The binding filesystem. */ - struct grub_fs *fs; - - /* FIXME: More data would be required, such as an IP address, a mask, - a gateway, etc. */ - - /* Device-specific data. */ + struct grub_net_card *next; + char *name; + struct grub_net_card_driver *driver; void *data; }; -typedef struct grub_net *grub_net_t; -/* FIXME: How to abstract networks? More consideration is necessary. */ +struct grub_net_network_level_interface; + +typedef union grub_net_network_level_address +{ + grub_uint32_t ipv4; +} grub_net_network_level_netaddress_t; + +typedef union grub_net_network_level_netaddress +{ + struct { + grub_uint32_t base; + int masksize; + } ipv4; +} grub_net_network_level_address_t; + +typedef enum grub_network_level_protocol_id +{ + GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 +} grub_network_level_protocol_id_t; + +struct grub_net_network_level_interface; + +struct grub_net_network_level_protocol +{ + struct grub_net_network_level_protocol *next; + char *name; + grub_network_level_protocol_id_t id; + grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr); + char * (*aton) (union grub_net_network_level_address addr); + grub_err_t (*net_ntoa) (char *name, + grub_net_network_level_netaddress_t *addr); + char * (*net_aton) (grub_net_network_level_netaddress_t addr); + int (* match_net) (grub_net_network_level_netaddress_t net, + grub_net_network_level_address_t addr); + grub_err_t (*init) (struct grub_net_network_level_interface *dev); + grub_err_t (*fini) (struct grub_net_network_level_interface *dev); + grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf, + grub_size_t buflen); + grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf, + grub_size_t buflen); +}; + +struct grub_net_network_level_interface +{ + struct grub_net_network_level_interface *next; + char *name; + /* Underlying protocol. */ + struct grub_net_network_level_protocol *protocol; + struct grub_net_card *card; + union grub_net_network_level_address address; + void *data; +}; + +struct grub_net_route +{ + struct grub_net_route *next; + grub_net_network_level_netaddress_t target; + char *name; + struct grub_net_network_level_protocol *prot; + int is_gateway; + union + { + struct grub_net_network_level_interface *interface; + grub_net_network_level_address_t gw; + }; +}; + +struct grub_net_session; + +struct grub_net_session_level_protocol +{ + void (*close) (struct grub_net_session *session); + grub_ssize_t (*recv) (struct grub_net_session *session, void *buf, + grub_size_t size); + grub_err_t (*send) (struct grub_net_session *session, void *buf, + grub_size_t size); +}; + +struct grub_net_session +{ + struct grub_net_session_level_protocol *protocol; + void *data; +}; + +static inline void +grub_net_session_close (struct grub_net_session *session) +{ + session->protocol->close (session); +} + +static inline grub_err_t +grub_net_session_send (struct grub_net_session *session, void *buf, + grub_size_t size) +{ + return session->protocol->send (session, buf, size); +} + +static inline grub_ssize_t +grub_net_session_recv (struct grub_net_session *session, void *buf, + grub_size_t size) +{ + return session->protocol->recv (session, buf, size); +} + +extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; + +static inline void +grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +static inline void +grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) + +extern struct grub_net_route *grub_net_routes; + +static inline void +grub_net_route_register (struct grub_net_route *route) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +static inline void +grub_net_route_unregister (struct grub_net_route *route) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) + +extern struct grub_net_card *grub_net_cards; + +static inline void +grub_net_card_register (struct grub_net_card *card) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + +static inline void +grub_net_card_unregister (struct grub_net_card *card) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + +#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) + +extern struct grub_net_network_level_protocol *grub_net_network_level_protocols; + +static inline void +grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols), + GRUB_AS_LIST (prot)); +} + +static inline void +grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols), + GRUB_AS_LIST (prot)); +} + +#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next) + +static inline grub_err_t +grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot, + char *name, + grub_net_network_level_address_t *addr) +{ + return prot->ntoa (name, addr); +} + +struct grub_net_session * +grub_net_open_tcp (char *address, grub_uint16_t port); + +grub_err_t +grub_net_resolve_address (struct grub_net_network_level_protocol **prot, + char *name, + grub_net_network_level_address_t *addr); + +grub_err_t +grub_net_route_address (grub_net_network_level_address_t addr, + grub_net_network_level_address_t *gateway, + struct grub_net_network_level_interface **interf); -/* Note: Networks are very different from disks, because networks must - be initialized before used, and the status is persistent. */ #endif /* ! GRUB_NET_HEADER */ diff --git a/kern/fs.c b/kern/fs.c index cf800f4cc..8ffb93c8b 100644 --- a/kern/fs.c +++ b/kern/fs.c @@ -94,7 +94,7 @@ grub_fs_probe (grub_device_t device) count--; } } - else if (device->net->fs) + else if (device->net) return device->net->fs; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); From 1bf0e31cfb90a05389715ebda22734dff7f38d7c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 3 Mar 2010 20:09:48 +0100 Subject: [PATCH 0014/1414] Network infrastructure --- commands/net.c | 296 ++++++++++++++++++++++++++++++++++++++++++ commands/probe.c | 2 +- conf/common.rmk | 6 + include/grub/device.h | 6 +- include/grub/err.h | 5 +- include/grub/net.h | 248 +++++++++++++++++++++++++++++------ kern/fs.c | 2 +- 7 files changed, 522 insertions(+), 43 deletions(-) create mode 100644 commands/net.c diff --git a/commands/net.c b/commands/net.c new file mode 100644 index 000000000..288ba4c2a --- /dev/null +++ b/commands/net.c @@ -0,0 +1,296 @@ +/* + * 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 + +struct grub_net_route *grub_net_routes = NULL; +struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; +struct grub_net_card *grub_net_cards = NULL; +struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; + +grub_err_t +grub_net_resolve_address (struct grub_net_network_level_protocol **prot, + char *name, + grub_net_network_level_address_t *addr) +{ + FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot) + { + grub_err_t err; + err = grub_net_resolve_address_in_protocol (*prot, name, addr); + if (err == GRUB_ERR_NET_BAD_ADDRESS) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("Unrecognised address %s"), + name); +} + +grub_err_t +grub_net_route_address (grub_net_network_level_address_t addr, + grub_net_network_level_address_t *gateway, + struct grub_net_network_level_interface **interf) +{ + struct grub_net_route *route; + int depth = 0; + int routecnt = 0; + struct grub_net_network_level_protocol *prot = NULL; + grub_net_network_level_address_t curtarget = addr; + + *gateway = addr; + + FOR_NET_ROUTES(route) + routecnt++; + + for (depth = 0; depth < routecnt + 2; depth++) + { + FOR_NET_ROUTES(route) + { + if (depth && prot != route->prot) + continue; + prot = route->prot; + if (!route->prot->match_net (route->target, curtarget)) + continue; + + if (route->is_gateway) + { + if (depth == 0) + *gateway = route->gw; + curtarget = route->gw; + break; + } + *interf = route->interface; + return GRUB_ERR_NONE; + } + if (route == NULL) + return grub_error (GRUB_ERR_NET_NO_ROUTE, "destination unreachable"); + } + + return grub_error (GRUB_ERR_NET_ROUTE_LOOP, "route loop detected"); +} + +static grub_err_t +grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_interface *inter; + + if (argc != 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[1])) + break; + if (inter == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); + + inter->protocol->fini (inter); + grub_net_network_level_interface_unregister (inter); + grub_free (inter->name); + grub_free (inter); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_card *card; + struct grub_net_network_level_protocol *prot; + grub_err_t err; + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inter; + + if (argc != 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); + + FOR_NET_CARDS (card) + if (grub_strcmp (card->name, args[1])) + break; + if (card == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); + + FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot) + if (grub_strcmp (prot->name, args[2])) + break; + + if (card == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); + + err = grub_net_resolve_address_in_protocol (prot, args[3], &addr); + if (err) + return err; + + inter = grub_zalloc (sizeof (*inter)); + if (!inter) + return grub_errno; + + inter->name = grub_strdup (args[0]); + inter->protocol = prot; + grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); + inter->card = card; + + err = prot->init (inter); + if (err) + { + grub_free (inter->name); + grub_free (inter); + return err; + } + grub_net_network_level_interface_register (inter); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_route *route; + struct grub_net_route **prev; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + for (prev = &grub_net_routes, route = *prev; route; prev = &((*prev)->next), + route = *prev) + if (grub_strcmp (route->name, args[0]) == 0) + { + *prev = route->next; + grub_free (route->name); + grub_free (route); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_protocol *prot; + struct grub_net_route *route; + + if (argc < 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("At least 3 arguments are expected")); + + route = grub_zalloc (sizeof (*route)); + if (!route) + return grub_errno; + + route->name = grub_strdup (args[0]); + if (!route->name) + { + grub_free (route); + return grub_errno; + } + + FOR_NET_NETWORK_LEVEL_PROTOCOLS(prot) + { + grub_err_t err; + err = prot->net_ntoa (args[1], &(route->target)); + if (err == GRUB_ERR_NET_BAD_ADDRESS) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + break; + } + + if (!prot) + { + grub_free (route->name); + grub_free (route); + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, + N_("Unrecognised address %s"), args[1]); + } + + if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) + { + grub_err_t err; + route->is_gateway = 1; + err = grub_net_resolve_address_in_protocol (prot, + args[3], &(route->gw)); + if (err) + { + grub_free (route->name); + grub_free (route); + return err; + } + } + else + { + struct grub_net_network_level_interface *inter; + route->is_gateway = 0; + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[2])) + break; + + if (!inter) + { + grub_free (route->name); + grub_free (route); + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Unrecognised interface %s"), args[2]); + } + route->interface = inter; + } + + grub_net_route_register (route); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; + +GRUB_MOD_INIT(net) +{ + cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, + "SHORTNAME CARD PROTOCOL ADDRESS", + N_("Add a network address.")); + cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, + "SHORTNAME", + N_("Delete a network address.")); + cmd_addroute = grub_register_command ("net_add_route", grub_cmd_addroute, + "SHORTNAME NET [INTERFACE| gw GATEWAY]", + N_("Add a network route.")); + cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, + "SHORTNAME", + N_("Delete a network route.")); +} + +GRUB_MOD_FINI(net) +{ + grub_unregister_command (cmd_addaddr); + grub_unregister_command (cmd_deladdr); + grub_unregister_command (cmd_addroute); + grub_unregister_command (cmd_delroute); +} diff --git a/commands/probe.c b/commands/probe.c index c2cc599e9..002ede85e 100644 --- a/commands/probe.c +++ b/commands/probe.c @@ -72,7 +72,7 @@ grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args) { const char *val = "none"; if (dev->net) - val = dev->net->dev->name; + val = dev->net->name; if (dev->disk) val = dev->disk->dev->name; if (state[0].set) diff --git a/conf/common.rmk b/conf/common.rmk index 7effa8af3..f1ed1478d 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -779,4 +779,10 @@ bin_UTILITIES += grub-mkpasswd-pbkdf2 grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 +pkglib_MODULES += net.mod +net_mod_SOURCES = commands/net.c +net_mod_CFLAGS = $(COMMON_CFLAGS) +net_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/gcry.mk + diff --git a/include/grub/device.h b/include/grub/device.h index f0e8a8ca8..d68c26e66 100644 --- a/include/grub/device.h +++ b/include/grub/device.h @@ -24,8 +24,12 @@ #include struct grub_disk; -struct grub_net; struct grub_fs; +struct grub_net +{ + char *name; + struct grub_fs *fs; +}; struct grub_device { diff --git a/include/grub/err.h b/include/grub/err.h index e44705389..493796d62 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -54,7 +54,10 @@ typedef enum GRUB_ERR_MENU, GRUB_ERR_TIMEOUT, GRUB_ERR_IO, - GRUB_ERR_ACCESS_DENIED + GRUB_ERR_ACCESS_DENIED, + GRUB_ERR_NET_BAD_ADDRESS, + GRUB_ERR_NET_ROUTE_LOOP, + GRUB_ERR_NET_NO_ROUTE } grub_err_t; diff --git a/include/grub/net.h b/include/grub/net.h index c6d71d5b6..4ca873f74 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * 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 @@ -19,54 +19,224 @@ #ifndef GRUB_NET_HEADER #define GRUB_NET_HEADER 1 -#include -#include #include +#include +#include -struct grub_net; +struct grub_net_card; -struct grub_net_dev +struct grub_net_card_driver { - /* The device name. */ - const char *name; - - /* FIXME: Just a template. */ - int (*probe) (struct grub_net *net, const void *addr); - void (*reset) (struct grub_net *net); - int (*poll) (struct grub_net *net); - void (*transmit) (struct grub_net *net, const void *destip, - unsigned srcsock, unsigned destsock, const void *packet); - void (*disable) (struct grub_net *net); - - /* The next net device. */ - struct grub_net_dev *next; + grub_err_t (*send) (struct grub_net_card *dev, void *buf, + grub_size_t buflen); + grub_size_t (*recv) (struct grub_net_card *dev, void *buf, + grub_size_t buflen); }; -typedef struct grub_net_dev *grub_net_dev_t; -struct grub_fs; - -struct grub_net +struct grub_net_card { - /* The net name. */ - const char *name; - - /* The underlying disk device. */ - grub_net_dev_t dev; - - /* The binding filesystem. */ - struct grub_fs *fs; - - /* FIXME: More data would be required, such as an IP address, a mask, - a gateway, etc. */ - - /* Device-specific data. */ + struct grub_net_card *next; + char *name; + struct grub_net_card_driver *driver; void *data; }; -typedef struct grub_net *grub_net_t; -/* FIXME: How to abstract networks? More consideration is necessary. */ +struct grub_net_network_level_interface; + +typedef union grub_net_network_level_address +{ + grub_uint32_t ipv4; +} grub_net_network_level_netaddress_t; + +typedef union grub_net_network_level_netaddress +{ + struct { + grub_uint32_t base; + int masksize; + } ipv4; +} grub_net_network_level_address_t; + +typedef enum grub_network_level_protocol_id +{ + GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 +} grub_network_level_protocol_id_t; + +struct grub_net_network_level_interface; + +struct grub_net_network_level_protocol +{ + struct grub_net_network_level_protocol *next; + char *name; + grub_network_level_protocol_id_t id; + grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr); + char * (*aton) (union grub_net_network_level_address addr); + grub_err_t (*net_ntoa) (char *name, + grub_net_network_level_netaddress_t *addr); + char * (*net_aton) (grub_net_network_level_netaddress_t addr); + int (* match_net) (grub_net_network_level_netaddress_t net, + grub_net_network_level_address_t addr); + grub_err_t (*init) (struct grub_net_network_level_interface *dev); + grub_err_t (*fini) (struct grub_net_network_level_interface *dev); + grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf, + grub_size_t buflen); + grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf, + grub_size_t buflen); +}; + +struct grub_net_network_level_interface +{ + struct grub_net_network_level_interface *next; + char *name; + /* Underlying protocol. */ + struct grub_net_network_level_protocol *protocol; + struct grub_net_card *card; + union grub_net_network_level_address address; + void *data; +}; + +struct grub_net_route +{ + struct grub_net_route *next; + grub_net_network_level_netaddress_t target; + char *name; + struct grub_net_network_level_protocol *prot; + int is_gateway; + union + { + struct grub_net_network_level_interface *interface; + grub_net_network_level_address_t gw; + }; +}; + +struct grub_net_session; + +struct grub_net_session_level_protocol +{ + void (*close) (struct grub_net_session *session); + grub_ssize_t (*recv) (struct grub_net_session *session, void *buf, + grub_size_t size); + grub_err_t (*send) (struct grub_net_session *session, void *buf, + grub_size_t size); +}; + +struct grub_net_session +{ + struct grub_net_session_level_protocol *protocol; + void *data; +}; + +static inline void +grub_net_session_close (struct grub_net_session *session) +{ + session->protocol->close (session); +} + +static inline grub_err_t +grub_net_session_send (struct grub_net_session *session, void *buf, + grub_size_t size) +{ + return session->protocol->send (session, buf, size); +} + +static inline grub_ssize_t +grub_net_session_recv (struct grub_net_session *session, void *buf, + grub_size_t size) +{ + return session->protocol->recv (session, buf, size); +} + +extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; + +static inline void +grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +static inline void +grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) + +extern struct grub_net_route *grub_net_routes; + +static inline void +grub_net_route_register (struct grub_net_route *route) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +static inline void +grub_net_route_unregister (struct grub_net_route *route) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) + +extern struct grub_net_card *grub_net_cards; + +static inline void +grub_net_card_register (struct grub_net_card *card) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + +static inline void +grub_net_card_unregister (struct grub_net_card *card) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + +#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) + +extern struct grub_net_network_level_protocol *grub_net_network_level_protocols; + +static inline void +grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols), + GRUB_AS_LIST (prot)); +} + +static inline void +grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols), + GRUB_AS_LIST (prot)); +} + +#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next) + +static inline grub_err_t +grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot, + char *name, + grub_net_network_level_address_t *addr) +{ + return prot->ntoa (name, addr); +} + +struct grub_net_session * +grub_net_open_tcp (char *address, grub_uint16_t port); + +grub_err_t +grub_net_resolve_address (struct grub_net_network_level_protocol **prot, + char *name, + grub_net_network_level_address_t *addr); + +grub_err_t +grub_net_route_address (grub_net_network_level_address_t addr, + grub_net_network_level_address_t *gateway, + struct grub_net_network_level_interface **interf); -/* Note: Networks are very different from disks, because networks must - be initialized before used, and the status is persistent. */ #endif /* ! GRUB_NET_HEADER */ diff --git a/kern/fs.c b/kern/fs.c index 0c456377f..7bd1445b0 100644 --- a/kern/fs.c +++ b/kern/fs.c @@ -124,7 +124,7 @@ grub_fs_probe (grub_device_t device) count--; } } - else if (device->net->fs) + else if (device->net) return device->net->fs; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); From 066528b4b18ed5870be40ef333bc85d2344ee812 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Tue, 27 Apr 2010 18:05:35 -0300 Subject: [PATCH 0015/1414] Initial Implementation of TFTP protocol and new protocol structs. --- conf/powerpc-ieee1275.rmk | 8 +- include/grub/net.h | 19 ++++- include/grub/net/arp.h | 23 ++++++ include/grub/net/device.h | 7 ++ include/grub/net/ethernet.h | 12 +++ include/grub/net/ieee1275/interface.h | 21 ++++++ include/grub/net/interface.h | 17 +++++ include/grub/net/ip.h | 25 +++++++ include/grub/net/netbuff.h | 27 +++++++ include/grub/net/protocol.h | 50 +++++++++++++ include/grub/net/tftp.h | 74 +++++++++++++++++++ include/grub/net/type_net.h | 7 ++ include/grub/net/udp.h | 22 ++++++ net/arp.c | 0 net/device.c | 0 net/ethernet.c | 54 ++++++++++++++ net/ieee1275/interface.c | 80 ++++++++++++++++++++ net/interface.c | 0 net/ip.c | 95 ++++++++++++++++++++++++ net/netbuff.c | 72 ++++++++++++++++++ net/protocol.c | 21 ++++++ net/tftp.c | 102 ++++++++++++++++++++++++++ net/udp.c | 59 +++++++++++++++ 23 files changed, 789 insertions(+), 6 deletions(-) create mode 100644 include/grub/net/arp.h create mode 100644 include/grub/net/device.h create mode 100644 include/grub/net/ethernet.h create mode 100644 include/grub/net/ieee1275/interface.h create mode 100644 include/grub/net/interface.h create mode 100644 include/grub/net/ip.h create mode 100644 include/grub/net/netbuff.h create mode 100644 include/grub/net/protocol.h create mode 100644 include/grub/net/tftp.h create mode 100644 include/grub/net/type_net.h create mode 100644 include/grub/net/udp.h create mode 100644 net/arp.c create mode 100644 net/device.c create mode 100644 net/ethernet.c create mode 100644 net/ieee1275/interface.c create mode 100644 net/interface.c create mode 100644 net/ip.c create mode 100644 net/netbuff.c create mode 100644 net/protocol.c create mode 100644 net/tftp.c create mode 100644 net/udp.c diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index be95b30ba..14d04f93e 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -3,7 +3,10 @@ # Images. -kernel_img_HEADERS += ieee1275/ieee1275.h +<<<<<<< TREE +kernel_img_HEADERS += ieee1275/ieee1275.h \ + command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\ + net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h # Programs pkglib_PROGRAMS = kernel.img @@ -20,7 +23,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ - symlist.c kern/$(target_cpu)/cache.S + symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c \ + net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic diff --git a/include/grub/net.h b/include/grub/net.h index 4ca873f74..75efd51d6 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -22,15 +22,20 @@ #include #include #include +#include struct grub_net_card; struct grub_net_card_driver { - grub_err_t (*send) (struct grub_net_card *dev, void *buf, - grub_size_t buflen); - grub_size_t (*recv) (struct grub_net_card *dev, void *buf, - grub_size_t buflen); + grub_err_t (*send) (struct grub_net_card *dev,struct grub_net_buff *nb); + grub_size_t (*recv) (struct grub_net_card *dev,struct grub_net_buff *nb); +}; + +struct grub_net_addr +{ + grub_uint8_t *addr; + grub_size_t len; }; struct grub_net_card @@ -38,6 +43,12 @@ struct grub_net_card struct grub_net_card *next; char *name; struct grub_net_card_driver *driver; + /*transport layer address*/ + struct grub_net_addr *tla; + /*internet layer address*/ + struct grub_net_addr *ila; + /*link layer address*/ + struct grub_net_addr *lla; void *data; }; diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h new file mode 100644 index 000000000..0ac2ec832 --- /dev/null +++ b/include/grub/net/arp.h @@ -0,0 +1,23 @@ +#ifndef GRUB_NET_ARP_HEADER +#define GRUB_NET_ARP_HEADER 1 + +#include +struct arprequest { + grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ + grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ + grub_int8_t hwlen; /* hardware address length (must be 6) */ + grub_int8_t protolen; /* protocol address length (must be 4) */ + grub_uint16_t opcode; /* ARP opcode */ + grub_uint8_t shwaddr[6]; /* sender's hardware address */ + grub_uint32_t sipaddr; /* sender's IP address */ + grub_uint8_t thwaddr[6]; /* target's hardware address */ + grub_uint32_t tipaddr; /* target's IP address */ +}__attribute__ ((packed)); + + +struct arp_pkt{ + struct etherhdr ether; + struct arprequest arpr; +} __attribute__ ((packed)); + +#endif diff --git a/include/grub/net/device.h b/include/grub/net/device.h new file mode 100644 index 000000000..9f1b9bf1d --- /dev/null +++ b/include/grub/net/device.h @@ -0,0 +1,7 @@ +struct grub_net_card +{ + struct grub_net_card *next; + char *name; + struct grub_net_card_driver *driver; + void *data; +}; diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h new file mode 100644 index 000000000..46aa04f60 --- /dev/null +++ b/include/grub/net/ethernet.h @@ -0,0 +1,12 @@ +#ifndef GRUB_NET_ETHERNET_HEADER +#define GRUB_NET_ETHERNET_HEADER 1 +#include +struct etherhdr { + grub_uint8_t dst[6]; + grub_uint8_t src[6]; + grub_uint16_t type; +} __attribute__ ((packed)) ; + +void ethernet_ini(void); +void ethernet_fini(void); +#endif diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h new file mode 100644 index 000000000..edc242cab --- /dev/null +++ b/include/grub/net/ieee1275/interface.h @@ -0,0 +1,21 @@ +#ifndef GRUB_IEEE1275_INTERFACE_HEADER +#define GRUB_IEEE1275_INTERFACE_HEADER 1 + +#include +#include +#include + +grub_ofnet_t EXPORT_VAR(grub_net); + +grub_bootp_t EXPORT_VAR(bootp_pckt); +grub_uint32_t get_server_ip(void); +grub_uint32_t get_client_ip(void); +grub_uint8_t* get_server_mac (void); +grub_uint8_t* get_client_mac (void); + +int send_card_buffer (void *buffer,int buff_len); +int get_card_buffer (void *buffer,int buff_len); +int card_open (void); +int card_close (void); + +#endif diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h new file mode 100644 index 000000000..0e11c86ba --- /dev/null +++ b/include/grub/net/interface.h @@ -0,0 +1,17 @@ +#ifndef GRUB_INTERFACE_HEADER +#define GRUB_INTERFACE_HEADER +#include +#include +/* +extern struct grub_net_topprotocol; + +struct grub_net_interface +{ + struct grub_net_card *card; + struct grub_net_topprotocol* topprot; + struct grub_net_addr *tla; + struct grub_net_addr *ila; + struct grub_net_addr *lla; +}; +*/ +#endif diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h new file mode 100644 index 000000000..e1f45dcfa --- /dev/null +++ b/include/grub/net/ip.h @@ -0,0 +1,25 @@ +#ifndef GRUB_NET_IP_HEADER +#define GRUB_NET_IP_HEADER 1 +#include + + +struct iphdr { + grub_uint8_t verhdrlen; + grub_uint8_t service; + grub_uint16_t len; + grub_uint16_t ident; + grub_uint16_t frags; + grub_uint8_t ttl; + grub_uint8_t protocol; + grub_uint16_t chksum; + grub_uint32_t src; + grub_uint32_t dest; +} __attribute__ ((packed)) ; + +#define IP_UDP 17 /* UDP protocol */ +#define IP_BROADCAST 0xFFFFFFFF + +grub_uint16_t ipchksum(void *ipv, int len); +void ipv4_ini(void); +void ipv4_fini(void); +#endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h new file mode 100644 index 000000000..7d63be1f5 --- /dev/null +++ b/include/grub/net/netbuff.h @@ -0,0 +1,27 @@ +#ifndef GRUB_NETBUFF_HEADER +#define GRUB_NETBUFF_HEADER + +#include + +#define NETBUFF_ALIGN 2048 +#define NETBUFFMINLEN 64 + +struct grub_net_buff +{ + /*Pointer to the start of the buffer*/ + char *head; + /*Pointer to the data */ + char *data; + /*Pointer to the tail */ + char *tail; + /*Pointer to the end of the buffer*/ + char *end; +}; + +grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len); +struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ); +#endif diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h new file mode 100644 index 000000000..2c979481b --- /dev/null +++ b/include/grub/net/protocol.h @@ -0,0 +1,50 @@ +#ifndef GRUB_PROTOCOL_HEADER +#define GRUB_PROTOCOL_HEADER +#include +#include +#include +#include +struct protocol_operations; +struct grub_net_protocol; +struct grub_net_interface; + +struct grub_net_protocol +{ + struct grub_net_protocol *next; + char *name; + grub_err_t (*open) (struct grub_net_interface* inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*open_confirm) (struct grub_net_interface *inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*get_payload) (struct grub_net_interface *inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_net_interface *inf, + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*send) (struct grub_net_interface *inf , + struct grub_net_protocol *prot, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_interface *inf , + struct grub_net_protocol *prot, struct grub_net_buff *nb); +}; + +typedef struct grub_net_protocol *grub_net_protocol_t; + +struct grub_net_interface +{ + struct grub_net_card *card; + struct grub_net_protocol* prot; + char *path; + char *username; + char *password; + /*transport layer addres*/ + struct grub_net_addr *tla; + /*internet layer addres*/ + struct grub_net_addr *ila; + /*link layer addres*/ + struct grub_net_addr *lla; +}; + +void grub_protocol_register (grub_net_protocol_t prot); +void grub_protocol_unregister (grub_net_protocol_t prot); +#endif diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h new file mode 100644 index 000000000..4148096c5 --- /dev/null +++ b/include/grub/net/tftp.h @@ -0,0 +1,74 @@ +#ifndef GRUB_NET_TFTP_HEADER +#define GRUB_NET_TFTP_HEADER 1 + +#include +#include +#include + +/* IP port for the MTFTP server used for Intel's PXE */ +#define MTFTP_SERVER_PORT 75 +#define MTFTP_CLIENT_PORT 76 + +#define TFTP_DEFAULTSIZE_PACKET 512 +#define TFTP_MAX_PACKET 1432 + +/* IP port for the TFTP server */ +#define TFTP_SERVER_PORT 69 +#define TFTP_CLIENT_PORT 2000 + + +/* We define these based on what's in arpa/tftp.h. We just like our + * names better, cause they're clearer */ +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 +#define TFTP_OACK 6 + +#define TFTP_CODE_EOF 1 +#define TFTP_CODE_MORE 2 +#define TFTP_CODE_ERROR 3 +#define TFTP_CODE_BOOT 4 +#define TFTP_CODE_CFG 5 + +#define TFTP_EUNDEF 0 /* not defined */ +#define TFTP_ENOTFOUND 1 /* file not found */ +#define TFTP_EACCESS 2 /* access violation */ +#define TFTP_ENOSPACE 3 /* disk full or allocation exceeded */ +#define TFTP_EBADOP 4 /* illegal TFTP operation */ +#define TFTP_EBADID 5 /* unknown transfer ID */ +#define TFTP_EEXISTS 6 /* file already exists */ +#define TFTP_ENOUSER 7 /* no such user */ +#define TFTP_DEFAULT_FILENAME "kernel" + + + + + + /* * own here because this is cleaner, and maps to the same data layout. + * */ +struct tftphdr { + grub_uint16_t opcode; + union { + grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; + struct { + grub_uint16_t block; + grub_int8_t download[TFTP_MAX_PACKET]; + } data; + struct { + grub_uint16_t block; + } ack; + struct { + grub_uint16_t errcode; + grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; + } err; + struct { + grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; + } oack; + } u; +} __attribute__ ((packed)) ; + +void tftp_ini(void); +void tftp_fini(void); +#endif diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h new file mode 100644 index 000000000..33f2d802d --- /dev/null +++ b/include/grub/net/type_net.h @@ -0,0 +1,7 @@ +#ifndef GRUB_TYPES_NET_HEADER +#define GRUB_TYPES_NET_HEADER 1 + +#define UDP_PCKT 0x11 +#define IP_PCKT 0x0800 + +#endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h new file mode 100644 index 000000000..dbfcecef0 --- /dev/null +++ b/include/grub/net/udp.h @@ -0,0 +1,22 @@ +#ifndef GRUB_NET_UDP_HEADER +#define GRUB_NET_UDP_HEADER 1 +#include +/* +typedef enum + { + GRUB_PROT_TFTP + } protocol_type; +*/ + +#define GRUB_PROT_TFTP 1 + +struct udphdr { + grub_uint16_t src; + grub_uint16_t dst; + grub_uint16_t len; + grub_uint16_t chksum; +} __attribute__ ((packed)); + +void udp_ini(void); +void udp_fini(void); +#endif diff --git a/net/arp.c b/net/arp.c new file mode 100644 index 000000000..e69de29bb diff --git a/net/device.c b/net/device.c new file mode 100644 index 000000000..e69de29bb diff --git a/net/ethernet.c b/net/ethernet.c new file mode 100644 index 000000000..fc64803e7 --- /dev/null +++ b/net/ethernet.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +send_ethernet_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot __attribute__ ((unused)) + ,struct grub_net_buff *nb) +{ + + struct etherhdr *eth; + grub_err_t err; + + if((err = grub_netbuff_push (nb,sizeof(*eth)) ) != GRUB_ERR_NONE) + return err; + eth = (struct etherhdr *) nb->data; + grub_memcpy (eth->src,inf->card->lla->addr,6 * sizeof (grub_uint8_t )); + grub_memcpy (eth->dst,inf->lla->addr,6 * sizeof (grub_uint8_t )); + eth->type = 0x0800; + + return inf->card->driver->send(inf->card,nb); +} + +static struct grub_net_protocol grub_ethernet_protocol = +{ + .name = "udp", + .send = send_ethernet_packet +}; + +void ethernet_ini(void) +{ + grub_protocol_register (&grub_ethernet_protocol); +} + +void ethernet_fini(void) +{ + grub_protocol_unregister (&grub_ethernet_protocol); +} +/* +int read_ethernet_packet(buffer,bufflen, int type) +{ + + struct etherhdr eth; + eth.type = 0; + + get_card_buffer (ð,sizeof (eth)); + + + +}*/ diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c new file mode 100644 index 000000000..5a246ffa5 --- /dev/null +++ b/net/ieee1275/interface.c @@ -0,0 +1,80 @@ +#include +#include + +grub_uint32_t get_server_ip (void) +{ + return bootp_pckt->siaddr; +} + +grub_uint32_t get_client_ip (void) +{ + return bootp_pckt->yiaddr; +} + +grub_uint8_t* get_server_mac (void) +{ + grub_uint8_t *mac; + + mac = grub_malloc (6 * sizeof(grub_uint8_t)); + mac[0] = 0x00 ; + mac[1] = 0x11 ; + mac[2] = 0x25 ; + mac[3] = 0xca ; + mac[4] = 0x1f ; + mac[5] = 0x01 ; + + return mac; + +} + +grub_uint8_t* get_client_mac (void) +{ + grub_uint8_t *mac; + + mac = grub_malloc (6 * sizeof (grub_uint8_t)); + mac[0] = 0x0a ; + mac[1] = 0x11 ; + mac[2] = 0xbd ; + mac[3] = 0xe3 ; + mac[4] = 0xe3 ; + mac[5] = 0x04 ; + + return mac; +} + +static grub_ieee1275_ihandle_t handle; +int card_open (void) +{ + + grub_ieee1275_open (grub_net->dev , &handle); + return 1;//error + +} +int card_close (void) +{ + + if (handle) + grub_ieee1275_close (handle); + return 0; +} + + +int send_card_buffer (void *buffer,int buff_len) +{ + + int actual; + + grub_ieee1275_write (handle,buffer,buff_len,&actual); + + return actual; +} + +int get_card_buffer (void *buffer,int buff_len) +{ + + int actual; + + grub_ieee1275_read (handle,buffer,buff_len,&actual); + + return actual; +} diff --git a/net/interface.c b/net/interface.c new file mode 100644 index 000000000..e69de29bb diff --git a/net/ip.c b/net/ip.c new file mode 100644 index 000000000..c669ff6d7 --- /dev/null +++ b/net/ip.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct grub_net_protocol *grub_ipv4_prot; + +grub_uint16_t +ipchksum(void *ipv, int len) +{ + grub_uint16_t *ip = (grub_uint16_t *)ipv; + grub_uint32_t sum = 0; + + + len >>= 1; + while (len--) { + sum += *(ip++); + if (sum > 0xFFFF) + sum -= 0xFFFF; + } + + return((~sum) & 0x0000FFFF); +} + + +static grub_err_t +send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb ) +{ + + struct iphdr *iph; + grub_err_t err; + + if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE) + return err; + iph = (struct iphdr *) nb->data; + + /*FIXME dont work in litte endian machines*/ + //grub_uint8_t ver = 4; + //grub_uint8_t hdrlen = sizeof (struct iphdr)/4; + iph->verhdrlen = (4<<4 | 5); + iph->service = 0; + iph->len = sizeof(*iph); + iph->ident = 0x2b5f; + iph->frags = 0; + iph->ttl = 0xff; + iph->protocol = 0x11; + //grub_memcpy(&(iph->src) ,inf->card->ila->addr,inf->card->ila->len); + iph->src = *((grub_uint32_t *)inf->card->ila->addr); + //grub_memcpy(&(iph->dest) ,inf->ila->addr,inf->ila->len); + iph->dest = *((grub_uint32_t *)inf->ila->addr); + + iph->chksum = 0 ; + iph->chksum = ipchksum((void *)nb->head, sizeof(*iph)); + + + return prot->next->send(inf,prot->next,nb); +} + +static struct grub_net_protocol grub_ipv4_protocol = +{ + .name = "ipv4", + .send = send_ip_packet, + .recv = NULL +}; + +void ipv4_ini(void) +{ + grub_protocol_register (&grub_ipv4_protocol); +} + +void ipv4_fini(void) +{ + grub_protocol_unregister (&grub_ipv4_protocol); +} + +/* +int read_ip_packet (void *buffer,int *bufflen) +{ + struct iphdr iph; + iph.protocol = 0; + + while ( iph.protocol != IP_UDP) + { + read_ethernet_packet(buffer,bufflen,IP_PROTOCOL); + grub_memcpy (&iph,buffer,sizeof (iph)); + } + + buffer += sizeof (iph); + *buff_len -= sizeof (iph); + +}*/ diff --git a/net/netbuff.c b/net/netbuff.c new file mode 100644 index 000000000..342260f43 --- /dev/null +++ b/net/netbuff.c @@ -0,0 +1,72 @@ +/* + * 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 + + +grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->tail += len; + if (net_buff->tail > net_buff->end) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->tail -= len; + if (net_buff->tail < net_buff->head) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->data -= len; + if (net_buff->data < net_buff->head) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->data += len; + if (net_buff->data > net_buff->end) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len) +{ + net_buff->data += len; + net_buff->tail += len; + if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return GRUB_ERR_NONE; +} + +struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ) +{ + if (len < NETBUFFMINLEN) + len = NETBUFFMINLEN; + len = ALIGN_UP (len,NETBUFF_ALIGN); + return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN); +} diff --git a/net/protocol.c b/net/protocol.c new file mode 100644 index 000000000..a6117dc2c --- /dev/null +++ b/net/protocol.c @@ -0,0 +1,21 @@ +#include + +static grub_net_protocol_t grub_net_protocols; + +void grub_protocol_register (grub_net_protocol_t prot) +{ + prot->next = grub_net_protocols; + grub_net_protocols = prot; +} + +void grub_protocol_unregister (grub_net_protocol_t prot) +{ + grub_net_protocol_t *p, q; + + for (p = &grub_net_protocols, q = *p; q; p = &(q->next), q = q->next) + if (q == prot) + { + *p = q->next; + break; + } +} diff --git a/net/tftp.c b/net/tftp.c new file mode 100644 index 000000000..fdca184e9 --- /dev/null +++ b/net/tftp.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*send read request*/ +static grub_err_t +send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,struct grub_net_buff *nb) +{ + /*Start TFTP header*/ + + struct tftphdr *tftph; + char *rrq; + int rrqlen; + int hdrlen; + grub_err_t err; + + if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE) + return err; + + tftph = (struct tftphdr *) nb->data; + + rrq = (char *) tftph->u.rrq; + rrqlen = 0; + + tftph->opcode = TFTP_RRQ; + grub_strcpy (rrq,inf->path); + rrqlen += grub_strlen (inf->path) + 1; + rrq += grub_strlen (inf->path) + 1; + /*passar opcoes como parametro ou usar default?*/ + + grub_strcpy (rrq,"octet"); + rrqlen += grub_strlen ("octet") + 1; + rrq += grub_strlen ("octet") + 1; + + grub_strcpy (rrq,"blksize"); + rrqlen += grub_strlen("blksize") + 1; + rrq += grub_strlen ("blksize") + 1; + + grub_strcpy (rrq,"1024"); + rrqlen += grub_strlen ("1024") + 1; + rrq += grub_strlen ("1024") + 1; + + grub_strcpy (rrq,"tsize"); + rrqlen += grub_strlen ("tsize") + 1; + rrq += grub_strlen ("tsize") + 1; + + grub_strcpy (rrq,"0"); + rrqlen += grub_strlen ("0") + 1; + rrq += grub_strlen ("0") + 1; + hdrlen = sizeof (tftph->opcode) + rrqlen; + + grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); + + return prot->next->send(inf,prot->next,nb); +} + +/* +int send_tftp_ack(int block, int port){ + + tftp_t pckt; + int pcktlen; + pckt.opcode = TFTP_ACK; + pckt.u.ack.block = block; + pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block); + + port = 4; + return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port); +} + +*/ + +static struct grub_net_protocol grub_tftp_protocol = +{ + .name = "tftp", + .open = send_tftp_rr + +}; + +void tftp_ini(void) +{ + grub_protocol_register (&grub_tftp_protocol); +} + +void tftp_fini(void) +{ + grub_protocol_unregister (&grub_tftp_protocol); +} +/* +int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){ + + + read_udp_packet (port,buffer,buff_len); + + +}*/ diff --git a/net/udp.c b/net/udp.c new file mode 100644 index 000000000..600eec542 --- /dev/null +++ b/net/udp.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +/*Assumes that there is allocated memory to the header before the buffer address. */ +static grub_err_t +send_udp_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb) +{ + + struct udphdr *udph; + grub_err_t err; + + if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE) + return err; + + udph = (struct udphdr *) nb->data; + udph->src = *((grub_uint16_t *) inf->card->tla->addr); + udph->dst = *((grub_uint16_t *) inf->tla->addr); + /*no chksum*/ + udph->chksum = 0; + udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head; + + return prot->next->send(inf,prot->next,nb); +} + +static struct grub_net_protocol grub_udp_protocol = +{ + .name = "udp", + .send = send_udp_packet +}; + +void udp_ini(void) +{ + grub_protocol_register (&grub_udp_protocol); +} + +void udp_fini(void) +{ + grub_protocol_unregister (&grub_udp_protocol); +} + +/* +int read_udp_packet (grub_uint16_t port,void *buffer,int *buff_len) +{ + + struct udphdr udph; + udph.dst = 0; + + while ( udph.dst != port) + { + read_ip_packet (buffer,bufflen); + grub_memcpy (&udph,buffer,sizeof (udph)); + } + + buffer += sizeof (udph); + *buff_len -= sizeof (udph); + +}*/ From 8d402bc9a8041f0ed15290901e0ff5f115ed5cc0 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Apr 2010 17:56:09 -0300 Subject: [PATCH 0016/1414] small change in the interface structure. --- include/grub/net.h | 14 ++++++++++++++ include/grub/net/interface.h | 18 ++++++++++++++---- include/grub/net/protocol.h | 33 +++++++++------------------------ net/ethernet.c | 3 ++- net/ip.c | 5 +++-- net/tftp.c | 5 +++-- net/udp.c | 5 +++-- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/include/grub/net.h b/include/grub/net.h index 75efd51d6..f021f0e9c 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -26,8 +26,22 @@ struct grub_net_card; +typedef enum +{ + GRUB_NET_TFTP_ID, + GRUB_NET_UDP_ID, + GRUB_NET_IPV4_ID, + GRUB_NET_IPV6_ID, + GRUB_NET_ETHERNET_ID, + GRUB_NET_ARP_ID, + GRUB_NET_DHCP_ID + +}protocol_type_t; + struct grub_net_card_driver { + grub_err_t (*init) (struct grub_net_card *dev); + grub_err_t (*fini) (struct grub_net_card *dev); grub_err_t (*send) (struct grub_net_card *dev,struct grub_net_buff *nb); grub_size_t (*recv) (struct grub_net_card *dev,struct grub_net_buff *nb); }; diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h index 0e11c86ba..2e0ddfcc8 100644 --- a/include/grub/net/interface.h +++ b/include/grub/net/interface.h @@ -2,16 +2,26 @@ #define GRUB_INTERFACE_HEADER #include #include -/* -extern struct grub_net_topprotocol; + +struct grub_net_protstack +{ + struct grub_net_protstack *next; + struct grub_net_protocol* prot; +}; struct grub_net_interface { struct grub_net_card *card; - struct grub_net_topprotocol* topprot; + struct grub_net_protstack* protstack; + char *path; + char *username; + char *password; + /*transport layer addres*/ struct grub_net_addr *tla; + /*internet layer addres*/ struct grub_net_addr *ila; + /*link layer addres*/ struct grub_net_addr *lla; }; -*/ + #endif diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index 2c979481b..1efc2ab7b 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -4,47 +4,32 @@ #include #include #include -struct protocol_operations; + struct grub_net_protocol; struct grub_net_interface; +struct grub_net_protstack; struct grub_net_protocol { struct grub_net_protocol *next; char *name; grub_err_t (*open) (struct grub_net_interface* inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*open_confirm) (struct grub_net_interface *inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*get_payload) (struct grub_net_interface *inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*close) (struct grub_net_interface *inf, - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*send) (struct grub_net_interface *inf , - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); grub_err_t (*recv) (struct grub_net_interface *inf , - struct grub_net_protocol *prot, struct grub_net_buff *nb); + struct grub_net_protstack *protstack, struct grub_net_buff *nb); }; typedef struct grub_net_protocol *grub_net_protocol_t; - -struct grub_net_interface -{ - struct grub_net_card *card; - struct grub_net_protocol* prot; - char *path; - char *username; - char *password; - /*transport layer addres*/ - struct grub_net_addr *tla; - /*internet layer addres*/ - struct grub_net_addr *ila; - /*link layer addres*/ - struct grub_net_addr *lla; -}; - void grub_protocol_register (grub_net_protocol_t prot); void grub_protocol_unregister (grub_net_protocol_t prot); #endif diff --git a/net/ethernet.c b/net/ethernet.c index fc64803e7..8c13966c1 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -6,9 +6,10 @@ #include #include #include +#include static grub_err_t -send_ethernet_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot __attribute__ ((unused)) +send_ethernet_packet (struct grub_net_interface *inf,struct grub_net_protstack *protstack __attribute__ ((unused)) ,struct grub_net_buff *nb) { diff --git a/net/ip.c b/net/ip.c index c669ff6d7..6fe58adb0 100644 --- a/net/ip.c +++ b/net/ip.c @@ -5,6 +5,7 @@ #include #include #include +#include #include struct grub_net_protocol *grub_ipv4_prot; @@ -28,7 +29,7 @@ ipchksum(void *ipv, int len) static grub_err_t -send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb ) +send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb ) { struct iphdr *iph; @@ -57,7 +58,7 @@ send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, iph->chksum = ipchksum((void *)nb->head, sizeof(*iph)); - return prot->next->send(inf,prot->next,nb); + return protstack->next->prot->send(inf,protstack->next,nb); } static struct grub_net_protocol grub_ipv4_protocol = diff --git a/net/tftp.c b/net/tftp.c index fdca184e9..3f481fe58 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -8,10 +8,11 @@ #include #include #include +#include /*send read request*/ static grub_err_t -send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,struct grub_net_buff *nb) +send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protstack,struct grub_net_buff *nb) { /*Start TFTP header*/ @@ -58,7 +59,7 @@ send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,str grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); - return prot->next->send(inf,prot->next,nb); + return protstack->next->prot->send(inf,protstack->next,nb); } /* diff --git a/net/udp.c b/net/udp.c index 600eec542..2a4a7690b 100644 --- a/net/udp.c +++ b/net/udp.c @@ -3,9 +3,10 @@ #include #include #include +#include /*Assumes that there is allocated memory to the header before the buffer address. */ static grub_err_t -send_udp_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb) +send_udp_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb) { struct udphdr *udph; @@ -21,7 +22,7 @@ send_udp_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, udph->chksum = 0; udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head; - return prot->next->send(inf,prot->next,nb); + return protstack->next->prot->send(inf,protstack->next,nb); } static struct grub_net_protocol grub_udp_protocol = From 87fae34a1ff2b165ad532b251e328494797cfc8e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 May 2010 14:54:51 +0200 Subject: [PATCH 0017/1414] Skeleton for keyboard layouts --- commands/cat.c | 2 +- commands/keylayouts.c | 186 ++++++++++++++++++++++++++++++++++++++ commands/keystatus.c | 15 ++- commands/sleep.c | 3 +- conf/common.rmk | 5 + include/grub/term.h | 44 +++++---- kern/i386/pc/startup.S | 49 ---------- kern/rescue_reader.c | 2 +- kern/term.c | 36 +------- lib/crypto.c | 2 +- normal/auth.c | 2 +- normal/cmdline.c | 33 ++++--- normal/main.c | 2 +- normal/menu.c | 23 +++-- normal/menu_entry.c | 48 ++++++---- term/at_keyboard.c | 25 +++-- term/i386/pc/console.c | 1 + term/usb_keyboard.c | 6 +- util/grub-fstest.c | 7 +- util/grub-probe.c | 7 +- util/i386/pc/grub-setup.c | 7 +- 21 files changed, 337 insertions(+), 168 deletions(-) create mode 100644 commands/keylayouts.c diff --git a/commands/cat.c b/commands/cat.c index 3bdafc4c6..556196b4a 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -63,7 +63,7 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), } while (grub_checkkey () >= 0 && - (key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC) + (key = grub_getkey ()) != GRUB_TERM_ESC) ; } diff --git a/commands/keylayouts.c b/commands/keylayouts.c new file mode 100644 index 000000000..35bbb8376 --- /dev/null +++ b/commands/keylayouts.c @@ -0,0 +1,186 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +static int keyboard_map[128] = +{ + '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', '\n', '\0', 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', '\0', '*', + '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, + GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, + GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC +}; + +/* Define scan codes. */ +#define GRUB_TERM_AT_KEY_LEFT 0x4B00 +#define GRUB_TERM_AT_KEY_RIGHT 0x4D00 +#define GRUB_TERM_AT_KEY_UP 0x4800 +#define GRUB_TERM_AT_KEY_DOWN 0x5000 +#define GRUB_TERM_AT_KEY_IC 0x5200 +#define GRUB_TERM_AT_KEY_DC 0x5300 +#define GRUB_TERM_AT_KEY_BACKSPACE 0x0008 +#define GRUB_TERM_AT_KEY_HOME 0x4700 +#define GRUB_TERM_AT_KEY_END 0x4F00 +#define GRUB_TERM_AT_KEY_NPAGE 0x5100 +#define GRUB_TERM_AT_KEY_PPAGE 0x4900 + +static int +get_abstract_code (grub_term_input_t term, int in) +{ + unsigned flags = 0; + switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) + { + default: + return in; + case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS: + { + unsigned status = 0; + if (term->getkeystatus) + status = term->getkeystatus (); + if (status & GRUB_TERM_CAPS) + flags |= GRUB_TERM_CAPS; + } + /* Fall through. */ + case GRUB_TERM_INPUT_FLAGS_TYPE_AT: + { + struct { + int from, to; + } translations[] = + { + {GRUB_TERM_AT_KEY_LEFT, GRUB_TERM_KEY_LEFT}, + {GRUB_TERM_AT_KEY_RIGHT, GRUB_TERM_KEY_RIGHT}, + {GRUB_TERM_AT_KEY_UP, GRUB_TERM_KEY_UP}, + {GRUB_TERM_AT_KEY_DOWN, GRUB_TERM_KEY_DOWN}, + {GRUB_TERM_AT_KEY_HOME, GRUB_TERM_KEY_HOME}, + {GRUB_TERM_AT_KEY_END, GRUB_TERM_KEY_END}, + {GRUB_TERM_AT_KEY_DC, GRUB_TERM_KEY_DC}, + {GRUB_TERM_AT_KEY_PPAGE, GRUB_TERM_KEY_PPAGE}, + {GRUB_TERM_AT_KEY_NPAGE, GRUB_TERM_KEY_NPAGE} + }; + unsigned i; + for (i = 0; i < ARRAY_SIZE (translations); i++) + if (translations[i].from == (in & 0xffff)) + return translations[i].to | flags; + if ((term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) + == GRUB_TERM_INPUT_FLAGS_TYPE_AT) + return in & ~0xff00; + /* Detect CTRL'ed keys. */ + if ((in & 0xff) > 0 && (in & 0xff) < 0x20 + && ((in & 0xffff) != (0x0100 | '\e')) + && ((in & 0xffff) != (0x0f00 | '\t')) + && ((in & 0xffff) != (0x0e00 | '\b')) + && ((in & 0xffff) != (0x1c00 | '\r')) + && ((in & 0xffff) != (0x1c00 | '\n'))) + return ((in & 0xff) - 1 + 'a') | flags | GRUB_TERM_CTRL; + /* Detect ALT'ed keys. */ + /* XXX no way to distinguish left and right ALT. */ + if (((in & 0xff) == 0) && keyboard_map[(in & 0xff00) >> 8] >= 'a' + && keyboard_map[(in & 0xff00) >> 8] <= 'z') + return keyboard_map[(in & 0xff00) >> 8] | flags | GRUB_TERM_ALT_GR; + + return (in & 0xff) | flags; + } + } +} + +static int +map (grub_term_input_t term __attribute__ ((unused)), int in) +{ + return in; +} + +static int +translate (grub_term_input_t term, int in) +{ + int code, code2; + code = get_abstract_code (term, in); + if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'a' && (code & 0xff) <= 'z') + code = (code & 0xff) + 'A' - 'a'; + else if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'A' + && (code & 0xff) <= 'Z') + code = (code & 0xff) + 'a' - 'A'; + + code2 = map (term, code & 0xff); + if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'a' && (code2 & 0xff) <= 'z') + code2 = code2 + 'A' - 'a'; + else if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'A' + && (code2 & 0xff) <= 'Z') + code2 = code2 + 'a' - 'A'; + return code2 | (code & ~0xffffff); +} + +static int +grub_getkey_smart (void) +{ + grub_term_input_t term; + + grub_refresh (); + + while (1) + { + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->checkkey (); + if (key != -1) + return translate (term, term->getkey ()); + } + + grub_cpu_idle (); + } +} + +int +grub_checkkey (void) +{ + grub_term_input_t term; + + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->checkkey (); + if (key != -1) + return translate (term, key); + } + + return -1; +} + +static int (*grub_getkey_saved) (void); + +GRUB_MOD_INIT(keylayouts) +{ + grub_getkey_saved = grub_getkey; + grub_getkey = grub_getkey_smart; +} + +GRUB_MOD_FINI(keylayouts) +{ + grub_getkey = grub_getkey_saved; +} diff --git a/commands/keystatus.c b/commands/keystatus.c index 838792889..fc4d11d73 100644 --- a/commands/keystatus.c +++ b/commands/keystatus.c @@ -31,7 +31,20 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -#define grub_cur_term_input grub_term_get_current_input () +static int +grub_getkeystatus (void) +{ + int status = 0; + grub_term_input_t term; + + FOR_ACTIVE_TERM_INPUTS(term) + { + if (term->getkeystatus) + status |= term->getkeystatus (); + } + + return status; +} static grub_err_t grub_cmd_keystatus (grub_extcmd_t cmd, diff --git a/commands/sleep.c b/commands/sleep.c index ead279506..bce1aee1d 100644 --- a/commands/sleep.c +++ b/commands/sleep.c @@ -52,8 +52,7 @@ grub_interruptible_millisleep (grub_uint32_t ms) start = grub_get_time_ms (); while (grub_get_time_ms () - start < ms) - if (grub_checkkey () >= 0 && - GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC) + if (grub_checkkey () >= 0 && grub_getkey () == GRUB_TERM_ESC) return 1; return 0; diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..13e1c7a6c 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -491,6 +491,11 @@ extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c extcmd_mod_CFLAGS = $(COMMON_CFLAGS) extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += keylayouts.mod +keylayouts_mod_SOURCES = commands/keylayouts.c +keylayouts_mod_CFLAGS = $(COMMON_CFLAGS) +keylayouts_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For hello.mod. hello_mod_SOURCES = hello/hello.c hello_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..a2fa80c1f 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -20,18 +20,27 @@ #define GRUB_TERM_HEADER 1 /* Internal codes used by GRUB to represent terminal input. */ -#define GRUB_TERM_LEFT 2 -#define GRUB_TERM_RIGHT 6 -#define GRUB_TERM_UP 16 -#define GRUB_TERM_DOWN 14 -#define GRUB_TERM_HOME 1 -#define GRUB_TERM_END 5 -#define GRUB_TERM_DC 4 -#define GRUB_TERM_PPAGE 7 -#define GRUB_TERM_NPAGE 3 +#define GRUB_TERM_CTRL 0x02000000 +#define GRUB_TERM_ALT 0x04000000 +/* Used by keylayouts code. Never returned in grub_getkey. */ +#define GRUB_TERM_ALT_GR 0x08000000 +#define GRUB_TERM_CAPS 0x10000000 + +/* Keys without associated character. */ +#define GRUB_TERM_EXTENDED 0x1000000 +#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 1) +#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 2) +#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 3) +#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 4) +#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 5) +#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 6) +#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 7) +#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 8) +#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 9) + #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' -#define GRUB_TERM_BACKSPACE 8 +#define GRUB_TERM_BACKSPACE '\b' #ifndef ASM_FILE @@ -135,9 +144,15 @@ struct grub_term_input /* Get keyboard modifier status. */ int (*getkeystatus) (void); + + grub_uint32_t flags; }; typedef struct grub_term_input *grub_term_input_t; +#define GRUB_TERM_INPUT_FLAGS_TYPE_MASK 0xf +#define GRUB_TERM_INPUT_FLAGS_TYPE_AT 0x1 +#define GRUB_TERM_INPUT_FLAGS_TYPE_BIOS 0x2 + struct grub_term_output { /* The next terminal. */ @@ -253,9 +268,8 @@ grub_term_unregister_output (grub_term_output_t term) void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, struct grub_term_output *term); -int EXPORT_FUNC(grub_getkey) (void); -int EXPORT_FUNC(grub_checkkey) (void); -int EXPORT_FUNC(grub_getkeystatus) (void); +extern int (*EXPORT_VAR(grub_getkey)) (void); +int grub_checkkey (void); void EXPORT_FUNC(grub_cls) (void); void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); void EXPORT_FUNC(grub_refresh) (void); @@ -409,10 +423,6 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) grub_putcode (' ', term); } - -/* For convenience. */ -#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff) - #endif /* ! ASM_FILE */ #endif /* ! GRUB_TERM_HEADER */ diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 374277767..6aa3297ab 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1154,54 +1154,6 @@ FUNCTION(grub_console_real_putchar) * %al = ASCII character */ -/* this table is used in translate_keycode below */ -LOCAL (translation_table): - .word GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT - .word GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT - .word GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP - .word GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN - .word GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME - .word GRUB_CONSOLE_KEY_END, GRUB_TERM_END - .word GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC - .word GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE - .word GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE - .word GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE - .word 0 - -/* - * translate_keycode translates the key code %dx to an ascii code. - */ - .code16 - -translate_keycode: - pushw %bx - pushw %si - -#ifdef __APPLE__ - movw $(ABS(LOCAL (translation_table)) - 0x10000), %si -#else - movw $ABS(LOCAL (translation_table)), %si -#endif - -1: lodsw - /* check if this is the end */ - testw %ax, %ax - jz 2f - /* load the ascii code into %ax */ - movw %ax, %bx - lodsw - /* check if this matches the key code */ - cmpw %bx, %dx - jne 1b - /* translate %dx, if successful */ - movw %ax, %dx - -2: popw %si - popw %bx - ret - - .code32 - FUNCTION(grub_console_getkey) pushl %ebp @@ -1228,7 +1180,6 @@ FUNCTION(grub_console_getkey) int $0x16 movw %ax, %dx /* real_to_prot uses %eax */ - call translate_keycode DATA32 call real_to_prot .code32 diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index f573cf41f..7cecac6ec 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -38,7 +38,7 @@ grub_rescue_read_line (char **line, int cont) grub_printf ((cont) ? "> " : "grub rescue> "); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); - while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r') + while ((c = grub_getkey ()) != '\n' && c != '\r') { if (grub_isprint (c)) { diff --git a/kern/term.c b/kern/term.c index 6e3a2b454..ab3d952fa 100644 --- a/kern/term.c +++ b/kern/term.c @@ -75,8 +75,8 @@ grub_putchar (int c) } } -int -grub_getkey (void) +static int +grub_getkey_dumb (void) { grub_term_input_t term; @@ -88,42 +88,14 @@ grub_getkey (void) { int key = term->checkkey (); if (key != -1) - return term->getkey (); + return term->getkey () & 0xff; } grub_cpu_idle (); } } -int -grub_checkkey (void) -{ - grub_term_input_t term; - - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->checkkey (); - if (key != -1) - return key; - } - - return -1; -} - -int -grub_getkeystatus (void) -{ - int status = 0; - grub_term_input_t term; - - FOR_ACTIVE_TERM_INPUTS(term) - { - if (term->getkeystatus) - status |= term->getkeystatus (); - } - - return status; -} +int (*grub_getkey) (void) = grub_getkey_dumb; void grub_cls (void) diff --git a/lib/crypto.c b/lib/crypto.c index d11f0994f..405d18911 100644 --- a/lib/crypto.c +++ b/lib/crypto.c @@ -420,7 +420,7 @@ grub_password_get (char buf[], unsigned buf_size) while (1) { - key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + key = grub_getkey (); if (key == '\n' || key == '\r') break; diff --git a/normal/auth.c b/normal/auth.c index 156b84c37..76dfddb53 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -162,7 +162,7 @@ grub_username_get (char buf[], unsigned buf_size) while (1) { - key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + key = grub_getkey (); if (key == '\n' || key == '\r') break; diff --git a/normal/cmdline.c b/normal/cmdline.c index 05d665411..618e25e08 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -387,16 +387,18 @@ grub_cmdline_get (const char *prompt) grub_refresh (); - while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r') + while ((key = grub_getkey ()) != '\n' && key != '\r') { switch (key) { - case 1: /* Ctrl-a */ + case GRUB_TERM_CTRL | 'a': + case GRUB_TERM_KEY_HOME: lpos = 0; cl_set_pos_all (); break; - case 2: /* Ctrl-b */ + case GRUB_TERM_CTRL | 'b': + case GRUB_TERM_KEY_LEFT: if (lpos > 0) { lpos--; @@ -404,12 +406,14 @@ grub_cmdline_get (const char *prompt) } break; - case 5: /* Ctrl-e */ + case GRUB_TERM_CTRL | 'e': + case GRUB_TERM_KEY_END: lpos = llen; cl_set_pos_all (); break; - case 6: /* Ctrl-f */ + case GRUB_TERM_CTRL | 'f': + case GRUB_TERM_KEY_RIGHT: if (lpos < llen) { lpos++; @@ -417,7 +421,8 @@ grub_cmdline_get (const char *prompt) } break; - case 9: /* Ctrl-i or TAB */ + case GRUB_TERM_CTRL | 'i': + case '\t': { int restore; char *insertu8; @@ -489,7 +494,7 @@ grub_cmdline_get (const char *prompt) } break; - case 11: /* Ctrl-k */ + case GRUB_TERM_CTRL | 'k': if (lpos < llen) { if (kill_buf) @@ -513,7 +518,8 @@ grub_cmdline_get (const char *prompt) } break; - case 14: /* Ctrl-n */ + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: { grub_uint32_t *hist; @@ -531,7 +537,9 @@ grub_cmdline_get (const char *prompt) break; } - case 16: /* Ctrl-p */ + + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': { grub_uint32_t *hist; @@ -550,7 +558,7 @@ grub_cmdline_get (const char *prompt) } break; - case 21: /* Ctrl-u */ + case GRUB_TERM_CTRL | 'u': if (lpos > 0) { grub_size_t n = lpos; @@ -576,7 +584,7 @@ grub_cmdline_get (const char *prompt) } break; - case 25: /* Ctrl-y */ + case GRUB_TERM_CTRL | 'y': if (kill_buf) cl_insert (kill_buf); break; @@ -594,7 +602,8 @@ grub_cmdline_get (const char *prompt) break; /* fall through */ - case 4: /* Ctrl-d */ + case GRUB_TERM_CTRL | 'd': + case GRUB_TERM_KEY_DC: if (lpos < llen) cl_delete (1); break; diff --git a/normal/main.c b/normal/main.c index 4ed17e82c..ff4be3a79 100644 --- a/normal/main.c +++ b/normal/main.c @@ -163,7 +163,7 @@ static struct { {"backspace", '\b'}, {"tab", '\t'}, - {"delete", GRUB_TERM_DC} + {"delete", GRUB_TERM_KEY_DC} }; /* Add a menu entry to the current menu context (as given by the environment diff --git a/normal/menu.c b/normal/menu.c index 09c5fd1eb..b740ea3ca 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -397,7 +397,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (grub_checkkey () >= 0 || timeout < 0) { - c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + c = grub_getkey (); if (timeout >= 0) { @@ -408,31 +408,36 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) switch (c) { - case GRUB_TERM_HOME: + case GRUB_TERM_KEY_HOME: + case GRUB_TERM_CTRL | 'a': current_entry = 0; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_END: + case GRUB_TERM_KEY_END: + case GRUB_TERM_CTRL | 'e': current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_UP: + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': case '^': if (current_entry > 0) current_entry--; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_DOWN: + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: case 'v': if (current_entry < menu->size - 1) current_entry++; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_PPAGE: + case GRUB_TERM_CTRL | 'g': + case GRUB_TERM_KEY_PPAGE: if (current_entry < GRUB_MENU_PAGE_SIZE) current_entry = 0; else @@ -440,7 +445,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_NPAGE: + case GRUB_TERM_CTRL | 'c': + case GRUB_TERM_KEY_NPAGE: if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) current_entry += GRUB_MENU_PAGE_SIZE; else @@ -450,7 +456,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) case '\n': case '\r': - case 6: + case GRUB_TERM_KEY_RIGHT: + case GRUB_TERM_CTRL | 'f': menu_fini (); *auto_boot = 0; return current_entry; diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 644fe90fd..0b03147dd 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -1262,7 +1262,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) while (1) { - int c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + int c = grub_getkey (); if (screen->completion_shown) { @@ -1278,70 +1278,78 @@ grub_menu_entry_run (grub_menu_entry_t entry) switch (c) { - case 16: /* C-p */ + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': if (! previous_line (screen, 1)) goto fail; break; - case 14: /* C-n */ + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: if (! next_line (screen, 1)) goto fail; break; - case 6: /* C-f */ + case GRUB_TERM_CTRL | 'f': + case GRUB_TERM_KEY_RIGHT: if (! forward_char (screen, 1)) goto fail; break; - case 2: /* C-b */ + case GRUB_TERM_CTRL | 'b': + case GRUB_TERM_KEY_LEFT: if (! backward_char (screen, 1)) goto fail; break; - case 1: /* C-a */ + case GRUB_TERM_CTRL | 'a': + case GRUB_TERM_KEY_HOME: if (! beginning_of_line (screen, 1)) goto fail; break; - case 5: /* C-e */ + case GRUB_TERM_CTRL | 'e': + case GRUB_TERM_KEY_END: if (! end_of_line (screen, 1)) goto fail; break; - case '\t': /* C-i */ + case GRUB_TERM_CTRL | 'i': + case '\t': if (! complete (screen, prev_c == c, 1)) goto fail; break; - case 4: /* C-d */ + case GRUB_TERM_CTRL | 'd': + case GRUB_TERM_KEY_DC: if (! delete_char (screen, 1)) goto fail; break; - case 8: /* C-h */ + case GRUB_TERM_CTRL | 'h': if (! backward_delete_char (screen, 1)) goto fail; break; - case 11: /* C-k */ + case GRUB_TERM_CTRL | 'k': if (! kill_line (screen, prev_c == c, 1)) goto fail; break; - case 21: /* C-u */ + case GRUB_TERM_CTRL | 'u': /* FIXME: What behavior is good for this key? */ break; - case 25: /* C-y */ + case GRUB_TERM_CTRL | 'y': if (! yank (screen, 1)) goto fail; break; - case 12: /* C-l */ + case GRUB_TERM_CTRL | 'l': /* FIXME: centering. */ goto refresh; - case 15: /* C-o */ + case GRUB_TERM_CTRL | 'o': if (! open_line (screen, 1)) goto fail; break; @@ -1356,18 +1364,18 @@ grub_menu_entry_run (grub_menu_entry_t entry) destroy_screen (screen); return; - case 3: /* C-c */ + case GRUB_TERM_CTRL | 'c': grub_cmdline_run (1); goto refresh; - case 24: /* C-x */ + case GRUB_TERM_CTRL | 'x': if (! run (screen)) goto fail; goto refresh; - case 18: /* C-r */ - case 19: /* C-s */ - case 20: /* C-t */ + case GRUB_TERM_CTRL | 'r': + case GRUB_TERM_CTRL | 's': + case GRUB_TERM_CTRL | 't': /* FIXME */ break; diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 1f84ae71a..f1932f64e 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -41,7 +41,7 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_CAPS (1 << 2) -static char keyboard_map[128] = +static int keyboard_map[128] = { '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, @@ -51,9 +51,9 @@ static char keyboard_map[128] = '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', '*', '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME, - GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END, - GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, + GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, + GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC, '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT @@ -213,9 +213,8 @@ grub_at_keyboard_getkey_noblock (void) key = -1; break; default: - if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) - key = keyboard_map[code] - 'a' + 1; - else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R)) + if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L + | KEYBOARD_STATUS_SHIFT_R)) && keyboard_map_shift[code]) key = keyboard_map_shift[code]; else @@ -231,6 +230,17 @@ grub_at_keyboard_getkey_noblock (void) else if ((key >= 'A') && (key <= 'Z')) key += 'a' - 'A'; } + + if (at_keyboard_status & KEYBOARD_STATUS_ALT_L) + key |= GRUB_TERM_ALT; + if (at_keyboard_status & KEYBOARD_STATUS_ALT_R) + key |= GRUB_TERM_ALT_GR; + if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L + | KEYBOARD_STATUS_CTRL_R)) + key |= GRUB_TERM_CTRL; + + if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK) + key |= GRUB_TERM_CAPS; } return key; } @@ -290,6 +300,7 @@ static struct grub_term_input grub_at_keyboard_term = .fini = grub_keyboard_controller_fini, .checkkey = grub_at_keyboard_checkkey, .getkey = grub_at_keyboard_getkey, + .flags = GRUB_TERM_INPUT_FLAGS_TYPE_AT }; GRUB_MOD_INIT(at_keyboard) diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 43cfe2f2a..09baabd8f 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -51,6 +51,7 @@ static struct grub_term_input grub_console_term_input = .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, .getkeystatus = grub_console_getkeystatus, + .flags = GRUB_TERM_INPUT_FLAGS_TYPE_BIOS }; static struct grub_term_output grub_console_term_output = diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..8f9a79ec4 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -28,7 +28,7 @@ #include -static char keyboard_map[128] = +static int keyboard_map[128] = { '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', @@ -39,8 +39,8 @@ static char keyboard_map[128] = ']', '\\', '#', ';', '\'', '`', ',', '.', '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, GRUB_TERM_NPAGE, GRUB_TERM_RIGHT, - GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP + '\0', '\0', GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, + GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP }; static char keyboard_map_shift[128] = diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c03c43451..14ddf2ad8 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -49,14 +49,13 @@ grub_putchar (int c) putchar (c); } -int -grub_getkey (void) +static int +grub_getkey_real (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; +int (*grub_getkey) (void) = grub_getkey_real; void grub_refresh (void) diff --git a/util/grub-probe.c b/util/grub-probe.c index bb41480e2..cb082da6d 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -64,14 +64,13 @@ grub_putchar (int c) putchar (c); } -int -grub_getkey (void) +static int +grub_getkey_real (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; +int (*grub_getkey) (void) = grub_getkey_real; void grub_refresh (void) diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..ffdb356a6 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -63,14 +63,13 @@ grub_putchar (int c) putchar (c); } -int -grub_getkey (void) +static int +grub_getkey_real (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; +int (*grub_getkey) (void) = grub_getkey_real; void grub_refresh (void) From 08bfb543c40ade8ed8d19dc9eb2d797172482282 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 May 2010 15:04:46 +0200 Subject: [PATCH 0018/1414] Add key_102 --- commands/keylayouts.c | 13 ++++++++++--- include/grub/term.h | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 35bbb8376..24da21364 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -83,7 +83,9 @@ get_abstract_code (grub_term_input_t term, int in) {GRUB_TERM_AT_KEY_END, GRUB_TERM_KEY_END}, {GRUB_TERM_AT_KEY_DC, GRUB_TERM_KEY_DC}, {GRUB_TERM_AT_KEY_PPAGE, GRUB_TERM_KEY_PPAGE}, - {GRUB_TERM_AT_KEY_NPAGE, GRUB_TERM_KEY_NPAGE} + {GRUB_TERM_AT_KEY_NPAGE, GRUB_TERM_KEY_NPAGE}, + {0x5600 | '\\', GRUB_TERM_KEY_102}, + {0x5600 | '|', GRUB_TERM_KEY_SHIFT_102}, }; unsigned i; for (i = 0; i < ARRAY_SIZE (translations); i++) @@ -114,6 +116,11 @@ get_abstract_code (grub_term_input_t term, int in) static int map (grub_term_input_t term __attribute__ ((unused)), int in) { + if (in == GRUB_TERM_KEY_102) + return '\\'; + if (in == GRUB_TERM_KEY_SHIFT_102) + return '|'; + return in; } @@ -128,13 +135,13 @@ translate (grub_term_input_t term, int in) && (code & 0xff) <= 'Z') code = (code & 0xff) + 'a' - 'A'; - code2 = map (term, code & 0xff); + code2 = map (term, code & 0x1ffffff); if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'a' && (code2 & 0xff) <= 'z') code2 = code2 + 'A' - 'a'; else if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'A' && (code2 & 0xff) <= 'Z') code2 = code2 + 'a' - 'A'; - return code2 | (code & ~0xffffff); + return code2 | (code & ~0x1ffffff); } static int diff --git a/include/grub/term.h b/include/grub/term.h index a2fa80c1f..b3db120df 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -37,6 +37,9 @@ #define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 7) #define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 8) #define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 9) +/* Used by keylayouts code. Never returned in grub_getkey. */ +#define GRUB_TERM_KEY_102 (GRUB_TERM_EXTENDED | 10) +#define GRUB_TERM_KEY_SHIFT_102 (GRUB_TERM_EXTENDED | 11) #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' From 1ff38af9b95e76e9e63f85fa1981b0c89c132ed9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 May 2010 20:57:01 +0200 Subject: [PATCH 0019/1414] Simplify AT keyboards and support 102nd key --- commands/keylayouts.c | 19 ++++++++----------- include/grub/term.h | 6 +++--- term/at_keyboard.c | 10 ++++++---- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 24da21364..9b1d92c73 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -58,19 +58,12 @@ get_abstract_code (grub_term_input_t term, int in) unsigned flags = 0; switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) { + case GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES: default: return in; case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS: { unsigned status = 0; - if (term->getkeystatus) - status = term->getkeystatus (); - if (status & GRUB_TERM_CAPS) - flags |= GRUB_TERM_CAPS; - } - /* Fall through. */ - case GRUB_TERM_INPUT_FLAGS_TYPE_AT: - { struct { int from, to; } translations[] = @@ -88,12 +81,16 @@ get_abstract_code (grub_term_input_t term, int in) {0x5600 | '|', GRUB_TERM_KEY_SHIFT_102}, }; unsigned i; + + if (term->getkeystatus) + status = term->getkeystatus (); + if (status & GRUB_TERM_CAPS) + flags |= GRUB_TERM_CAPS; + for (i = 0; i < ARRAY_SIZE (translations); i++) if (translations[i].from == (in & 0xffff)) return translations[i].to | flags; - if ((term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) - == GRUB_TERM_INPUT_FLAGS_TYPE_AT) - return in & ~0xff00; + /* Detect CTRL'ed keys. */ if ((in & 0xff) > 0 && (in & 0xff) < 0x20 && ((in & 0xffff) != (0x0100 | '\e')) diff --git a/include/grub/term.h b/include/grub/term.h index b3db120df..064093bc5 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -152,9 +152,9 @@ struct grub_term_input }; typedef struct grub_term_input *grub_term_input_t; -#define GRUB_TERM_INPUT_FLAGS_TYPE_MASK 0xf -#define GRUB_TERM_INPUT_FLAGS_TYPE_AT 0x1 -#define GRUB_TERM_INPUT_FLAGS_TYPE_BIOS 0x2 +#define GRUB_TERM_INPUT_FLAGS_TYPE_MASK 0xf +#define GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES 0x0 +#define GRUB_TERM_INPUT_FLAGS_TYPE_BIOS 0x1 struct grub_term_output { diff --git a/term/at_keyboard.c b/term/at_keyboard.c index f1932f64e..bf94200cc 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -53,13 +53,14 @@ static int keyboard_map[128] = '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, - GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC, '\0', '\0', '\0', '\0', + GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC, '\0', '\0', + GRUB_TERM_KEY_102, '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT }; -static char keyboard_map_shift[128] = +static int keyboard_map_shift[128] = { '\0', '\0', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\0', '\0', @@ -67,7 +68,8 @@ static char keyboard_map_shift[128] = 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?' + 'B', 'N', 'M', '<', '>', '?', + [0x56] = GRUB_TERM_KEY_SHIFT_102 }; static grub_uint8_t grub_keyboard_controller_orig; @@ -300,7 +302,7 @@ static struct grub_term_input grub_at_keyboard_term = .fini = grub_keyboard_controller_fini, .checkkey = grub_at_keyboard_checkkey, .getkey = grub_at_keyboard_getkey, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_AT + .flags = GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES }; GRUB_MOD_INIT(at_keyboard) From 176194068fd30237e1262271cb8d9cbfcd380fb0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 May 2010 21:23:40 +0200 Subject: [PATCH 0020/1414] cleaner AltGr handling --- commands/keylayouts.c | 31 ++++++++++++++++++++++--------- include/grub/term.h | 1 + 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 9b1d92c73..370d55c4f 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -111,8 +111,13 @@ get_abstract_code (grub_term_input_t term, int in) } static int -map (grub_term_input_t term __attribute__ ((unused)), int in) +map (grub_term_input_t term, int in) { + /* No match with AltGr. Interpret it as Alt rather than as L3 modifier then. + */ + if (in & GRUB_TERM_ALT_GR) + return map (term, in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT_GR; + if (in == GRUB_TERM_KEY_102) return '\\'; if (in == GRUB_TERM_KEY_SHIFT_102) @@ -124,7 +129,7 @@ map (grub_term_input_t term __attribute__ ((unused)), int in) static int translate (grub_term_input_t term, int in) { - int code, code2; + int code, flags; code = get_abstract_code (term, in); if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'a' && (code & 0xff) <= 'z') code = (code & 0xff) + 'A' - 'a'; @@ -132,13 +137,21 @@ translate (grub_term_input_t term, int in) && (code & 0xff) <= 'Z') code = (code & 0xff) + 'a' - 'A'; - code2 = map (term, code & 0x1ffffff); - if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'a' && (code2 & 0xff) <= 'z') - code2 = code2 + 'A' - 'a'; - else if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'A' - && (code2 & 0xff) <= 'Z') - code2 = code2 + 'a' - 'A'; - return code2 | (code & ~0x1ffffff); + flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR); + code &= (GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR); + code = map (term, code); + /* Transform unconsumed AltGr into Alt. */ + if (code & GRUB_TERM_ALT_GR) + { + flags |= GRUB_TERM_ALT; + code &= ~GRUB_TERM_ALT_GR; + } + if ((flags & GRUB_TERM_CAPS) && code >= 'a' && code <= 'z') + code += 'A' - 'a'; + else if ((flags & GRUB_TERM_CAPS) && code >= 'A' + && code <= 'Z') + code += 'a' - 'A'; + return code | flags; } static int diff --git a/include/grub/term.h b/include/grub/term.h index 064093bc5..626349ac5 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -28,6 +28,7 @@ /* Keys without associated character. */ #define GRUB_TERM_EXTENDED 0x1000000 +#define GRUB_TERM_KEY_MASK 0x1ffffff #define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 1) #define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 2) #define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 3) From 9fbfb64abec41ceebbf4844efdd408ee2a681e9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 May 2010 21:25:46 +0200 Subject: [PATCH 0021/1414] adjust usb_keyboard for keylayouts --- term/usb_keyboard.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 8f9a79ec4..5a388eb73 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -150,10 +150,16 @@ grub_usb_keyboard_checkkey (void) data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - /* Check if the Control or Shift key was pressed. */ - if (data[0] & 0x01 || data[0] & 0x10) - key = keyboard_map[data[2]] - 'a' + 1; - else if (data[0] & 0x02 || data[0] & 0x20) +#define GRUB_USB_KEYBOARD_LEFT_CTRL 0x01 +#define GRUB_USB_KEYBOARD_LEFT_SHIFT 0x02 +#define GRUB_USB_KEYBOARD_LEFT_ALT 0x04 +#define GRUB_USB_KEYBOARD_RIGHT_CTRL 0x10 +#define GRUB_USB_KEYBOARD_RIGHT_SHIFT 0x20 +#define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 + + /* Check if the Shift key was pressed. */ + if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT + || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) key = keyboard_map_shift[data[2]]; else key = keyboard_map[data[2]]; @@ -161,6 +167,18 @@ grub_usb_keyboard_checkkey (void) if (key == 0) grub_printf ("Unknown key 0x%x detected\n", data[2]); + /* Check if the Ctrl key was pressed. */ + if (data[0] & GRUB_USB_KEYBOARD_LEFT_CTRL + || data[0] & GRUB_USB_KEYBOARD_RIGHT_CTRL) + key |= GRUB_TERM_CTRL; + + /* Check if the Alt key was pressed. */ + if (data[0] & GRUB_USB_KEYBOARD_LEFT_ALT) + key |= GRUB_TERM_ALT; + + if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT) + key |= GRUB_TERM_ALT_GR; + #if 0 /* Wait until the key is released. */ while (!err && data[2]) @@ -314,6 +332,7 @@ static struct grub_term_input grub_usb_keyboard_term = .checkkey = grub_usb_keyboard_checkkey, .getkey = grub_usb_keyboard_getkey, .getkeystatus = grub_usb_keyboard_getkeystatus, + .flags = GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES, .next = 0 }; From 092fd48a25b748ff9969883815554f7980b34fe3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 May 2010 15:19:01 +0200 Subject: [PATCH 0022/1414] legacy parser prototype --- commands/legacycfg.c | 521 +++++++++++++++++++++++++++++++++++++++++++ conf/i386-pc.rmk | 6 + 2 files changed, 527 insertions(+) create mode 100644 commands/legacycfg.c diff --git a/commands/legacycfg.c b/commands/legacycfg.c new file mode 100644 index 000000000..de4631140 --- /dev/null +++ b/commands/legacycfg.c @@ -0,0 +1,521 @@ +/* + * 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 +#include +#include + +struct legacy_command +{ + const char *name; + const char *map; + unsigned argc; + enum { + TYPE_VERBATIM, + TYPE_FORCE_OPTION, + TYPE_NOAPM_OPTION, + TYPE_FILE, + TYPE_PARTITION, + TYPE_BOOL, + TYPE_INT + } argt[3]; + enum { + FLAG_IGNORE_REST = 1, + FLAG_ALL_VERBATIM = 2 + } flags; +}; + +struct legacy_command legacy_commands[] = + { + {"blocklist", "blocklist '%s'\n", 1, {TYPE_FILE}, 0}, + {"boot", "boot\n", 0, {}, 0}, + /* bootp unsupported. */ + {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0}, + {"chainloader", "chainloader %s '%s'\n", 2, {TYPE_FORCE_OPTION, TYPE_FILE}, + 0}, + {"cmp", "cmp '%s' '%s'\n", 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST}, + /* FIXME: Implement command. */ + {"color", "legacy_color '%s' '%s'\n", 2, {TYPE_VERBATIM, TYPE_VERBATIM}, + FLAG_IGNORE_REST}, + {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0}, + {"debug", + "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", + 0, {}, 0}, + /* FIXME: Implement command. */ + {"default", "legacy_default %s\n", 1, {TYPE_INT}, 0}, + /* dhcp unsupported. */ + /* displayapm unsupported. */ + {"displaymem", "lsmem\n", 0, {}, 0}, + /* embed unsupported. */ + {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0}, + {"find", "search -f '%s'\n", 1, {TYPE_FILE}, 0}, + /* fstest unsupported. */ + /* geometry unsupported. */ + {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0}, + /* help unsupported. */ /* NUL_TERMINATE */ + /* hiddenmenu unsupported. */ + {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0}, + /* ifconfig unsupported. */ + /* impsprobe unsupported. */ + /* FIXME: Implement command. */ + {"initrd", "legacy_initrd '%s'\n", 1, {TYPE_FILE}, 0}, + /* install unsupported. */ + /* ioprobe unsupported. */ + /* FIXME: implement command. */ + {"kernel", "legacy_kernel %s\n", 0, {}, FLAG_ALL_VERBATIM}, + /* lock is handled separately. */ + {"makeactive", "parttool '%s' boot+\n", 1, {TYPE_PARTITION}, 0}, + {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, + FLAG_IGNORE_REST}, + /* md5crypt unsupported. */ + {"module", "legacy_initrd '%s'\n", 1, {TYPE_FILE}, 0}, + /* modulenounzip unsupported. */ + {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0}, + /* partnew unsupported. */ + {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0}, + /* password unsupported. */ /* NUL_TERMINATE */ + /* pause unsupported. */ + /* rarp unsupported. */ + {"read", "read_dword %s\n", 1, {TYPE_INT}, 0}, + {"reboot", "reboot\n", 0, {}, 0}, + {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0}, + {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0}, + {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0}, + /* serial unsupported. */ + /* setkey unsupported. */ /* NUL_TERMINATE */ + /* setup unsupported. */ + /* terminal unsupported. */ /* NUL_TERMINATE */ + /* terminfo unsupported. */ /* NUL_TERMINATE */ + /* testload unsupported. */ + /* testvbe unsupported. */ + /* tftpserver unsupported. */ + {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0}, + /* title is handled separately. */ + {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0}, + /* uppermem unsupported. */ + /* vbeprobe unsupported. */ + }; + +static char * +escape (const char *in) +{ + const char *ptr; + char *ret, *outptr; + int overhead = 0; + for (ptr = in; *ptr; ptr++) + if (*ptr == '\'' || *ptr == '\\') + overhead++; + ret = grub_malloc (ptr - in + overhead); + if (!ret) + return NULL; + outptr = ret; + for (ptr = in; *ptr; ptr++) + { + if (*ptr == '\'' || *ptr == '\\') + *outptr++ = '\\'; + + *outptr++ = *ptr; + } + return ret; +} + +static char * +adjust_file (const char *in) +{ + const char *comma, *ptr, *rest; + char *ret, *outptr; + int overhead = 0; + int part; + if (in[0] != '(') + return escape (in); + for (ptr = in + 1; *ptr && *ptr != ')' && *ptr != ','; ptr++) + if (*ptr == '\'' || *ptr == '\\') + overhead++; + comma = ptr; + if (*comma != ',') + return escape (in); + part = grub_strtoull (comma + 1, (char **) &rest, 0); + for (ptr = rest; *ptr; ptr++) + if (*ptr == '\'' || *ptr == '\\') + overhead++; + + /* 30 is enough for any number. */ + ret = grub_malloc (ptr - in + overhead + 30); + if (!ret) + return NULL; + + outptr = ret; + for (ptr = in; ptr <= comma; ptr++) + { + if (*ptr == '\'' || *ptr == '\\') + *outptr++ = '\\'; + + *outptr++ = *ptr; + } + grub_snprintf (outptr, 30, "%d", part + 1); + while (*outptr) + outptr++; + for (ptr = rest; ptr <= comma; ptr++) + { + if (*ptr == '\'' || *ptr == '\\') + *outptr++ = '\\'; + + *outptr++ = *ptr; + } + return ret; +} + +static char * +legacy_parse (char *buf, char **entryname) +{ + char *ptr; + char *cmdname; + unsigned i, cmdnum; + + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); + if ((!*ptr || *ptr == '#') && entryname && *entryname) + return buf; + if (!*ptr || *ptr == '#') + { + grub_free (buf); + return NULL; + } + + cmdname = ptr; + for (ptr = buf; !grub_isspace (*ptr) && *ptr != '='; ptr++); + + if (entryname && grub_strncmp ("title", cmdname, ptr - cmdname) == 0 + && ptr - cmdname == sizeof ("title") - 1) + { + for (; grub_isspace (*ptr) || *ptr == '='; ptr++); + *entryname = grub_strdup (ptr); + grub_free (buf); + return NULL; + } + + if (grub_strncmp ("lock", cmdname, ptr - cmdname) == 0 + && ptr - cmdname == sizeof ("lock") - 1) + { + /* FIXME */ + } + + for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) + if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 + && legacy_commands[cmdnum].name[ptr - cmdname] == 0) + break; + if (cmdnum == ARRAY_SIZE (legacy_commands)) + return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); + + for (; grub_isspace (*ptr) || *ptr == '='; ptr++); + + char *args[ARRAY_SIZE (legacy_commands[0].argt)]; + memset (args, 0, sizeof (args)); + + if (legacy_commands[cmdnum].flags & FLAG_ALL_VERBATIM) + { + char *arg0 = ptr, *outptr; + int overhead = 3; + while (*ptr) + { + char *curarg; + for (; grub_isspace (*ptr); ptr++); + curarg = ptr; + for (; *ptr && !grub_isspace (*ptr); ptr++) + if (*ptr == '\\' || *ptr == '\'') + overhead++; + if (ptr) + ptr++; + overhead += 3; + } + args[0] = grub_malloc (overhead + (ptr - arg0)); + if (!args[0]) + { + grub_free (buf); + return NULL; + } + ptr = arg0; + outptr = args[0]; + while (*ptr) + { + char *curarg; + for (; grub_isspace (*ptr); ptr++); + curarg = ptr; + if (outptr != args[0]) + *outptr++ = ' '; + *outptr++ = '\''; + for (; *ptr && !grub_isspace (*ptr); ptr++) + { + if (*ptr == '\\' || *ptr == '\'') + *outptr++ = '\\'; + *outptr++ = *ptr; + } + *outptr++ = '\''; + if (ptr) + ptr++; + overhead += 3; + } + } + + { + unsigned j = 0; + for (i = 0; i < legacy_commands[cmdnum].argc; i++) + { + char *curarg, *cptr = NULL, c; + for (; grub_isspace (*ptr); ptr++); + curarg = ptr; + for (; !grub_isspace (*ptr); ptr++); + if (i != legacy_commands[cmdnum].argc - 1 + || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) + { + cptr = ptr; + c = *cptr; + *ptr = 0; + } + ptr++; + switch (legacy_commands[cmdnum].argt[i]) + { + case TYPE_PARTITION: + case TYPE_FILE: + args[j++] = adjust_file (curarg); + break; + + case TYPE_VERBATIM: + args[j++] = escape (curarg); + break; + case TYPE_FORCE_OPTION: + if (grub_strcmp (curarg, "--force") == 0) + { + args[j++] = grub_strdup ("--force"); + break; + } + if (cptr) + *cptr = c; + ptr = curarg; + break; + case TYPE_NOAPM_OPTION: + if (grub_strcmp (curarg, "--no-apm") == 0) + { + args[j++] = grub_strdup ("--no-apm"); + break; + } + if (cptr) + *cptr = c; + ptr = curarg; + break; + case TYPE_INT: + { + char *brk; + int base = 10; + brk = curarg; + if (brk[0] == '0' && brk[1] == 'x') + base = 16; + else if (brk[0] == '0') + base = 8; + for (; *brk; brk++) + { + if (base == 8 && (*brk == '8' || *brk == '9')) + break; + if (grub_isdigit (*brk)) + continue; + if (base != 16) + break; + if (!(*brk >= 'a' && *brk <= 'f') + && !(*brk >= 'A' && *brk <= 'F')) + break; + } + if (brk == curarg) + args[j++] = grub_strdup ("0"); + else + args[j++] = grub_strndup (curarg, brk - curarg); + } + break; + case TYPE_BOOL: + if (curarg[0] == 'o' && curarg[1] == 'n' + && (curarg[2] == 0 || grub_isspace (curarg[2]))) + args[j++] = grub_strdup ("1"); + else + args[j++] = grub_strdup ("0"); + break; + } + } + } + grub_free (buf); + return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2]); +} + +static grub_err_t +legacy_file (const char *filename) +{ + grub_file_t file; + char *entryname = NULL, *entrysrc = NULL; + grub_menu_t menu; + + file = grub_gzfile_open (filename, 1); + if (! file) + return grub_errno; + + menu = grub_env_get_menu (); + if (! menu) + { + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + return grub_errno; + + grub_env_set_menu (menu); + } + + while (1) + { + char *buf = grub_file_getline (file); + char *parsed; + + if (!buf && grub_errno) + { + grub_file_close (file); + return grub_errno; + } + + if (!buf) + break; + + { + char *oldname = NULL; + + oldname = entryname; + parsed = legacy_parse (buf, &entryname); + if (oldname != entryname && oldname) + { + const char **args = grub_malloc (sizeof (args[0])); + if (!args) + { + grub_file_close (file); + return grub_errno; + } + args[0] = oldname; + grub_normal_add_menu_entry (1, args, entrysrc); + } + } + + if (parsed && !entryname) + { + auto grub_err_t getline (char **line, int cont); + grub_err_t getline (char **line __attribute__ ((unused)), + int cont __attribute__ ((unused))) + { + return GRUB_ERR_NONE; + } + + grub_normal_parse_line (parsed, getline); + grub_free (parsed); + } + else if (parsed) + { + if (!entrysrc) + entrysrc = parsed; + else + { + char *t; + + t = entrysrc; + entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) + + grub_strlen (parsed) + 1); + if (!entrysrc) + { + grub_free (t); + grub_free (parsed); + return grub_errno; + } + grub_memcpy (entrysrc + grub_strlen (entrysrc), buf, + grub_strlen (parsed) + 1); + grub_free (parsed); + parsed = NULL; + } + } + } + grub_file_close (file); + + if (entryname) + { + const char **args = grub_malloc (sizeof (args[0])); + if (!args) + { + grub_file_close (file); + return grub_errno; + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, entrysrc); + } + + if (menu && menu->size) + grub_show_menu (menu, 1); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_legacy_source (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + return legacy_file (args[0]); +} + +static grub_err_t +grub_cmd_legacy_configfile (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_err_t ret; + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_cls (); + grub_env_context_open (1); + + ret = legacy_file (args[0]); + grub_env_context_close (); + + return ret; +} + +static grub_command_t cmd_source, cmd_configfile; + +GRUB_MOD_INIT(legacycfg) +{ + cmd_source = grub_register_command ("legacy_source", + grub_cmd_legacy_source, + N_("FILE"), N_("Parse legacy config")); + cmd_configfile = grub_register_command ("legacy_configfile", + grub_cmd_legacy_configfile, + N_("FILE"), + N_("Parse legacy config")); +} + +GRUB_MOD_FINI(legacycfg) +{ + grub_unregister_command (cmd_source); + grub_unregister_command (cmd_configfile); +} diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 5ff852f2e..791d64349 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -255,6 +255,12 @@ hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c hdparm_mod_CFLAGS = $(COMMON_CFLAGS) hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) +# grub legacy ever supported only i386-pc. +pkglib_MODULES += legacycfg.mod +legacycfg_mod_SOURCES = commands/legacycfg.c +legacycfg_mod_CFLAGS = $(COMMON_CFLAGS) +legacycfg_mod_LDFLAGS = $(COMMON_LDFLAGS) + ifeq ($(enable_efiemu), yes) efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) From 68cc4355f8b31612a4edd7a6d6bb844857e1cfb0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 May 2010 17:51:22 +0200 Subject: [PATCH 0023/1414] Fix few bugs and put a cleaner way to handle kernel command --- commands/legacycfg.c | 151 +++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 64 deletions(-) diff --git a/commands/legacycfg.c b/commands/legacycfg.c index de4631140..6069fe746 100644 --- a/commands/legacycfg.c +++ b/commands/legacycfg.c @@ -27,24 +27,26 @@ #include #include #include +#include struct legacy_command { const char *name; const char *map; unsigned argc; - enum { + enum arg_type { TYPE_VERBATIM, TYPE_FORCE_OPTION, TYPE_NOAPM_OPTION, + TYPE_TYPE_OPTION, TYPE_FILE, TYPE_PARTITION, TYPE_BOOL, - TYPE_INT + TYPE_INT, + TYPE_REST_VERBATIM } argt[3]; enum { - FLAG_IGNORE_REST = 1, - FLAG_ALL_VERBATIM = 2 + FLAG_IGNORE_REST = 1 } flags; }; @@ -85,7 +87,8 @@ struct legacy_command legacy_commands[] = /* install unsupported. */ /* ioprobe unsupported. */ /* FIXME: implement command. */ - {"kernel", "legacy_kernel %s\n", 0, {}, FLAG_ALL_VERBATIM}, + {"kernel", "legacy_kernel %s '%s' %s\n", 3, {TYPE_TYPE_OPTION, TYPE_FILE, + TYPE_REST_VERBATIM}, 0}, /* lock is handled separately. */ {"makeactive", "parttool '%s' boot+\n", 1, {TYPE_PARTITION}, 0}, {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, @@ -116,6 +119,7 @@ struct legacy_command legacy_commands[] = /* title is handled separately. */ {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0}, /* uppermem unsupported. */ + {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0}, /* vbeprobe unsupported. */ }; @@ -139,6 +143,7 @@ escape (const char *in) *outptr++ = *ptr; } + *outptr++ = 0; return ret; } @@ -188,6 +193,27 @@ adjust_file (const char *in) return ret; } +static int +is_option (enum arg_type opt, const char *curarg) +{ + switch (opt) + { + case TYPE_NOAPM_OPTION: + return grub_strcmp (curarg, "--no-apm") == 0; + case TYPE_FORCE_OPTION: + return grub_strcmp (curarg, "--force") == 0; + case TYPE_TYPE_OPTION: + return grub_strcmp (curarg, "--type=netbsd") == 0 + || grub_strcmp (curarg, "--type=freebsd") == 0 + || grub_strcmp (curarg, "--type=openbsd") == 0 + || grub_strcmp (curarg, "--type=linux") == 0 + || grub_strcmp (curarg, "--type=biglinux") == 0 + || grub_strcmp (curarg, "--type=multiboot") == 0; + default: + return 0; + } +} + static char * legacy_parse (char *buf, char **entryname) { @@ -197,7 +223,11 @@ legacy_parse (char *buf, char **entryname) for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); if ((!*ptr || *ptr == '#') && entryname && *entryname) - return buf; + { + char *ret = grub_xasprintf ("%s\n", buf); + grub_free (buf); + return ret; + } if (!*ptr || *ptr == '#') { grub_free (buf); @@ -234,51 +264,6 @@ legacy_parse (char *buf, char **entryname) char *args[ARRAY_SIZE (legacy_commands[0].argt)]; memset (args, 0, sizeof (args)); - if (legacy_commands[cmdnum].flags & FLAG_ALL_VERBATIM) - { - char *arg0 = ptr, *outptr; - int overhead = 3; - while (*ptr) - { - char *curarg; - for (; grub_isspace (*ptr); ptr++); - curarg = ptr; - for (; *ptr && !grub_isspace (*ptr); ptr++) - if (*ptr == '\\' || *ptr == '\'') - overhead++; - if (ptr) - ptr++; - overhead += 3; - } - args[0] = grub_malloc (overhead + (ptr - arg0)); - if (!args[0]) - { - grub_free (buf); - return NULL; - } - ptr = arg0; - outptr = args[0]; - while (*ptr) - { - char *curarg; - for (; grub_isspace (*ptr); ptr++); - curarg = ptr; - if (outptr != args[0]) - *outptr++ = ' '; - *outptr++ = '\''; - for (; *ptr && !grub_isspace (*ptr); ptr++) - { - if (*ptr == '\\' || *ptr == '\'') - *outptr++ = '\\'; - *outptr++ = *ptr; - } - *outptr++ = '\''; - if (ptr) - ptr++; - overhead += 3; - } - } - { unsigned j = 0; for (i = 0; i < legacy_commands[cmdnum].argc; i++) @@ -294,7 +279,8 @@ legacy_parse (char *buf, char **entryname) c = *cptr; *ptr = 0; } - ptr++; + if (*ptr) + ptr++; switch (legacy_commands[cmdnum].argt[i]) { case TYPE_PARTITION: @@ -302,28 +288,65 @@ legacy_parse (char *buf, char **entryname) args[j++] = adjust_file (curarg); break; + case TYPE_REST_VERBATIM: + { + char *outptr, *outptr0; + int overhead = 3; + ptr = curarg; + while (*ptr) + { + for (; grub_isspace (*ptr); ptr++); + for (; *ptr && !grub_isspace (*ptr); ptr++) + if (*ptr == '\\' || *ptr == '\'') + overhead++; + if (*ptr) + ptr++; + overhead += 3; + } + outptr0 = args[j++] = grub_malloc (overhead + (ptr - curarg)); + if (!outptr0) + { + grub_free (buf); + return NULL; + } + ptr = curarg; + outptr = outptr0; + while (*ptr) + { + for (; grub_isspace (*ptr); ptr++); + if (outptr != outptr0) + *outptr++ = ' '; + *outptr++ = '\''; + for (; *ptr && !grub_isspace (*ptr); ptr++) + { + if (*ptr == '\\' || *ptr == '\'') + *outptr++ = '\\'; + *outptr++ = *ptr; + } + *outptr++ = '\''; + if (*ptr) + ptr++; + overhead += 3; + } + *outptr++ = 0; + } + break; + case TYPE_VERBATIM: args[j++] = escape (curarg); break; case TYPE_FORCE_OPTION: - if (grub_strcmp (curarg, "--force") == 0) - { - args[j++] = grub_strdup ("--force"); - break; - } - if (cptr) - *cptr = c; - ptr = curarg; - break; case TYPE_NOAPM_OPTION: - if (grub_strcmp (curarg, "--no-apm") == 0) + case TYPE_TYPE_OPTION: + if (is_option (legacy_commands[cmdnum].argt[i], curarg)) { - args[j++] = grub_strdup ("--no-apm"); + args[j++] = grub_strdup (curarg); break; } if (cptr) *cptr = c; ptr = curarg; + args[j++] = ""; break; case TYPE_INT: { @@ -448,7 +471,7 @@ legacy_file (const char *filename) grub_free (parsed); return grub_errno; } - grub_memcpy (entrysrc + grub_strlen (entrysrc), buf, + grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, grub_strlen (parsed) + 1); grub_free (parsed); parsed = NULL; From b07e88dc6add00f8860d2ab7b47dbf4d2982b38d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 May 2010 17:55:37 +0200 Subject: [PATCH 0024/1414] default support --- commands/legacycfg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/commands/legacycfg.c b/commands/legacycfg.c index 6069fe746..46637c301 100644 --- a/commands/legacycfg.c +++ b/commands/legacycfg.c @@ -66,8 +66,7 @@ struct legacy_command legacy_commands[] = {"debug", "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", 0, {}, 0}, - /* FIXME: Implement command. */ - {"default", "legacy_default %s\n", 1, {TYPE_INT}, 0}, + {"default", "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; set default=\"$saved_entry\"\n", 1, {TYPE_VERBATIM}, 0}, /* dhcp unsupported. */ /* displayapm unsupported. */ {"displaymem", "lsmem\n", 0, {}, 0}, From 67cb07a31bfc7269af7c3f411f636d8d275e72eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 May 2010 18:13:43 +0200 Subject: [PATCH 0025/1414] fix more bugs --- commands/legacycfg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/commands/legacycfg.c b/commands/legacycfg.c index 46637c301..aaaac8112 100644 --- a/commands/legacycfg.c +++ b/commands/legacycfg.c @@ -66,10 +66,10 @@ struct legacy_command legacy_commands[] = {"debug", "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", 0, {}, 0}, - {"default", "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; set default=\"$saved_entry\"\n", 1, {TYPE_VERBATIM}, 0}, + {"default", "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; set default=\"$saved_entry\"; fi\n", 1, {TYPE_VERBATIM}, 0}, /* dhcp unsupported. */ /* displayapm unsupported. */ - {"displaymem", "lsmem\n", 0, {}, 0}, + {"displaymem", "lsmmap\n", 0, {}, 0}, /* embed unsupported. */ {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0}, {"find", "search -f '%s'\n", 1, {TYPE_FILE}, 0}, @@ -234,7 +234,7 @@ legacy_parse (char *buf, char **entryname) } cmdname = ptr; - for (ptr = buf; !grub_isspace (*ptr) && *ptr != '='; ptr++); + for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); if (entryname && grub_strncmp ("title", cmdname, ptr - cmdname) == 0 && ptr - cmdname == sizeof ("title") - 1) @@ -267,7 +267,7 @@ legacy_parse (char *buf, char **entryname) unsigned j = 0; for (i = 0; i < legacy_commands[cmdnum].argc; i++) { - char *curarg, *cptr = NULL, c; + char *curarg, *cptr = NULL, c = 0; for (; grub_isspace (*ptr); ptr++); curarg = ptr; for (; !grub_isspace (*ptr); ptr++); @@ -451,6 +451,7 @@ legacy_file (const char *filename) } grub_normal_parse_line (parsed, getline); + grub_print_error (); grub_free (parsed); } else if (parsed) From a408e05187d5411e623c602e936df054c1934663 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 May 2010 18:24:02 +0200 Subject: [PATCH 0026/1414] Add serial command --- commands/legacycfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/legacycfg.c b/commands/legacycfg.c index aaaac8112..8f02a028f 100644 --- a/commands/legacycfg.c +++ b/commands/legacycfg.c @@ -106,7 +106,7 @@ struct legacy_command legacy_commands[] = {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0}, {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0}, {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0}, - /* serial unsupported. */ + {"serial", "serial %s\n", 1, {TYPE_REST_VERBATIM}, 0}, /* setkey unsupported. */ /* NUL_TERMINATE */ /* setup unsupported. */ /* terminal unsupported. */ /* NUL_TERMINATE */ From 8f937bfe07fd622bb982ca218e5e8e67345d7dba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 May 2010 21:02:41 +0200 Subject: [PATCH 0027/1414] Fix makeactive syntax --- commands/legacycfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/legacycfg.c b/commands/legacycfg.c index 8f02a028f..8077497f3 100644 --- a/commands/legacycfg.c +++ b/commands/legacycfg.c @@ -89,7 +89,7 @@ struct legacy_command legacy_commands[] = {"kernel", "legacy_kernel %s '%s' %s\n", 3, {TYPE_TYPE_OPTION, TYPE_FILE, TYPE_REST_VERBATIM}, 0}, /* lock is handled separately. */ - {"makeactive", "parttool '%s' boot+\n", 1, {TYPE_PARTITION}, 0}, + {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0}, {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, FLAG_IGNORE_REST}, /* md5crypt unsupported. */ From d17a9fea4ac98b3aebea13f2b280c98afcd19c03 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:05:14 -0300 Subject: [PATCH 0028/1414] Add interface struct for communication between protocols and protocols stack. Changed the protocols structs to use one struct for each layer. --- include/grub/net/arp.h | 8 +- include/grub/net/ieee1275/interface.h | 14 ++-- include/grub/net/interface.h | 77 ++++++++++++++---- include/grub/net/netbuff.h | 3 + include/grub/net/protocol.h | 110 ++++++++++++++++++++------ include/grub/net/tftp.h | 6 +- include/grub/net/type_net.h | 25 ++++++ include/grub/net/udp.h | 19 ++--- 8 files changed, 194 insertions(+), 68 deletions(-) diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 0ac2ec832..86ae2deea 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -2,7 +2,7 @@ #define GRUB_NET_ARP_HEADER 1 #include -struct arprequest { +struct arphdr{ grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ grub_int8_t hwlen; /* hardware address length (must be 6) */ @@ -14,10 +14,4 @@ struct arprequest { grub_uint32_t tipaddr; /* target's IP address */ }__attribute__ ((packed)); - -struct arp_pkt{ - struct etherhdr ether; - struct arprequest arpr; -} __attribute__ ((packed)); - #endif diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h index edc242cab..16f624c05 100644 --- a/include/grub/net/ieee1275/interface.h +++ b/include/grub/net/ieee1275/interface.h @@ -4,17 +4,15 @@ #include #include #include +#include -grub_ofnet_t EXPORT_VAR(grub_net); -grub_bootp_t EXPORT_VAR(bootp_pckt); -grub_uint32_t get_server_ip(void); -grub_uint32_t get_client_ip(void); -grub_uint8_t* get_server_mac (void); -grub_uint8_t* get_client_mac (void); +grub_ofnet_t grub_net; -int send_card_buffer (void *buffer,int buff_len); -int get_card_buffer (void *buffer,int buff_len); +grub_bootp_t bootp_pckt; + +int send_card_buffer (struct grub_net_buff *pack); +int get_card_packet (struct grub_net_buff *pack); int card_open (void); int card_close (void); diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h index 2e0ddfcc8..4d100fd75 100644 --- a/include/grub/net/interface.h +++ b/include/grub/net/interface.h @@ -1,27 +1,70 @@ #ifndef GRUB_INTERFACE_HEADER #define GRUB_INTERFACE_HEADER -#include -#include +//#include +#include +#include +#include -struct grub_net_protstack +struct grub_net_protocol_stack { - struct grub_net_protstack *next; - struct grub_net_protocol* prot; + struct grub_net_protocol_stack *next; + char *name; + grub_net_protocol_id_t id; + void *interface; }; -struct grub_net_interface +struct grub_net_application_transport_interface { - struct grub_net_card *card; - struct grub_net_protstack* protstack; - char *path; - char *username; - char *password; - /*transport layer addres*/ - struct grub_net_addr *tla; - /*internet layer addres*/ - struct grub_net_addr *ila; - /*link layer addres*/ - struct grub_net_addr *lla; + struct grub_net_transport_network_interface *inner_layer; + void *data; + struct grub_net_application_layer_protocol *app_prot; + struct grub_net_transport_layer_protocol *trans_prot; }; +struct grub_net_transport_network_interface +{ + struct grub_net_network_link_interface *inner_layer; + void *data; + struct grub_net_transport_layer_protocol *trans_prot; + struct grub_net_network_layer_protocol *net_prot; +}; + +struct grub_net_network_link_interface +{ + void *data; + struct grub_net_network_layer_protocol *net_prot; + struct grub_net_link_layer_protocol *link_prot; +}; + + +extern struct grub_net_protocol_stack *grub_net_protocol_stacks; +static inline void +grub_net_stack_register (struct grub_net_protocol_stack *stack) +{ + + grub_list_push (GRUB_AS_LIST_P (&grub_net_protocol_stacks), + GRUB_AS_LIST (stack)); +} +/* +void grub_net_stack_unregister (struct grub_net_protocol_stack *stack) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_protocol_stacks), + GRUB_AS_LIST (stack)); +}*/ + +struct grub_net_protocol_stack *grub_net_protocol_stack_get (char *name); + +/* +static inline void +grub_net_interface_application_transport_register (struct grub_net_application_transport_interface); +static inline void +grub_net_interface_application_transport_unregister (struct grub_net_application_transport_interface); +static inline void +grub_net_interface_transport_network_register (struct grub_net_transport_network_interface); +static inline void +grub_net_interface_transport_network_unregister (struct grub_net_transport_network_interface); +static inline void +grub_net_interface_network_link_register (struct grub_net_network_link_interface); +static inline void +grub_net_interface_network_link_unregister (struct grub_net_network_link_interface);*/ #endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h index 7d63be1f5..8ce508ead 100644 --- a/include/grub/net/netbuff.h +++ b/include/grub/net/netbuff.h @@ -23,5 +23,8 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len); grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len); grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len); grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len); +grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ); +grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff); +grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); #endif diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index 1efc2ab7b..b7a3e5d3b 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -1,35 +1,101 @@ #ifndef GRUB_PROTOCOL_HEADER #define GRUB_PROTOCOL_HEADER #include -#include +#include #include -#include +#include struct grub_net_protocol; -struct grub_net_interface; -struct grub_net_protstack; +struct grub_net_protocol_stack; +struct grub_net_network_layer_interface; -struct grub_net_protocol + +typedef enum grub_network_layer_protocol_id { - struct grub_net_protocol *next; + GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 +} grub_network_layer_protocol_id_t; + +struct grub_net_application_layer_protocol +{ + struct grub_net_application_layer_protocol *next; char *name; - grub_err_t (*open) (struct grub_net_interface* inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*open_confirm) (struct grub_net_interface *inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*get_payload) (struct grub_net_interface *inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*close) (struct grub_net_interface *inf, - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*send) (struct grub_net_interface *inf , - struct grub_net_protstack *protstack, struct grub_net_buff *nb); - grub_err_t (*recv) (struct grub_net_interface *inf , - struct grub_net_protstack *protstack, struct grub_net_buff *nb); + grub_net_protocol_id_t id; + int (*get_file_size) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb,char *filename); + grub_err_t (*open) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb,char *filename); + grub_err_t (*send_ack) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*send) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); }; +struct grub_net_transport_layer_protocol +{ + struct grub_net_transport_layer_protocol *next; + char *name; + grub_net_protocol_id_t id; + //grub_transport_layer_protocol_id_t id; + grub_err_t (*open) (struct grub_net_network_layer_interface* inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb); + grub_err_t (*send_ack) (struct grub_net_network_layer_interface* inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); + grub_err_t (*send) (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_net_network_layer_interface *inf, + struct grub_net_protocol_stack *protocol_stack, struct grub_net_buff *nb); +}; + +struct grub_net_network_layer_protocol +{ + struct grub_net_network_layer_protocol *next; + char *name; + grub_net_protocol_id_t id; + //grub_network_layer_protocol_id_t id; + grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr); + char * (*aton) (union grub_net_network_layer_address addr); + grub_err_t (*net_ntoa) (char *name, + grub_net_network_layer_netaddress_t *addr); + char * (*net_aton) (grub_net_network_layer_netaddress_t addr); + int (* match_net) (grub_net_network_layer_netaddress_t net, + grub_net_network_layer_address_t addr); + grub_err_t (*send) (struct grub_net_network_layer_interface *inf , + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf , + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb); +}; + +struct grub_net_link_layer_protocol +{ + + struct grub_net_link_layer_protocol *next; + char *name; + grub_net_protocol_id_t id; + grub_err_t (*send) (struct grub_net_network_layer_interface *inf , + struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); + grub_err_t (*recv) (struct grub_net_network_layer_interface *inf , + struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); +}; + +extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols; + typedef struct grub_net_protocol *grub_net_protocol_t; -void grub_protocol_register (grub_net_protocol_t prot); -void grub_protocol_unregister (grub_net_protocol_t prot); +void grub_net_application_layer_protocol_register (struct grub_net_application_layer_protocol *prot); +void grub_net_application_layer_protocol_unregister (struct grub_net_application_layer_protocol *prot); +struct grub_net_application_layer_protocol *grub_net_application_layer_protocol_get (grub_net_protocol_id_t id); +void grub_net_transport_layer_protocol_register (struct grub_net_transport_layer_protocol *prot); +void grub_net_transport_layer_protocol_unregister (struct grub_net_transport_layer_protocol *prot); +struct grub_net_transport_layer_protocol *grub_net_transport_layer_protocol_get (grub_net_protocol_id_t id); +void grub_net_network_layer_protocol_register (struct grub_net_network_layer_protocol *prot); +void grub_net_network_layer_protocol_unregister (struct grub_net_network_layer_protocol *prot); +struct grub_net_network_layer_protocol *grub_net_network_layer_protocol_get (grub_net_protocol_id_t id); +void grub_net_link_layer_protocol_register (struct grub_net_link_layer_protocol *prot); +void grub_net_link_layer_protocol_unregister (struct grub_net_link_layer_protocol *prot); +struct grub_net_link_layer_protocol *grub_net_link_layer_protocol_get (grub_net_protocol_id_t id); #endif diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h index 4148096c5..1f1c48616 100644 --- a/include/grub/net/tftp.h +++ b/include/grub/net/tftp.h @@ -14,7 +14,7 @@ /* IP port for the TFTP server */ #define TFTP_SERVER_PORT 69 -#define TFTP_CLIENT_PORT 2000 +#define TFTP_CLIENT_PORT 26300 /* We define these based on what's in arpa/tftp.h. We just like our @@ -42,10 +42,6 @@ #define TFTP_ENOUSER 7 /* no such user */ #define TFTP_DEFAULT_FILENAME "kernel" - - - - /* * own here because this is cleaner, and maps to the same data layout. * */ struct tftphdr { diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h index 33f2d802d..276c50bf9 100644 --- a/include/grub/net/type_net.h +++ b/include/grub/net/type_net.h @@ -1,7 +1,32 @@ #ifndef GRUB_TYPES_NET_HEADER #define GRUB_TYPES_NET_HEADER 1 +#include + #define UDP_PCKT 0x11 #define IP_PCKT 0x0800 +typedef enum +{ + GRUB_NET_TFTP_ID, + GRUB_NET_UDP_ID, + GRUB_NET_IPV4_ID, + GRUB_NET_IPV6_ID, + GRUB_NET_ETHERNET_ID, + GRUB_NET_ARP_ID, + GRUB_NET_DHCP_ID +}grub_net_protocol_id_t; + +typedef union grub_net_network_layer_address +{ + grub_uint32_t ipv4; +} grub_net_network_layer_netaddress_t; + +typedef union grub_net_network_layer_netaddress +{ + struct { + grub_uint32_t base; + int masksize; + } ipv4; +} grub_net_network_layer_address_t; #endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index dbfcecef0..dfc1776a4 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -1,22 +1,23 @@ #ifndef GRUB_NET_UDP_HEADER #define GRUB_NET_UDP_HEADER 1 #include -/* -typedef enum - { - GRUB_PROT_TFTP - } protocol_type; -*/ -#define GRUB_PROT_TFTP 1 - -struct udphdr { +struct udphdr +{ grub_uint16_t src; grub_uint16_t dst; grub_uint16_t len; grub_uint16_t chksum; } __attribute__ ((packed)); +struct udp_interf +{ + grub_uint16_t src; + grub_uint16_t dst; +}; + + + void udp_ini(void); void udp_fini(void); #endif From c3639ae731b7043f641090b38995a73aceda70c9 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:13:26 -0300 Subject: [PATCH 0029/1414] File manipulation. Based in OF implementation. For debug porpouse and will be changed later. --- fs/ieee1275/ofnet.c | 355 ++++++++++++++++++++++++++++++++++ include/grub/ieee1275/ofnet.h | 95 +++++++++ 2 files changed, 450 insertions(+) create mode 100644 fs/ieee1275/ofnet.c create mode 100644 include/grub/ieee1275/ofnet.h diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c new file mode 100644 index 000000000..196aadcf2 --- /dev/null +++ b/fs/ieee1275/ofnet.c @@ -0,0 +1,355 @@ +/* ofnet.c - Driver to provide access to the ofnet filesystem */ +/* + * 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 +#include +#include + +#define BUFFERADDR 0X00000000 +#define BUFFERSIZE 0x02000000 +#define U64MAXSIZE 18446744073709551615ULL + + +//static grub_ieee1275_ihandle_t handle = 0; + + +static int +grub_ofnet_iterate (int (*hook) (const char *name)) +{ + if (hook ("net")) + return 1; + return 0; +} + +static grub_err_t +grub_ofnet_open (const char *name, grub_disk_t disk) +{ + + + if (grub_strcmp (name, "network")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); + + disk->total_sectors = U64MAXSIZE; + disk->id = (unsigned long) "net"; + + disk->has_partitions = 0; + disk->data = 0; + + return GRUB_ERR_NONE; +} + +static void +grub_ofnet_close (grub_disk_t disk __attribute((unused))) +{ +} + +static grub_err_t +grub_ofnet_read (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + char *buf __attribute((unused))) +{ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ofnet_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_NONE; +} + +static struct grub_disk_dev grub_ofnet_dev = + { + .name = "net", + .id = GRUB_DISK_DEVICE_OFNET_ID, + .iterate = grub_ofnet_iterate, + .open = grub_ofnet_open, + .close = grub_ofnet_close, + .read = grub_ofnet_read, + .write = grub_ofnet_write, + .next = 0 + }; + +static grub_err_t +grub_ofnetfs_dir (grub_device_t device , + const char *path __attribute((unused)), + int (*hook) (const char *filename, + const struct grub_dirhook_info *info) __attribute((unused))) +{ + if(grub_strcmp (device->disk->name,"network")) + { + return grub_error (GRUB_ERR_BAD_FS, "not an net filesystem"); + } + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_ofnetfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_size_t actual; + actual = len <= (file->size - file->offset)?len:file->size - file->offset; + grub_memcpy(buf, (void *)( (grub_addr_t) file->data + (grub_addr_t)file->offset), actual); + return actual; +} + +static grub_err_t +grub_ofnetfs_close (grub_file_t file) +{ + grub_ieee1275_release ((grub_addr_t) file->data,file->size); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ofnetfs_open (struct grub_file *file , const char *name ) +{ + //void *buffer; + //grub_addr_t addr; + if (name[0] == '/') + name++; + if(grub_strcmp (file->device->disk->name,"network")) + { + + return 1; + } + grub_printf("name = %s\n",name); + + struct grub_net_protocol_stack *stack; + struct grub_net_buff *pack; + struct grub_net_application_transport_interface *app_interface; + int file_size; + char *datap; + int amount = 0; + grub_addr_t found_addr; + + stack = grub_net_protocol_stack_get ("tftp"); + app_interface = (struct grub_net_application_transport_interface *) stack->interface; + pack = grub_netbuff_alloc (80*1024); + grub_netbuff_reserve (pack,80*1024); + file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); + + + for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) + { + grub_printf("traing to claim %d bytes at 0x%x\n",file_size,found_addr); + if (grub_claimmap (found_addr , file_size) != -1) + break; + } + grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); + file->data = (void *) found_addr; + grub_printf("file->data = 0x%x\n",(int)file->data); + grub_printf("file_size = %d\n",file_size); + grub_printf("OPEN\n"); + grub_netbuff_clear(pack); + grub_netbuff_reserve (pack,80*1024); + app_interface->app_prot->open (NULL,stack,pack,(char *) name); + + do { + //if (app_interface->app_prot->recv (NULL,stack,pack) == GRUB_ERR_NONE) + grub_printf("RECEIVE PACKET\n"); + grub_netbuff_clear(pack); + grub_netbuff_reserve (pack,80*1024); + app_interface->app_prot->recv (NULL,stack,pack); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + grub_printf("RECEIVED PACKET\n"); + // { + grub_printf("payload_size= %d\n",pack->tail - pack->data); + grub_printf("amount= %d\n",amount); + grub_printf("file_size= %d\n",file_size); + datap = (char *)file->data + amount; + amount += (pack->tail - pack->data); + grub_printf("datap = 0x%x\n",(int)datap ); + // amount += pack->tail - pack->data; + grub_memcpy(datap, pack->data, pack->tail - pack->data); + grub_printf("SEND ACK\n"); + + grub_netbuff_clear(pack); + grub_netbuff_reserve (pack,80*1024); + app_interface->app_prot->send_ack (NULL,stack,pack); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + grub_printf("SENT ACK\n"); + //} + // file->data = grub_realloc(file->data,amount); + + }while (amount < file_size); + grub_printf("transfer complete\n"); + file->size = file_size; + +// grub_netbuff_free(pack); + /*Start ARP header*/ + // arp.arpr.hwtype = 0x1; /* hardware type (must be ARPHRD_ETHER) */ + // arp.arpr.protocol = 0x0800; /* protocol type (must be ETH_P_IP) */ + // arp.arpr.hwlen = 0x6; /* hardware address length (must be 6) */ + // arp.arpr.protolen = 0x4; /* protocol address length (must be 4) */ + // arp.arpr.opcode = 0x1; /* ARP opcode */ + + + /*arp.arpr.shwaddr[0] =0x0a ; + arp.arpr.shwaddr[1] =0x11 ; + arp.arpr.shwaddr[2] =0xbd ; + arp.arpr.shwaddr[3] =0xe3 ; + arp.arpr.shwaddr[4] =0xe3 ; + arp.arpr.shwaddr[5] =0x04 ; + arp.arpr.sipaddr = dhcp_pckt -> yiaddr; */ /* sender's IP address */ + /*arp.arpr.thwaddr[0] =0; + arp.arpr.thwaddr[1] =0; + arp.arpr.thwaddr[2] =0; + arp.arpr.thwaddr[3] =0; + arp.arpr.thwaddr[4] =0; + arp.arpr.thwaddr[5] =0; + arp.arpr.tipaddr = dhcp_pckt -> siaddr; */ /* target's IP address */ + /*END ARP header */ + return grub_errno; +} + + +static grub_err_t +grub_ofnetfs_label (grub_device_t device __attribute ((unused)), + char **label __attribute ((unused))) +{ + *label = 0; + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_ofnetfs_fs = + { + .name = "ofnetfs", + .dir = grub_ofnetfs_dir, + .open = grub_ofnetfs_open, + .read = grub_ofnetfs_read, + .close = grub_ofnetfs_close, + .label = grub_ofnetfs_label, + .next = 0 + }; + +static char * +grub_ieee1275_get_devargs (const char *path) +{ + int len; + char *colon = grub_strchr (path, ':'); + len = colon - path; + if (! colon) + return 0; + + return grub_strndup (path,len); +} + +static int +grub_ofnet_detect (void) +{ + + char *devalias; + char bootpath[64]; /* XXX check length */ + grub_ieee1275_phandle_t root; + grub_uint32_t net_type; + + grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, + sizeof (bootpath), 0)) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); + return 0; + } + devalias = grub_ieee1275_get_aliasdevname (bootpath); + + if (grub_strcmp(devalias ,"network")) + return 0; + + grub_net = grub_malloc (sizeof *grub_net ); + grub_net->name = "net"; + grub_net->dev = grub_ieee1275_get_devargs (bootpath); + grub_ieee1275_finddevice ("/", &root); + grub_ieee1275_get_integer_property (root, "ibm,fw-net-compatibility", + &net_type, sizeof net_type, 0); + grub_printf("root = %d\n",root); + grub_printf("net_type= %d\n",net_type); + grub_net->type = net_type; + + return 1; +} + + +#define IPMASK 0x000000FF +#define IPSIZE 16 +#define IPTEMPLATE "%d.%d.%d.%d" +char * +grub_ip2str (grub_uint32_t ip) +{ + char* str_ip; +// str_ip = grub_malloc(IPSIZE); + str_ip = grub_xasprintf (IPTEMPLATE, ip >> 24 & IPMASK, ip >> 16 & IPMASK, ip >> 8 & IPMASK, ip & IPMASK); + grub_printf ("str_ip = %s\n",str_ip); + grub_printf ("template = "IPTEMPLATE"\n" , ip >> 24 & IPMASK, ip >> 16 & IPMASK, ip >> 8 & IPMASK, ip & IPMASK); + return str_ip; +} + +void +grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet) +{ + netinfo->sip = grub_ip2str(packet->siaddr); + netinfo->cip = grub_ip2str(packet->yiaddr); + netinfo->gat = grub_ip2str(packet->giaddr); + grub_printf("packet->siaddr = %x\n",packet->siaddr); + grub_printf("netinfo-> = %s\n",netinfo->sip); + grub_printf("packet->yiaddr = %x\n",packet->yiaddr); + grub_printf("netinfo-> = %s\n",netinfo->cip); + grub_printf("packet->giaddr = %x\n",packet->giaddr); + grub_printf("netinfo-> = %s\n",netinfo->gat); +} +void +grub_ofnet_init(void) +{ + tftp_ini (); + bootp_pckt = grub_getbootp (); + if(grub_ofnet_detect ()) + { + grub_get_netinfo (grub_net, bootp_pckt ); + grub_disk_dev_register (&grub_ofnet_dev); + grub_fs_register (&grub_ofnetfs_fs); + } + card_open (); +} +void +grub_ofnet_fini(void) +{ + grub_fs_unregister (&grub_ofnetfs_fs); + grub_disk_dev_unregister (&grub_ofnet_dev); +} diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h new file mode 100644 index 000000000..7daadf61d --- /dev/null +++ b/include/grub/ieee1275/ofnet.h @@ -0,0 +1,95 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,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_OFNET_HEADER +#define GRUB_OFNET_HEADER 1 + +#include +#include +#include + +extern void grub_ofnet_init(void); +extern void grub_ofnet_fini(void); +/* +struct grub_net; + +struct grub_net_dev +{ + / The device name. / + const char *name; + + / FIXME: Just a template. / + int (*probe) (struct grub_net *net, const void *addr); + void (*reset) (struct grub_net *net); + int (*poll) (struct grub_net *net); + void (*transmit) (struct grub_net *net, const void *destip, + unsigned srcsock, unsigned destsock, const void *packet); + void (*disable) (struct grub_net *net); + + / The next net device. / + struct grub_net_dev *next; +}; +typedef struct grub_net_dev *grub_net_dev_t; + +struct grub_fs; +*/ +struct grub_ofnet +{ + /* The net name. */ + const char *name; + + /* The OF device string. */ + char *dev; + /*server ip*/ + char *sip; + /*client ip*/ + char *cip; + /*gateway*/ + char *gat; + /**/ + int type; +}; + +typedef struct grub_ofnet *grub_ofnet_t; + +struct grub_bootp { + grub_uint8_t op; /* 1 = BOOTREQUEST, 2 = BOOTREPLY */ + grub_uint8_t htype; /* Hardware address type. */ + grub_uint8_t hlen; /* Hardware address length */ + grub_uint8_t hops; /* Used by gateways in cross-gateway booting. */ + grub_uint32_t xid; /* Transaction ID */ + grub_uint16_t secs; /* Seconds elapsed. */ + grub_uint16_t unused; /* Unused. */ + grub_uint32_t ciaddr; /* Client IP address, */ + grub_uint32_t yiaddr; /* Client IP address filled by server. */ + grub_uint32_t siaddr; /* Server IP address. */ + grub_uint32_t giaddr; /* Gateway IP address. */ + unsigned char chaddr [16]; /* Client hardware address */ + char sname [64]; /* Server name */ + char file [128]; /* Boot filename */ +// grub_uint32_t filesize ; /*File size (testing)*/ + unsigned char vend [64]; +}; + +typedef struct grub_bootp* grub_bootp_t; + +char * grub_get_filestr(const char * ); +char * grub_ip2str (grub_uint32_t ip); +void grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet); +grub_bootp_t grub_getbootp (void); +#endif /* ! GRUB_NET_HEADER */ From 60cdb895da65aaa09dcb256d03063c3a711a61e2 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:15:45 -0300 Subject: [PATCH 0030/1414] Adaptation for the new protocols and interface structs. implementation of receive in the protocols. Also all unwanted packets are discarded. --- commands/net.c | 38 ++++---- include/grub/net.h | 118 ++++++------------------ net/ethernet.c | 88 ++++++++++++------ net/interface.c | 38 ++++++++ net/ip.c | 66 ++++++++++---- net/netbuff.c | 41 +++++++-- net/protocol.c | 50 ++++++---- net/tftp.c | 223 ++++++++++++++++++++++++++++++++++++++------- net/udp.c | 69 +++++++++++--- 9 files changed, 505 insertions(+), 226 deletions(-) diff --git a/commands/net.c b/commands/net.c index 288ba4c2a..b8ceb36f4 100644 --- a/commands/net.c +++ b/commands/net.c @@ -23,14 +23,14 @@ #include struct grub_net_route *grub_net_routes = NULL; -struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; +struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL; struct grub_net_card *grub_net_cards = NULL; -struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; +struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL; grub_err_t -grub_net_resolve_address (struct grub_net_network_level_protocol **prot, +grub_net_resolve_address (struct grub_net_network_layer_protocol **prot, char *name, - grub_net_network_level_address_t *addr) + grub_net_network_layer_address_t *addr) { FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot) { @@ -50,15 +50,15 @@ grub_net_resolve_address (struct grub_net_network_level_protocol **prot, } grub_err_t -grub_net_route_address (grub_net_network_level_address_t addr, - grub_net_network_level_address_t *gateway, - struct grub_net_network_level_interface **interf) +grub_net_route_address (grub_net_network_layer_address_t addr, + grub_net_network_layer_address_t *gateway, + struct grub_net_network_layer_interface **interf) { struct grub_net_route *route; int depth = 0; int routecnt = 0; - struct grub_net_network_level_protocol *prot = NULL; - grub_net_network_level_address_t curtarget = addr; + struct grub_net_network_layer_protocol *prot = NULL; + grub_net_network_layer_address_t curtarget = addr; *gateway = addr; @@ -96,7 +96,7 @@ static grub_err_t grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { - struct grub_net_network_level_interface *inter; + struct grub_net_network_layer_interface *inter; if (argc != 4) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); @@ -107,8 +107,8 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); - inter->protocol->fini (inter); - grub_net_network_level_interface_unregister (inter); +// inter->protocol->fini (inter); + grub_net_network_layer_interface_unregister (inter); grub_free (inter->name); grub_free (inter); @@ -120,10 +120,10 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { struct grub_net_card *card; - struct grub_net_network_level_protocol *prot; + struct grub_net_network_layer_protocol *prot; grub_err_t err; - grub_net_network_level_address_t addr; - struct grub_net_network_level_interface *inter; + grub_net_network_layer_address_t addr; + struct grub_net_network_layer_interface *inter; if (argc != 4) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); @@ -154,14 +154,14 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); inter->card = card; - err = prot->init (inter); + // err = prot->init (inter); if (err) { grub_free (inter->name); grub_free (inter); return err; } - grub_net_network_level_interface_register (inter); + grub_net_network_layer_interface_register (inter); return GRUB_ERR_NONE; } @@ -192,7 +192,7 @@ static grub_err_t grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { - struct grub_net_network_level_protocol *prot; + struct grub_net_network_layer_protocol *prot; struct grub_net_route *route; if (argc < 3) @@ -247,7 +247,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), } else { - struct grub_net_network_level_interface *inter; + struct grub_net_network_layer_interface *inter; route->is_gateway = 0; FOR_NET_NETWORK_LEVEL_INTERFACES (inter) diff --git a/include/grub/net.h b/include/grub/net.h index f021f0e9c..abb8a3167 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -23,20 +23,11 @@ #include #include #include +#include +#include struct grub_net_card; -typedef enum -{ - GRUB_NET_TFTP_ID, - GRUB_NET_UDP_ID, - GRUB_NET_IPV4_ID, - GRUB_NET_IPV6_ID, - GRUB_NET_ETHERNET_ID, - GRUB_NET_ARP_ID, - GRUB_NET_DHCP_ID - -}protocol_type_t; struct grub_net_card_driver { @@ -66,76 +57,36 @@ struct grub_net_card void *data; }; -struct grub_net_network_level_interface; +//struct grub_net_network_layer_interface; -typedef union grub_net_network_level_address +struct grub_net_network_layer_interface { - grub_uint32_t ipv4; -} grub_net_network_level_netaddress_t; - -typedef union grub_net_network_level_netaddress -{ - struct { - grub_uint32_t base; - int masksize; - } ipv4; -} grub_net_network_level_address_t; - -typedef enum grub_network_level_protocol_id -{ - GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 -} grub_network_level_protocol_id_t; - -struct grub_net_network_level_interface; - -struct grub_net_network_level_protocol -{ - struct grub_net_network_level_protocol *next; - char *name; - grub_network_level_protocol_id_t id; - grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr); - char * (*aton) (union grub_net_network_level_address addr); - grub_err_t (*net_ntoa) (char *name, - grub_net_network_level_netaddress_t *addr); - char * (*net_aton) (grub_net_network_level_netaddress_t addr); - int (* match_net) (grub_net_network_level_netaddress_t net, - grub_net_network_level_address_t addr); - grub_err_t (*init) (struct grub_net_network_level_interface *dev); - grub_err_t (*fini) (struct grub_net_network_level_interface *dev); - grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf, - grub_size_t buflen); - grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf, - grub_size_t buflen); -}; - -struct grub_net_network_level_interface -{ - struct grub_net_network_level_interface *next; + struct grub_net_network_layer_interface *next; char *name; /* Underlying protocol. */ - struct grub_net_network_level_protocol *protocol; + struct grub_net_network_layer_protocol *protocol; struct grub_net_card *card; - union grub_net_network_level_address address; + union grub_net_network_layer_address address; void *data; }; struct grub_net_route { struct grub_net_route *next; - grub_net_network_level_netaddress_t target; + grub_net_network_layer_netaddress_t target; char *name; - struct grub_net_network_level_protocol *prot; + struct grub_net_network_layer_protocol *prot; int is_gateway; union { - struct grub_net_network_level_interface *interface; - grub_net_network_level_address_t gw; + struct grub_net_network_layer_interface *interface; + grub_net_network_layer_address_t gw; }; }; struct grub_net_session; -struct grub_net_session_level_protocol +struct grub_net_session_layer_protocol { void (*close) (struct grub_net_session *session); grub_ssize_t (*recv) (struct grub_net_session *session, void *buf, @@ -146,7 +97,7 @@ struct grub_net_session_level_protocol struct grub_net_session { - struct grub_net_session_level_protocol *protocol; + struct grub_net_session_layer_protocol *protocol; void *data; }; @@ -170,23 +121,23 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, return session->protocol->recv (session, buf, size); } -extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; +struct grub_net_network_layer_interface *grub_net_network_layer_interfaces; static inline void -grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) +grub_net_network_layer_interface_register (struct grub_net_network_layer_interface *inter) { - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces), GRUB_AS_LIST (inter)); } static inline void -grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) +grub_net_network_layer_interface_unregister (struct grub_net_network_layer_interface *inter) { - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces), GRUB_AS_LIST (inter)); } -#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_layer_interfaces; var; var = var->next) extern struct grub_net_route *grub_net_routes; @@ -224,28 +175,13 @@ grub_net_card_unregister (struct grub_net_card *card) #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) -extern struct grub_net_network_level_protocol *grub_net_network_level_protocols; -static inline void -grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols), - GRUB_AS_LIST (prot)); -} - -static inline void -grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols), - GRUB_AS_LIST (prot)); -} - -#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next) +#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_layer_protocols; (var); (var) = (var)->next) static inline grub_err_t -grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot, +grub_net_resolve_address_in_protocol (struct grub_net_network_layer_protocol *prot, char *name, - grub_net_network_level_address_t *addr) + grub_net_network_layer_address_t *addr) { return prot->ntoa (name, addr); } @@ -254,14 +190,14 @@ struct grub_net_session * grub_net_open_tcp (char *address, grub_uint16_t port); grub_err_t -grub_net_resolve_address (struct grub_net_network_level_protocol **prot, +grub_net_resolve_address (struct grub_net_network_layer_protocol **prot, char *name, - grub_net_network_level_address_t *addr); + grub_net_network_layer_address_t *addr); grub_err_t -grub_net_route_address (grub_net_network_level_address_t addr, - grub_net_network_level_address_t *gateway, - struct grub_net_network_level_interface **interf); +grub_net_route_address (grub_net_network_layer_address_t addr, + grub_net_network_layer_address_t *gateway, + struct grub_net_network_layer_interface **interf); #endif /* ! GRUB_NET_HEADER */ diff --git a/net/ethernet.c b/net/ethernet.c index 8c13966c1..a4bdbff5b 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -5,51 +5,85 @@ #include #include #include -#include #include +#include static grub_err_t -send_ethernet_packet (struct grub_net_interface *inf,struct grub_net_protstack *protstack __attribute__ ((unused)) - ,struct grub_net_buff *nb) +send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), + struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) { - struct etherhdr *eth; - grub_err_t err; - - if((err = grub_netbuff_push (nb,sizeof(*eth)) ) != GRUB_ERR_NONE) - return err; + struct etherhdr *eth; + + grub_netbuff_push (nb,sizeof(*eth)); eth = (struct etherhdr *) nb->data; - grub_memcpy (eth->src,inf->card->lla->addr,6 * sizeof (grub_uint8_t )); - grub_memcpy (eth->dst,inf->lla->addr,6 * sizeof (grub_uint8_t )); + eth->dst[0] =0x00; + eth->dst[1] =0x11; + eth->dst[2] =0x25; + eth->dst[3] =0xca; + eth->dst[4] =0x1f; + eth->dst[5] =0x01; + eth->src[0] =0x0a; + eth->src[1] =0x11; + eth->src[2] =0xbd; + eth->src[3] =0xe3; + eth->src[4] =0xe3; + eth->src[5] =0x04; + eth->type = 0x0800; - - return inf->card->driver->send(inf->card,nb); + + return send_card_buffer(nb); +// return inf->card->driver->send(inf->card,nb); } -static struct grub_net_protocol grub_ethernet_protocol = + +static grub_err_t +recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), + struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) { - .name = "udp", - .send = send_ethernet_packet + struct etherhdr *eth; + while (1) + { + get_card_packet (nb); + eth = (struct etherhdr *) nb->data; + /*change for grub_memcmp*/ + if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && + eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && eth->type == 0x800) + { + //grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], + // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); + // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], + // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); + //grub_printf("ethernet eth->type 0x%x\n",eth->type); + //grub_printf("out from ethernet\n"); + grub_netbuff_pull(nb,sizeof(*eth)); + return 0; + } + } +/* - get ethernet header + - verify if the next layer is the desired one. + - if not. get another packet. + - remove ethernet header from buffer*/ + return 0; +} + + +static struct grub_net_link_layer_protocol grub_ethernet_protocol = +{ + .name = "ethernet", + .id = GRUB_NET_ETHERNET_ID, + .send = send_ethernet_packet, + .recv = recv_ethernet_packet }; void ethernet_ini(void) { - grub_protocol_register (&grub_ethernet_protocol); + grub_net_link_layer_protocol_register (&grub_ethernet_protocol); } void ethernet_fini(void) { - grub_protocol_unregister (&grub_ethernet_protocol); + grub_net_link_layer_protocol_unregister (&grub_ethernet_protocol); } -/* -int read_ethernet_packet(buffer,bufflen, int type) -{ - - struct etherhdr eth; - eth.type = 0; - - get_card_buffer (ð,sizeof (eth)); - -}*/ diff --git a/net/interface.c b/net/interface.c index e69de29bb..bacabf4cb 100644 --- a/net/interface.c +++ b/net/interface.c @@ -0,0 +1,38 @@ +/*#include + +#define INTERFACE_REGISTER_FUNCTIONS(layerprevious,layernext) \ +struct grub_net_##layername_layer_protocol *grub_net_##layername_layer_protocols;\ +\ +void grub_net_##layerprevious_##layernext_interface_register (struct grub_net_##layername_layer_protocol *prot)\ +{\ + grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ +\ +void grub_net_##layerprevious_##layernext_interface_unregister (struct grub_net_##layername_layer_protocol *prot);\ +{\ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ + +INTERFACE_REGISTER_FUNCTIONS("application","transport"); +INTERFACE_REGISTER_FUNCTIONS("transport","network"); +INTERFACE_REGISTER_FUNCTIONS("network","link"); +INTERFACE_REGISTER_FUNCTIONS("link");*/ + +#include +#include +struct grub_net_protocol_stack *grub_net_protocol_stacks; +struct grub_net_protocol_stack + *grub_net_protocol_stack_get (char *name) +{ + struct grub_net_protocol_stack *p; + + for (p = grub_net_protocol_stacks; p; p = p->next) + { + if (!grub_strcmp(p->name,name)) + return p; + } + + return NULL; +} diff --git a/net/ip.c b/net/ip.c index 6fe58adb0..5eaa74f90 100644 --- a/net/ip.c +++ b/net/ip.c @@ -1,11 +1,11 @@ #include -#include #include #include #include -#include -#include #include +#include +#include +#include #include struct grub_net_protocol *grub_ipv4_prot; @@ -29,14 +29,14 @@ ipchksum(void *ipv, int len) static grub_err_t -send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb ) +send_ip_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb ) { struct iphdr *iph; - grub_err_t err; + static int id = 0x2400; - if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE) - return err; + grub_netbuff_push(nb,sizeof(*iph)); iph = (struct iphdr *) nb->data; /*FIXME dont work in litte endian machines*/ @@ -44,38 +44,64 @@ send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *prots //grub_uint8_t hdrlen = sizeof (struct iphdr)/4; iph->verhdrlen = (4<<4 | 5); iph->service = 0; - iph->len = sizeof(*iph); - iph->ident = 0x2b5f; + iph->len = nb->tail - nb-> data;//sizeof(*iph); + iph->ident = ++id; iph->frags = 0; iph->ttl = 0xff; iph->protocol = 0x11; - //grub_memcpy(&(iph->src) ,inf->card->ila->addr,inf->card->ila->len); - iph->src = *((grub_uint32_t *)inf->card->ila->addr); - //grub_memcpy(&(iph->dest) ,inf->ila->addr,inf->ila->len); - iph->dest = *((grub_uint32_t *)inf->ila->addr); + iph->src = (grub_uint32_t) bootp_pckt -> yiaddr; //inf->address.ipv4; // *((grub_uint32_t *)inf->card->ila->addr); + iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr); iph->chksum = 0 ; - iph->chksum = ipchksum((void *)nb->head, sizeof(*iph)); + iph->chksum = ipchksum((void *)nb->data, sizeof(*iph)); - - return protstack->next->prot->send(inf,protstack->next,nb); + return trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb); + //return protstack->next->prot->send(inf,protstack->next,nb); } -static struct grub_net_protocol grub_ipv4_protocol = +static grub_err_t +recv_ip_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb ) +{ + + struct iphdr *iph; + while (1) + { + trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); + iph = (struct iphdr *) nb->data; + if (iph->dest == 0x0908eaaa && iph->src == 0x0908ea92 && iph->protocol == 0x11) + { + grub_netbuff_pull(nb,sizeof(*iph)); + return 0; + } + } +/* grub_printf("ip.src 0x%x\n",iph->src); + grub_printf("ip.dst 0x%x\n",iph->dest); + grub_printf("ip.len 0x%x\n",iph->len); + grub_printf("ip.protocol 0x%x\n",iph->protocol); + */ + /* - get ip header + - verify if is the next layer is correct + -*/ + return 0; +} + +static struct grub_net_network_layer_protocol grub_ipv4_protocol = { .name = "ipv4", + .id = GRUB_NET_IPV4_ID, .send = send_ip_packet, - .recv = NULL + .recv = recv_ip_packet }; void ipv4_ini(void) { - grub_protocol_register (&grub_ipv4_protocol); + grub_net_network_layer_protocol_register (&grub_ipv4_protocol); } void ipv4_fini(void) { - grub_protocol_unregister (&grub_ipv4_protocol); + grub_net_network_layer_protocol_unregister (&grub_ipv4_protocol); } /* diff --git a/net/netbuff.c b/net/netbuff.c index 342260f43..136d55bc4 100644 --- a/net/netbuff.c +++ b/net/netbuff.c @@ -26,7 +26,7 @@ grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->tail += len; if (net_buff->tail > net_buff->end) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "put out of the packet range."); return GRUB_ERR_NONE; } @@ -34,15 +34,20 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->tail -= len; if (net_buff->tail < net_buff->head) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "unput out of the packet range."); return GRUB_ERR_NONE; } grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->data -= len; +/* grub_printf("push len =%d\n",len); + grub_printf("pack->head =%x\n",(unsigned int)net_buff->head); + grub_printf("pack->data =%x\n",(unsigned int)net_buff->data); + grub_printf("pack->tail =%x\n",(unsigned int)net_buff->tail); + grub_printf("pack->end =%x\n",(unsigned int)net_buff->end);*/ if (net_buff->data < net_buff->head) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range."); return GRUB_ERR_NONE; } @@ -50,7 +55,7 @@ grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->data += len; if (net_buff->data > net_buff->end) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "pull out of the packet range."); return GRUB_ERR_NONE; } @@ -59,14 +64,36 @@ grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len net_buff->data += len; net_buff->tail += len; if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range."); + return grub_error (GRUB_ERR_OUT_OF_RANGE, "reserve out of the packet range."); return GRUB_ERR_NONE; } -struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ) +struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) { + struct grub_net_buff *nb; + void *data; + if (len < NETBUFFMINLEN) len = NETBUFFMINLEN; + len = ALIGN_UP (len,NETBUFF_ALIGN); - return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN); + data = grub_memalign (len + sizeof (*nb),NETBUFF_ALIGN); + nb = (struct grub_net_buff *) ((int)data + len); + nb->head = nb->data = nb->tail = data; + nb->end = (char *) nb; + + return nb; +} + +grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff) +{ + grub_free (net_buff); + return 0; + +} + +grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff) +{ + net_buff->data = net_buff->tail = net_buff->head; + return 0; } diff --git a/net/protocol.c b/net/protocol.c index a6117dc2c..05d4471d2 100644 --- a/net/protocol.c +++ b/net/protocol.c @@ -1,21 +1,37 @@ #include +#include +#include -static grub_net_protocol_t grub_net_protocols; - -void grub_protocol_register (grub_net_protocol_t prot) -{ - prot->next = grub_net_protocols; - grub_net_protocols = prot; +#define PROTOCOL_REGISTER_FUNCTIONS(layername) \ +struct grub_net_##layername##_layer_protocol *grub_net_##layername##_layer_protocols;\ +\ +void grub_net_##layername##_layer_protocol_register (struct grub_net_##layername##_layer_protocol *prot)\ +{\ + grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ +\ +void grub_net_##layername##_layer_protocol_unregister (struct grub_net_##layername##_layer_protocol *prot)\ +{\ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\ + GRUB_AS_LIST (prot));\ +}\ +\ +struct grub_net_##layername##_layer_protocol \ + *grub_net_##layername##_layer_protocol_get (grub_net_protocol_id_t id)\ +{\ + struct grub_net_##layername##_layer_protocol *p;\ +\ + for (p = grub_net_##layername##_layer_protocols; p; p = p->next)\ + {\ + if (p->id == id)\ + return p;\ + }\ + \ + return NULL; \ } -void grub_protocol_unregister (grub_net_protocol_t prot) -{ - grub_net_protocol_t *p, q; - - for (p = &grub_net_protocols, q = *p; q; p = &(q->next), q = q->next) - if (q == prot) - { - *p = q->next; - break; - } -} +PROTOCOL_REGISTER_FUNCTIONS(application); +PROTOCOL_REGISTER_FUNCTIONS(transport); +PROTOCOL_REGISTER_FUNCTIONS(network); +PROTOCOL_REGISTER_FUNCTIONS(link); diff --git a/net/tftp.c b/net/tftp.c index 3f481fe58..1f04ef47e 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -4,42 +4,94 @@ #include #include #include -#include #include #include -#include #include +#include +#include +#include + +int block,rrq_count=0; +struct { + int block_size; + int size; +} tftp_file; + + +char *get_tok_val(char **tok, char **val, char **str_opt,char *end); +void process_option(char *tok, char *val); + +char *get_tok_val(char **tok, char **val,char **str_opt,char *end) +{ + char *p = *str_opt; + *tok = p; + p += grub_strlen(p) + 1; + + if(p > end) + return NULL; + + *val = p; + p += grub_strlen(p) + 1; + *str_opt = p; + return *tok; +} + +void process_option(char *tok, char *val) +{ + if (!grub_strcmp(tok,"blksize")) + { + tftp_file.block_size = grub_strtoul (val,NULL,0); + return; + } + + if (!grub_strcmp(tok,"tsize")) + { + tftp_file.size = grub_strtoul (val,NULL,0); + return; + } + +} + +//void tftp_open (char *options); /*send read request*/ static grub_err_t -send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protstack,struct grub_net_buff *nb) +tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb, char *filename) { - /*Start TFTP header*/ - struct tftphdr *tftph; char *rrq; int rrqlen; int hdrlen; - grub_err_t err; + struct udp_interf *udp_interf; + struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface; - if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE) - return err; + app_interface = (struct grub_net_application_transport_interface *) protstack->interface; + grub_netbuff_push (nb,sizeof (*tftph)); + udp_interf = (struct udp_interf *) app_interface->data; + udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; + grub_printf("open tfpt udp_port = %d\n",udp_interf->src); + udp_interf->dst = TFTP_SERVER_PORT; tftph = (struct tftphdr *) nb->data; rrq = (char *) tftph->u.rrq; rrqlen = 0; tftph->opcode = TFTP_RRQ; - grub_strcpy (rrq,inf->path); - rrqlen += grub_strlen (inf->path) + 1; - rrq += grub_strlen (inf->path) + 1; + grub_strcpy (rrq,filename); + rrqlen += grub_strlen (filename) + 1; + rrq += grub_strlen (filename) + 1; /*passar opcoes como parametro ou usar default?*/ grub_strcpy (rrq,"octet"); rrqlen += grub_strlen ("octet") + 1; rrq += grub_strlen ("octet") + 1; + //grub_strcpy (rrq,"netascii"); + //rrqlen += grub_strlen ("netascii") + 1; + //rrq += grub_strlen ("netascii") + 1; + grub_strcpy (rrq,"blksize"); rrqlen += grub_strlen("blksize") + 1; rrq += grub_strlen ("blksize") + 1; @@ -59,39 +111,146 @@ send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protsta grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); - return protstack->next->prot->send(inf,protstack->next,nb); + app_interface->trans_prot->send (inf,protstack->interface,nb); + /*Receive OACK*/ + return app_interface->app_prot->recv(inf,protstack,nb); } -/* -int send_tftp_ack(int block, int port){ - - tftp_t pckt; - int pcktlen; - pckt.opcode = TFTP_ACK; - pckt.u.ack.block = block; - pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block); - - port = 4; - return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port); -} - -*/ - -static struct grub_net_protocol grub_tftp_protocol = +static grub_err_t +tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb) { - .name = "tftp", - .open = send_tftp_rr + struct tftphdr *tftph; + char *token,*value,*temp; + struct grub_net_application_transport_interface *app_interface = + (struct grub_net_application_transport_interface *) protstack->interface; + + app_interface->trans_prot->recv (inf,protstack->interface,nb); + + tftph = (struct tftphdr *) nb->data; + switch (tftph->opcode) + { + case TFTP_OACK: + /*process oack packet*/ + temp = (char *) tftph->u.oack.data; + while(get_tok_val(&token,&value,&temp,nb->tail)) + { + grub_printf("tok = <%s> val = <%s>\n",token,value); + process_option(token,value); + } + + //buff_clean + nb->data = nb->tail; + grub_printf("OACK---------------------------------------------------------\n"); + grub_printf("block_size=%d\n",tftp_file.block_size); + grub_printf("file_size=%d\n",tftp_file.size); + grub_printf("OACK---------------------------------------------------------\n"); + block = 0; + break; + case TFTP_DATA: + grub_netbuff_pull (nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block)); + if (tftph->u.data.block == block + 1) + block = tftph->u.data.block; + else + grub_netbuff_clear(nb); + break; + case TFTP_ERROR: + nb->data = nb->tail; + break; + } + return 0;// tftp_send_ack (inf,protstack,nb,tftph->u.data.block); + /*remove tftp header and return. + nb should now contain only the payload*/ +} + +static grub_err_t +tftp_send_ack (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb) +{ + struct tftphdr *tftph; + struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface; + + nb->data = nb->tail = nb->end; + + grub_netbuff_push (nb,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block)); + + tftph = (struct tftphdr *) nb->data; + tftph->opcode = TFTP_ACK; + tftph->u.ack.block = block; + + return app_interface->trans_prot->send (inf,protstack->interface,nb); +} + +static int tftp_file_size (struct grub_net_network_layer_interface* inf , + struct grub_net_protocol_stack *protocol_stack , struct grub_net_buff *nb ,char *filename ) +{ + + tftp_open (inf, protocol_stack,nb, filename); + return tftp_file.size; +} + +static grub_err_t +tftp_close (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack __attribute((unused)),struct grub_net_buff *nb __attribute((unused))) +{ + + return 0; +} + +static struct grub_net_application_transport_interface grub_net_tftp_app_trans_interf; +static struct grub_net_transport_network_interface grub_net_tftp_trans_net_interf; +static struct grub_net_network_link_interface grub_net_tftp_net_link_interf; +static struct grub_net_protocol_stack grub_net_tftp_stack = +{ + .name = "tftp", + .id = GRUB_NET_TFTP_ID, + .interface = (void *) &grub_net_tftp_app_trans_interf + }; +static struct grub_net_application_layer_protocol grub_tftp_protocol = +{ + .name = "tftp", + .id = GRUB_NET_TFTP_ID, + .open = tftp_open, + .recv = tftp_receive, + .send_ack = tftp_send_ack, + .get_file_size = tftp_file_size, + .close = tftp_close +}; + +static struct udp_interf tftp_udp_interf; + void tftp_ini(void) { - grub_protocol_register (&grub_tftp_protocol); + + ethernet_ini (); + ipv4_ini (); + udp_ini (); + grub_net_application_layer_protocol_register (&grub_tftp_protocol); + grub_net_stack_register (&grub_net_tftp_stack); + + grub_net_tftp_app_trans_interf.app_prot = &grub_tftp_protocol; + grub_net_tftp_app_trans_interf.trans_prot = grub_net_transport_layer_protocol_get (GRUB_NET_UDP_ID); + grub_net_tftp_app_trans_interf.inner_layer = &grub_net_tftp_trans_net_interf; + grub_net_tftp_app_trans_interf.data = &tftp_udp_interf; + + grub_net_tftp_trans_net_interf.trans_prot = grub_net_tftp_app_trans_interf.trans_prot; + grub_net_tftp_trans_net_interf.net_prot = grub_net_network_layer_protocol_get (GRUB_NET_IPV4_ID); + grub_net_tftp_trans_net_interf.inner_layer = &grub_net_tftp_net_link_interf; + + grub_net_tftp_net_link_interf.net_prot = grub_net_tftp_trans_net_interf.net_prot; + grub_net_tftp_net_link_interf.link_prot = grub_net_link_layer_protocol_get (GRUB_NET_ETHERNET_ID) ; + + } void tftp_fini(void) { - grub_protocol_unregister (&grub_tftp_protocol); + + + grub_net_application_layer_protocol_unregister (&grub_tftp_protocol); } /* int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){ diff --git a/net/udp.c b/net/udp.c index 2a4a7690b..fb81aef93 100644 --- a/net/udp.c +++ b/net/udp.c @@ -4,41 +4,84 @@ #include #include #include -/*Assumes that there is allocated memory to the header before the buffer address. */ + static grub_err_t -send_udp_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb) +send_udp_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb) { struct udphdr *udph; - grub_err_t err; + struct udp_interf *udp_interf; - if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE) - return err; + grub_netbuff_push (nb,sizeof(*udph)); udph = (struct udphdr *) nb->data; - udph->src = *((grub_uint16_t *) inf->card->tla->addr); - udph->dst = *((grub_uint16_t *) inf->tla->addr); + udp_interf = (struct udp_interf *) app_trans_inf->data; + udph->src = udp_interf->src; + udph->dst = udp_interf->dst; + /*no chksum*/ udph->chksum = 0; - udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head; + udph->len = nb->tail - nb->data; - return protstack->next->prot->send(inf,protstack->next,nb); + return app_trans_inf->inner_layer->net_prot->send(inf,app_trans_inf->inner_layer,nb); } -static struct grub_net_protocol grub_udp_protocol = +static grub_err_t +receive_udp_packet (struct grub_net_network_layer_interface *inf, + struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb) +{ + + struct udphdr *udph; + struct udp_interf *udp_interf; + udp_interf = (struct udp_interf *) app_trans_inf->data; + + while(1) + { + app_trans_inf->inner_layer->net_prot->recv(inf,app_trans_inf->inner_layer,nb); + + udph = (struct udphdr *) nb->data; + // grub_printf("udph->dst %d\n",udph->dst); + // grub_printf("udp_interf->src %d\n",udp_interf->src); + if (udph->dst == udp_interf->src) + { + grub_netbuff_pull (nb,sizeof(*udph)); + + // udp_interf->src = udph->dst; + udp_interf->dst = udph->src; + + // grub_printf("udph->dst %d\n",udph->dst); + // grub_printf("udph->src %d\n",udph->src); + // grub_printf("udph->len %d\n",udph->len); + // grub_printf("udph->chksum %x\n",udph->chksum); + + /* - get udp header.. + - verify if is in the desired port + - if not. get another packet + - remove udp header*/ + + return 0; + } + } +} + + +static struct grub_net_transport_layer_protocol grub_udp_protocol = { .name = "udp", - .send = send_udp_packet + .id = GRUB_NET_UDP_ID, + .send = send_udp_packet, + .recv = receive_udp_packet }; void udp_ini(void) { - grub_protocol_register (&grub_udp_protocol); + grub_net_transport_layer_protocol_register (&grub_udp_protocol); } void udp_fini(void) { - grub_protocol_unregister (&grub_udp_protocol); + grub_net_transport_layer_protocol_unregister (&grub_udp_protocol); } /* From 8c599704a75bad68bd4d903fc1b111cba91bd354 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Mon, 21 Jun 2010 19:20:55 -0300 Subject: [PATCH 0031/1414] Network code specific for ieee1275 machines. Used to parse BOOTP packet from the server and use write/read on the network card. May be removed later. --- conf/powerpc-ieee1275.rmk | 3 +- include/grub/disk.h | 3 +- include/grub/ieee1275/ieee1275.h | 3 +- kern/ieee1275/init.c | 4 +- kern/ieee1275/openfw.c | 68 ++++++++++++++++-- kern/main.c | 8 +-- net/ieee1275/interface.c | 120 ++++++++++++++++++------------- 7 files changed, 144 insertions(+), 65 deletions(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 14d04f93e..ead6d4230 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -24,7 +24,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c \ - net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c + net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c \ + fs/ieee1275/ofnet.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic diff --git a/include/grub/disk.h b/include/grub/disk.h index e7f807e0e..1bdfb639b 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_OFNET_ID }; struct grub_disk; diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index b30909c68..f4c8b4edf 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -182,9 +182,8 @@ EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt, char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path); - int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) (struct grub_ieee1275_devalias * alias)); - +char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index b7e5c337e..1e108c920 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -32,6 +32,7 @@ #include #include #include +#include /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) @@ -223,13 +224,14 @@ grub_machine_init (void) grub_ssize_t actual; grub_ieee1275_init (); - + grub_console_init (); #ifdef __i386__ grub_get_extended_memory (); #endif grub_claim_heap (); grub_ofdisk_init (); + grub_ofnet_init(); /* Process commandline. */ if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args, diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 5693f3be0..337fc4b7e 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -22,11 +22,13 @@ #include #include #include +#include enum grub_ieee1275_parse_type { GRUB_PARSE_FILENAME, GRUB_PARSE_PARTITION, + GRUB_PARSE_DEVICE }; /* Walk children of 'devpath', calling hook for each. */ @@ -366,12 +368,14 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) ret = grub_strndup (args, (grub_size_t)(comma - args)); } } - else + + else if (!grub_strcmp ("network", type)) + { + if (ptype == GRUB_PARSE_DEVICE) + ret = grub_strdup(device); + } + else { - /* XXX Handle net devices by configuring & registering a grub_net_dev - here, then return its name? - Example path: "net:,,,,,". */ grub_printf ("Unsupported type %s for device %s\n", type, device); } @@ -381,6 +385,12 @@ fail: return ret; } +char * +grub_ieee1275_get_aliasdevname (const char *path) +{ + return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE); +} + char * grub_ieee1275_get_filename (const char *path) { @@ -432,3 +442,51 @@ grub_halt (void) grub_ieee1275_interpret ("power-off", 0); grub_ieee1275_interpret ("poweroff", 0); } + +static const struct +{ + char *name; + int offset; +} + +bootp_response_properties[] = +{ + { .name = "bootp-response", .offset = 0 }, + { .name = "dhcp-response", .offset = 0 }, + { .name = "bootpreply-packet", .offset = 0x2a }, +}; + +#define SIZE(X) ( sizeof (X) / sizeof(X[0])) + +grub_bootp_t +grub_getbootp( void ) +{ + grub_bootp_t packet = grub_malloc(sizeof *packet); + void *bootp_response = NULL; + grub_ssize_t size; + unsigned int i; + // grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); + for ( i = 0; i < SIZE(bootp_response_properties); i++) + { + if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, + bootp_response_properties[i].name, &size)>=0) + break; + } + + if ( size <0 ) + { + grub_printf("Error to get bootp\n"); + return NULL; + } + + if (grub_ieee1275_get_property (grub_ieee1275_chosen, bootp_response_properties[i].name , bootp_response , + size, 0) < 0) + { + grub_printf("Error to get bootp\n"); + return NULL; + } + + packet = (void *) ((int)bootp_response + bootp_response_properties[i].offset); + return packet; +} + diff --git a/kern/main.c b/kern/main.c index 8b6c8a180..3320c4a68 100644 --- a/kern/main.c +++ b/kern/main.c @@ -95,14 +95,14 @@ grub_load_modules (void) grub_module_iterate (hook); } - +/* static void grub_load_config (void) { auto int hook (struct grub_module_header *); int hook (struct grub_module_header *header) { - /* Not an embedded config, skip. */ + / Not an embedded config, skip. / if (header->type != OBJ_TYPE_CONFIG) return 0; @@ -113,7 +113,7 @@ grub_load_config (void) grub_module_iterate (hook); } - +*/ /* Write hook for the environment variables of root. Remove surrounding parentheses, if any. */ static char * @@ -192,7 +192,7 @@ grub_main (void) grub_register_core_commands (); - grub_load_config (); + //grub_load_config (); grub_load_normal_mode (); grub_rescue_run (); } diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index 5a246ffa5..fbd887ad2 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -1,55 +1,21 @@ #include +#include #include - -grub_uint32_t get_server_ip (void) -{ - return bootp_pckt->siaddr; -} - -grub_uint32_t get_client_ip (void) -{ - return bootp_pckt->yiaddr; -} - -grub_uint8_t* get_server_mac (void) -{ - grub_uint8_t *mac; - - mac = grub_malloc (6 * sizeof(grub_uint8_t)); - mac[0] = 0x00 ; - mac[1] = 0x11 ; - mac[2] = 0x25 ; - mac[3] = 0xca ; - mac[4] = 0x1f ; - mac[5] = 0x01 ; - - return mac; - -} - -grub_uint8_t* get_client_mac (void) -{ - grub_uint8_t *mac; - - mac = grub_malloc (6 * sizeof (grub_uint8_t)); - mac[0] = 0x0a ; - mac[1] = 0x11 ; - mac[2] = 0xbd ; - mac[3] = 0xe3 ; - mac[4] = 0xe3 ; - mac[5] = 0x04 ; - - return mac; -} +#include +#include +#include +#include +#include static grub_ieee1275_ihandle_t handle; int card_open (void) { grub_ieee1275_open (grub_net->dev , &handle); - return 1;//error + return 0; } + int card_close (void) { @@ -59,22 +25,74 @@ int card_close (void) } -int send_card_buffer (void *buffer,int buff_len) +int send_card_buffer (struct grub_net_buff *pack) { - int actual; - - grub_ieee1275_write (handle,buffer,buff_len,&actual); + int actual; + //grub_printf("packet size transmited: %d\n",pack->tail - pack->data); + grub_ieee1275_write (handle,pack->data,pack->tail - pack->data,&actual); +// grub_printf("actual transmited %d\n",actual); return actual; } -int get_card_buffer (void *buffer,int buff_len) +int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) { - int actual; + int actual; + char *datap; + struct iphdr *iph; + struct etherhdr *eth; + struct arphdr *arph; + pack->data = pack->tail = pack->head; + datap = pack->data; + do + { + grub_ieee1275_read (handle,datap,sizeof (*eth),&actual); + // if (actual <= 0) + // grub_millisleep(10); - grub_ieee1275_read (handle,buffer,buff_len,&actual); - - return actual; + }while (actual <= 0); + eth = (struct etherhdr *) datap; + datap += sizeof(*eth); + + // grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], + // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); + // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], + // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); +// grub_printf ("eth.type 0x%x\n",eth->type); + + switch (eth->type) + { + case 0x806: + + grub_ieee1275_read (handle,datap,sizeof (*arph),&actual); + arph = (struct arphdr *) datap; + + grub_netbuff_put (pack,sizeof (*eth) + sizeof (*arph)); + break; + case 0x800: + grub_ieee1275_read (handle,datap,sizeof (*iph),&actual); + iph = (struct iphdr *) datap; + datap += sizeof(*iph); + + // grub_printf("ip.src 0x%x\n",iph->src); + // grub_printf("ip.dst 0x%x\n",iph->dest); + // grub_printf("ip.len 0x%x\n",iph->len); + // grub_printf("ip.protocol 0x%x\n",iph->protocol); + + grub_ieee1275_read (handle,datap,iph->len - sizeof (*iph),&actual); + + + grub_netbuff_put (pack,sizeof (*eth) + iph->len); + break; + case 0x86DD: + grub_printf("Ipv6 not yet implemented.\n"); + break; + default: + grub_printf("Unknow packet %x\n",eth->type); + break; + } +// grub_printf("packsize %d\n",pack->tail - pack->data); + return 0;// sizeof (eth) + iph.len; } From bf6d9eeb531e19d88c1705688468b89ea44c9031 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 23 Jun 2010 14:47:55 -0300 Subject: [PATCH 0032/1414] Abort transference when getting file size. --- net/tftp.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index 1f04ef47e..8e89ed1f4 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -71,7 +71,6 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), udp_interf = (struct udp_interf *) app_interface->data; udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; - grub_printf("open tfpt udp_port = %d\n",udp_interf->src); udp_interf->dst = TFTP_SERVER_PORT; tftph = (struct tftphdr *) nb->data; @@ -135,16 +134,15 @@ tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)) temp = (char *) tftph->u.oack.data; while(get_tok_val(&token,&value,&temp,nb->tail)) { - grub_printf("tok = <%s> val = <%s>\n",token,value); process_option(token,value); } //buff_clean nb->data = nb->tail; - grub_printf("OACK---------------------------------------------------------\n"); - grub_printf("block_size=%d\n",tftp_file.block_size); - grub_printf("file_size=%d\n",tftp_file.size); - grub_printf("OACK---------------------------------------------------------\n"); + // grub_printf("OACK---------------------------------------------------------\n"); + //grub_printf("block_size=%d\n",tftp_file.block_size); + // grub_printf("file_size=%d\n",tftp_file.size); + // grub_printf("OACK---------------------------------------------------------\n"); block = 0; break; case TFTP_DATA: @@ -182,11 +180,39 @@ tftp_send_ack (struct grub_net_network_layer_interface *inf __attribute((unused) return app_interface->trans_prot->send (inf,protstack->interface,nb); } +static grub_err_t +tftp_send_err (struct grub_net_network_layer_interface *inf __attribute((unused)), + struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb, char *errmsg, int errcode) +{ + + struct tftphdr *tftph; + struct grub_net_application_transport_interface *app_interface + = (struct grub_net_application_transport_interface *) protstack->interface; + int msglen = 0; + int hdrlen = 0; + nb->data = nb->tail = nb->end; + + grub_netbuff_push (nb,sizeof (*tftph)); + + tftph = (struct tftphdr *) nb->data; + tftph->opcode = TFTP_ERROR; + tftph->u.err.errcode = errcode; + + grub_strcpy ((char *)tftph->u.err.errmsg,errmsg); + msglen += grub_strlen (errmsg) + 1; + hdrlen = sizeof (tftph->opcode) + sizeof (tftph->u.err.errcode) + msglen; + grub_netbuff_unput (nb,nb->tail - (nb->data + hdrlen)); + + return app_interface->trans_prot->send (inf,protstack->interface,nb); +} + static int tftp_file_size (struct grub_net_network_layer_interface* inf , struct grub_net_protocol_stack *protocol_stack , struct grub_net_buff *nb ,char *filename ) { tftp_open (inf, protocol_stack,nb, filename); + tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0); + return tftp_file.size; } From 1edb7287ff681aa6889e397ab4c891ea93246f2f Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 23 Jun 2010 14:49:46 -0300 Subject: [PATCH 0033/1414] Parse ipv6 header on incoming packets. --- conf/powerpc-ieee1275.rmk | 1 - fs/ieee1275/ofnet.c | 31 +++++++++++++++---------------- include/grub/net/ip.h | 12 ++++++++++++ net/ieee1275/interface.c | 14 ++++++++++++-- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index ead6d4230..f0faef489 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -3,7 +3,6 @@ # Images. -<<<<<<< TREE kernel_img_HEADERS += ieee1275/ieee1275.h \ command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\ net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 196aadcf2..3bbb5c227 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -145,7 +145,7 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) return 1; } - grub_printf("name = %s\n",name); + // grub_printf("name = %s\n",name); struct grub_net_protocol_stack *stack; struct grub_net_buff *pack; @@ -164,38 +164,37 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) { - grub_printf("traing to claim %d bytes at 0x%x\n",file_size,found_addr); +// grub_printf("trying to claim %d bytes at 0x%x\n",file_size,found_addr); if (grub_claimmap (found_addr , file_size) != -1) break; } - grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); +// grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); file->data = (void *) found_addr; - grub_printf("file->data = 0x%x\n",(int)file->data); - grub_printf("file_size = %d\n",file_size); - grub_printf("OPEN\n"); +// grub_printf("file->data = 0x%x\n",(int)file->data); +// grub_printf("file_size = %d\n",file_size); +// grub_printf("OPEN\n"); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->open (NULL,stack,pack,(char *) name); do { //if (app_interface->app_prot->recv (NULL,stack,pack) == GRUB_ERR_NONE) - grub_printf("RECEIVE PACKET\n"); +// grub_printf("RECEIVE PACKET\n"); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->recv (NULL,stack,pack); if (grub_errno != GRUB_ERR_NONE) return grub_errno; - grub_printf("RECEIVED PACKET\n"); +// grub_printf("RECEIVED PACKET\n"); // { - grub_printf("payload_size= %d\n",pack->tail - pack->data); - grub_printf("amount= %d\n",amount); - grub_printf("file_size= %d\n",file_size); +// grub_printf("payload_size= %d\n",pack->tail - pack->data); +// grub_printf("amount= %d\n",amount); +// grub_printf("file_size= %d\n",file_size); datap = (char *)file->data + amount; amount += (pack->tail - pack->data); - grub_printf("datap = 0x%x\n",(int)datap ); - // amount += pack->tail - pack->data; +// grub_printf("datap = 0x%x\n",(int)datap ); grub_memcpy(datap, pack->data, pack->tail - pack->data); - grub_printf("SEND ACK\n"); +// grub_printf("SEND ACK\n"); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); @@ -204,12 +203,12 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) if (grub_errno != GRUB_ERR_NONE) return grub_errno; - grub_printf("SENT ACK\n"); +// grub_printf("SENT ACK\n"); //} // file->data = grub_realloc(file->data,amount); }while (amount < file_size); - grub_printf("transfer complete\n"); +// grub_printf("transfer complete\n"); file->size = file_size; // grub_netbuff_free(pack); diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index e1f45dcfa..cb119ac6f 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -16,6 +16,18 @@ struct iphdr { grub_uint32_t dest; } __attribute__ ((packed)) ; +struct ip6hdr +{ + grub_uint8_t version:4, + priority:4; + grub_uint8_t flow_lbl[3]; + grub_uint16_t payload_len; + grub_uint8_t nexthdr; + grub_uint8_t hop_limit; + grub_uint8_t saddr[16]; + grub_uint8_t daddr[16]; +} __attribute__ ((packed)); + #define IP_UDP 17 /* UDP protocol */ #define IP_BROADCAST 0xFFFFFFFF diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index fbd887ad2..1100ee85d 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -44,6 +44,7 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) struct iphdr *iph; struct etherhdr *eth; struct arphdr *arph; + struct ip6hdr *ip6h; pack->data = pack->tail = pack->head; datap = pack->data; do @@ -86,11 +87,20 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) grub_netbuff_put (pack,sizeof (*eth) + iph->len); break; + case 0x86DD: - grub_printf("Ipv6 not yet implemented.\n"); + grub_printf("!!!!!!!!!!!!!!!!!IPV6 packet received!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + grub_ieee1275_read (handle,datap,sizeof (*ip6h),&actual); + ip6h = (struct ip6hdr *) datap; + grub_printf("ip6hdr->payload_len = %x\n",ip6h->payload_len); + grub_printf("ip6hdr->nexthdr = %x\n",ip6h->nexthdr); + + datap += sizeof(*ip6h); + grub_ieee1275_read (handle,datap,ip6h->payload_len - sizeof (*ip6h),&actual); break; + default: - grub_printf("Unknow packet %x\n",eth->type); + grub_printf("Unknow packet %x\n",eth->type); break; } // grub_printf("packsize %d\n",pack->tail - pack->data); From 3ec6213b179b3b82611e4caa35dae37a16fd2045 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Tue, 29 Jun 2010 06:50:15 -0300 Subject: [PATCH 0034/1414] Clean Debug messages --- fs/ieee1275/ofnet.c | 75 ++++++++++--------------------------- include/grub/net/type_net.h | 1 + net/ethernet.c | 6 +++ net/ieee1275/interface.c | 16 -------- net/ip.c | 7 ++++ net/netbuff.c | 7 +--- net/tftp.c | 6 ++- net/udp.c | 8 +++- 8 files changed, 46 insertions(+), 80 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 3bbb5c227..a9d16e7e0 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -56,7 +56,7 @@ grub_ofnet_open (const char *name, grub_disk_t disk) { - if (grub_strcmp (name, "network")) + if (grub_strcmp (name, "net")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); disk->total_sectors = U64MAXSIZE; @@ -109,7 +109,7 @@ grub_ofnetfs_dir (grub_device_t device , int (*hook) (const char *filename, const struct grub_dirhook_info *info) __attribute((unused))) { - if(grub_strcmp (device->disk->name,"network")) + if(grub_strcmp (device->disk->name,"net")) { return grub_error (GRUB_ERR_BAD_FS, "not an net filesystem"); } @@ -140,7 +140,7 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) //grub_addr_t addr; if (name[0] == '/') name++; - if(grub_strcmp (file->device->disk->name,"network")) + if(grub_strcmp (file->device->disk->name,"net")) { return 1; @@ -161,80 +161,43 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) grub_netbuff_reserve (pack,80*1024); file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); - for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) { -// grub_printf("trying to claim %d bytes at 0x%x\n",file_size,found_addr); if (grub_claimmap (found_addr , file_size) != -1) break; } -// grub_printf("Claimed %d bytes at 0x%x\n",file_size,found_addr); file->data = (void *) found_addr; -// grub_printf("file->data = 0x%x\n",(int)file->data); -// grub_printf("file_size = %d\n",file_size); -// grub_printf("OPEN\n"); + grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->open (NULL,stack,pack,(char *) name); - do { - //if (app_interface->app_prot->recv (NULL,stack,pack) == GRUB_ERR_NONE) -// grub_printf("RECEIVE PACKET\n"); + do + { grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->recv (NULL,stack,pack); if (grub_errno != GRUB_ERR_NONE) - return grub_errno; -// grub_printf("RECEIVED PACKET\n"); - // { -// grub_printf("payload_size= %d\n",pack->tail - pack->data); -// grub_printf("amount= %d\n",amount); -// grub_printf("file_size= %d\n",file_size); - datap = (char *)file->data + amount; - amount += (pack->tail - pack->data); -// grub_printf("datap = 0x%x\n",(int)datap ); - grub_memcpy(datap, pack->data, pack->tail - pack->data); -// grub_printf("SEND ACK\n"); - + goto error; + if ((pack->tail - pack->data)) + { + // file->data = grub_realloc(file->data,amount + pack->tail - pack->data); + datap = (char *)file->data + amount; + amount += (pack->tail - pack->data); + grub_memcpy(datap , pack->data, pack->tail - pack->data); + } grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->send_ack (NULL,stack,pack); if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - -// grub_printf("SENT ACK\n"); - //} - // file->data = grub_realloc(file->data,amount); + goto error; }while (amount < file_size); -// grub_printf("transfer complete\n"); - file->size = file_size; - -// grub_netbuff_free(pack); - /*Start ARP header*/ - // arp.arpr.hwtype = 0x1; /* hardware type (must be ARPHRD_ETHER) */ - // arp.arpr.protocol = 0x0800; /* protocol type (must be ETH_P_IP) */ - // arp.arpr.hwlen = 0x6; /* hardware address length (must be 6) */ - // arp.arpr.protolen = 0x4; /* protocol address length (must be 4) */ - // arp.arpr.opcode = 0x1; /* ARP opcode */ - - - /*arp.arpr.shwaddr[0] =0x0a ; - arp.arpr.shwaddr[1] =0x11 ; - arp.arpr.shwaddr[2] =0xbd ; - arp.arpr.shwaddr[3] =0xe3 ; - arp.arpr.shwaddr[4] =0xe3 ; - arp.arpr.shwaddr[5] =0x04 ; - arp.arpr.sipaddr = dhcp_pckt -> yiaddr; */ /* sender's IP address */ - /*arp.arpr.thwaddr[0] =0; - arp.arpr.thwaddr[1] =0; - arp.arpr.thwaddr[2] =0; - arp.arpr.thwaddr[3] =0; - arp.arpr.thwaddr[4] =0; - arp.arpr.thwaddr[5] =0; - arp.arpr.tipaddr = dhcp_pckt -> siaddr; */ /* target's IP address */ - /*END ARP header */ + file->size = file_size; + + error: + grub_netbuff_free(pack); return grub_errno; } diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h index 276c50bf9..a1717d6a7 100644 --- a/include/grub/net/type_net.h +++ b/include/grub/net/type_net.h @@ -5,6 +5,7 @@ #define UDP_PCKT 0x11 #define IP_PCKT 0x0800 +#define TIMEOUT_TIME_MS 3*1000 typedef enum { GRUB_NET_TFTP_ID, diff --git a/net/ethernet.c b/net/ethernet.c index a4bdbff5b..2bcb8107d 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -7,6 +7,7 @@ #include #include #include +#include static grub_err_t send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), @@ -42,6 +43,8 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) { struct etherhdr *eth; + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); while (1) { get_card_packet (nb); @@ -59,6 +62,9 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ grub_netbuff_pull(nb,sizeof(*eth)); return 0; } + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } /* - get ethernet header - verify if the next layer is the desired one. diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index 1100ee85d..be9810fb2 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -29,9 +29,7 @@ int send_card_buffer (struct grub_net_buff *pack) { int actual; - //grub_printf("packet size transmited: %d\n",pack->tail - pack->data); grub_ieee1275_write (handle,pack->data,pack->tail - pack->data,&actual); -// grub_printf("actual transmited %d\n",actual); return actual; } @@ -50,18 +48,11 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) do { grub_ieee1275_read (handle,datap,sizeof (*eth),&actual); - // if (actual <= 0) - // grub_millisleep(10); }while (actual <= 0); eth = (struct etherhdr *) datap; datap += sizeof(*eth); - // grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], - // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); - // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], - // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); -// grub_printf ("eth.type 0x%x\n",eth->type); switch (eth->type) { @@ -77,10 +68,6 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) iph = (struct iphdr *) datap; datap += sizeof(*iph); - // grub_printf("ip.src 0x%x\n",iph->src); - // grub_printf("ip.dst 0x%x\n",iph->dest); - // grub_printf("ip.len 0x%x\n",iph->len); - // grub_printf("ip.protocol 0x%x\n",iph->protocol); grub_ieee1275_read (handle,datap,iph->len - sizeof (*iph),&actual); @@ -89,11 +76,8 @@ int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) break; case 0x86DD: - grub_printf("!!!!!!!!!!!!!!!!!IPV6 packet received!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); grub_ieee1275_read (handle,datap,sizeof (*ip6h),&actual); ip6h = (struct ip6hdr *) datap; - grub_printf("ip6hdr->payload_len = %x\n",ip6h->payload_len); - grub_printf("ip6hdr->nexthdr = %x\n",ip6h->nexthdr); datap += sizeof(*ip6h); grub_ieee1275_read (handle,datap,ip6h->payload_len - sizeof (*ip6h),&actual); diff --git a/net/ip.c b/net/ip.c index 5eaa74f90..044cfde6b 100644 --- a/net/ip.c +++ b/net/ip.c @@ -7,6 +7,7 @@ #include #include #include +#include struct grub_net_protocol *grub_ipv4_prot; @@ -65,6 +66,8 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, { struct iphdr *iph; + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); while (1) { trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); @@ -74,6 +77,10 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, grub_netbuff_pull(nb,sizeof(*iph)); return 0; } + + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } /* grub_printf("ip.src 0x%x\n",iph->src); grub_printf("ip.dst 0x%x\n",iph->dest); diff --git a/net/netbuff.c b/net/netbuff.c index 136d55bc4..ce52233b6 100644 --- a/net/netbuff.c +++ b/net/netbuff.c @@ -41,11 +41,6 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) { net_buff->data -= len; -/* grub_printf("push len =%d\n",len); - grub_printf("pack->head =%x\n",(unsigned int)net_buff->head); - grub_printf("pack->data =%x\n",(unsigned int)net_buff->data); - grub_printf("pack->tail =%x\n",(unsigned int)net_buff->tail); - grub_printf("pack->end =%x\n",(unsigned int)net_buff->end);*/ if (net_buff->data < net_buff->head) return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range."); return GRUB_ERR_NONE; @@ -87,7 +82,7 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff) { - grub_free (net_buff); + grub_free (net_buff->head); return 0; } diff --git a/net/tftp.c b/net/tftp.c index 8e89ed1f4..dff0f134c 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -70,7 +70,7 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), grub_netbuff_push (nb,sizeof (*tftph)); udp_interf = (struct udp_interf *) app_interface->data; - udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; + udp_interf->src = TFTP_CLIENT_PORT;// + rrq_count++; udp_interf->dst = TFTP_SERVER_PORT; tftph = (struct tftphdr *) nb->data; @@ -112,6 +112,8 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), app_interface->trans_prot->send (inf,protstack->interface,nb); /*Receive OACK*/ + grub_netbuff_clear (nb); + grub_netbuff_reserve (nb,80*1024); return app_interface->app_prot->recv(inf,protstack,nb); } @@ -211,6 +213,8 @@ static int tftp_file_size (struct grub_net_network_layer_interface* inf , { tftp_open (inf, protocol_stack,nb, filename); + grub_netbuff_clear (nb); + grub_netbuff_reserve (nb,80*1024); tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0); return tftp_file.size; diff --git a/net/udp.c b/net/udp.c index fb81aef93..0321fd58a 100644 --- a/net/udp.c +++ b/net/udp.c @@ -4,6 +4,7 @@ #include #include #include +#include static grub_err_t send_udp_packet (struct grub_net_network_layer_interface *inf, @@ -35,7 +36,8 @@ receive_udp_packet (struct grub_net_network_layer_interface *inf, struct udphdr *udph; struct udp_interf *udp_interf; udp_interf = (struct udp_interf *) app_trans_inf->data; - + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); while(1) { app_trans_inf->inner_layer->net_prot->recv(inf,app_trans_inf->inner_layer,nb); @@ -62,6 +64,10 @@ receive_udp_packet (struct grub_net_network_layer_interface *inf, return 0; } + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + return grub_error (GRUB_ERR_TIMEOUT, "Time out."); + } } From f8795693f1c3caa557b8658ac3d8661b1f84b739 Mon Sep 17 00:00:00 2001 From: Paulo de Rezende Pinatti Date: Tue, 13 Jul 2010 11:22:35 -0300 Subject: [PATCH 0035/1414] Added support to netdisk specified in the form (net,protocol,server_ip,username,password) an to list its information with command ls. * fs/ieee1275/ofnet.c (grub_ofnet_open): parse parameters to determine netdisk data * fs/ieee1275/ofnet.c (grub_ofnet_close): dealloc netdisk data * include/grub/disk.h: added struct grub_netdisk_data * include/grub/ieee1275/ofnet.h: added newline * kern/disk.c (grub_disk_open): ignore partition check for netdisk * normal/misc.c (grub_normal_print_device_info): added support to list netdisk information --- fs/ieee1275/ofnet.c | 159 ++++++++++++++++++++++++++++++++-- include/grub/disk.h | 17 ++++ include/grub/ieee1275/ofnet.h | 1 + kern/disk.c | 4 +- normal/misc.c | 39 +++++++++ 5 files changed, 213 insertions(+), 7 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index a9d16e7e0..9010317ba 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -42,6 +42,85 @@ //static grub_ieee1275_ihandle_t handle = 0; +static const char * +find_sep (const char *name) +{ + const char *p = name; + char c = *p; + + if (c == '\0') + return NULL; + + do + { + if (c == '\\' && *p == ',') + p++; + else if (c == ',') + return p - 1; + } while ((c = *p++) != '\0'); + return p - 1; +} + +static grub_err_t +retrieve_field(const char *src, char **field, const char **rest) +{ + const char *p; + grub_size_t len; + + p = find_sep(src); + if (! p) + { + *field = NULL; + *rest = src; + return 0; + } + + len = p - src; + *field = grub_malloc (len + 1); + if (! *field) + { + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + } + + grub_memcpy (*field, src, len); + (*field)[len] = '\0'; + + if (*p == '\0') + *rest = p; + else + *rest = p + 1; + return 0; +} + +static grub_err_t +parse_ip (const char *val, grub_uint32_t *ip, const char **rest) +{ + grub_uint32_t newip = 0; + unsigned long t; + int i; + const char *ptr = val; + + for (i = 0; i < 4; i++) + { + t = grub_strtoul (ptr, (char **) &ptr, 0); + if (grub_errno) + return grub_errno; + if (t & ~0xff) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + newip >>= 8; + newip |= (t << 24); + if (i != 3 && *ptr != '.') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + ptr++; + } + ptr = ptr - 1; + if ( *ptr != '\0' && *ptr != ',') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + *ip = newip; + if (rest) + *rest = ptr; + return 0; +} static int grub_ofnet_iterate (int (*hook) (const char *name)) @@ -54,23 +133,93 @@ grub_ofnet_iterate (int (*hook) (const char *name)) static grub_err_t grub_ofnet_open (const char *name, grub_disk_t disk) { - + grub_err_t err; + const char *p1, *p2; + char *user = NULL, *pwd = NULL; + grub_netdisk_data_t data; + grub_netdisk_protocol_t proto; + grub_uint32_t server_ip = 0; if (grub_strcmp (name, "net")) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); - disk->total_sectors = U64MAXSIZE; + p1 = find_sep(disk->name); + if (! p1 || *p1 == '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing"); + p1++; + + // parse protocol + p2 = find_sep(p1); + if (! p2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no protocol specified"); + if ((p2 - p1 == 4) && (! grub_strncasecmp(p1, "tftp", p2 - p1))) + proto = GRUB_NETDISK_PROTOCOL_TFTP; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid protocol specified"); + + // parse server ip + if ( *p2 == '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no server ip specified"); + p1 = p2 + 1; + err = parse_ip(p1, &server_ip, &p2); + if (err) + return err; + + // parse username (optional) + if ( *p2 == ',') + p2++; + err = retrieve_field(p2, &user, &p1); + if (err) + return err; + if (user) + { + // parse password (optional) + err = retrieve_field(p1, &pwd, &p2); + if (err) + { + grub_free(user); + return err; + } + } + + if (! disk->data) + { + data = grub_malloc (sizeof(*data)); + disk->data = data; + } + else + { + data = disk->data; + if (data->username) + grub_free(data->username); + if (data->password) + grub_free(data->password); + } + data->protocol = proto; + data->server_ip = server_ip; + data->username = user; + data->password = pwd; + + disk->total_sectors = 0; disk->id = (unsigned long) "net"; disk->has_partitions = 0; - disk->data = 0; return GRUB_ERR_NONE; } static void -grub_ofnet_close (grub_disk_t disk __attribute((unused))) +grub_ofnet_close (grub_disk_t disk) { + grub_netdisk_data_t data = disk->data; + if (data) + { + if (data->username) + grub_free(data->username); + if (data->password) + grub_free(data->password); + grub_free(data); + } } static grub_err_t diff --git a/include/grub/disk.h b/include/grub/disk.h index 1bdfb639b..dc8bc5018 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -119,6 +119,23 @@ struct grub_disk }; typedef struct grub_disk *grub_disk_t; +/* Net Disk */ +enum grub_netdisk_protocol +{ + GRUB_NETDISK_PROTOCOL_TFTP +}; +typedef enum grub_netdisk_protocol grub_netdisk_protocol_t; + +struct grub_netdisk_data +{ + grub_netdisk_protocol_t protocol; + grub_uint32_t server_ip; + grub_uint32_t port; + char *username; + char *password; +}; +typedef struct grub_netdisk_data *grub_netdisk_data_t; + #ifdef GRUB_UTIL struct grub_disk_memberlist { diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h index 7daadf61d..a26c22235 100644 --- a/include/grub/ieee1275/ofnet.h +++ b/include/grub/ieee1275/ofnet.h @@ -25,6 +25,7 @@ extern void grub_ofnet_init(void); extern void grub_ofnet_fini(void); + /* struct grub_net; diff --git a/kern/disk.c b/kern/disk.c index ccd5f200f..051e59aca 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -281,7 +281,7 @@ grub_disk_open (const char *name) goto fail; } - if (p && ! disk->has_partitions) + if (p && ! disk->has_partitions && grub_strcmp (raw, "net")) { grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk"); goto fail; @@ -289,7 +289,7 @@ grub_disk_open (const char *name) disk->dev = dev; - if (p) + if (p && grub_strcmp (raw, "net")) { disk->partition = grub_partition_probe (disk, p + 1); if (! disk->partition) diff --git a/normal/misc.c b/normal/misc.c index 17ba372ce..d53fe711c 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -32,8 +32,47 @@ grub_err_t grub_normal_print_device_info (const char *name) { grub_device_t dev; + grub_netdisk_data_t data; char *p; + if ((! grub_strcmp(name, "net")) || (! grub_strncmp(name, "net,", 4))) + { + grub_printf_ (N_("Device network:")); + grub_putchar (' '); + + dev = grub_device_open (name); + if (! dev || ! dev->disk || ! dev->disk->data) + grub_printf ("%s", _("Network information not available")); + else + { + data = dev->disk->data; + grub_putchar ('\n'); + grub_putchar ('\t'); + if (data->protocol == GRUB_NETDISK_PROTOCOL_TFTP) + grub_printf_(N_("Protocol: %s"), "TFTP"); + else + grub_printf_(N_("Protocol: %s"), "Unknown"); + grub_putchar ('\n'); + grub_putchar ('\t'); + grub_printf_(N_("Server IP: %d.%d.%d.%d"), data->server_ip & 0xff, data->server_ip >> 8 & 0xff, data->server_ip >> 16 & 0xff, data->server_ip >> 24 & 0xff); + if (data->username) + { + grub_putchar ('\n'); + grub_putchar ('\t'); + grub_printf_(N_("Username: %s"), data->username); + if (data->password) + { + grub_putchar ('\n'); + grub_putchar ('\t'); + grub_printf_(N_("Password: %s"), data->password); + } + } + } + grub_putchar ('\n'); + + return GRUB_ERR_NONE; + } + p = grub_strchr (name, ','); if (p) { From 7e8b77c03359b2537dee39ded103b2f126157dd8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 19 Jul 2010 21:22:54 +0200 Subject: [PATCH 0036/1414] AHCI skeleton --- conf/i386.rmk | 5 + disk/ahci.c | 311 ++++++++++++++++++++++++++++++++++++++++++++ include/grub/scsi.h | 3 +- 3 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 disk/ahci.c diff --git a/conf/i386.rmk b/conf/i386.rmk index b1df584a6..54edb468b 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -36,6 +36,11 @@ ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += ahci.mod +ahci_mod_SOURCES = disk/ahci.c +ahci_mod_CFLAGS = $(COMMON_CFLAGS) +ahci_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For setpci.mod pkglib_MODULES += setpci.mod setpci_mod_SOURCES = commands/setpci.c diff --git a/disk/ahci.c b/disk/ahci.c new file mode 100644 index 000000000..1372fd651 --- /dev/null +++ b/disk/ahci.c @@ -0,0 +1,311 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_ahci_cmd_head +{ + grub_uint32_t unused[8]; +}; + +struct grub_ahci_hba_port +{ + grub_uint64_t command_list_base; + grub_uint32_t unused[12]; + grub_uint32_t sata_active; + grub_uint32_t command_issue; + grub_uint32_t unused[16]; +}; + +struct grub_ahci_hba +{ + grub_uint32_t cap; +#define GRUB_AHCI_HBA_CAP_MASK 0x1f + grub_uint32_t global_control; +#define GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN 0x80000000 + grub_uint32_t ports_implemented; + grub_uint32_t unused1[7]; + grub_uint32_t bios_handoff; +#define GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED 1 +#define GRUB_AHCI_BIOS_HANDOFF_OS_OWNED 2 +#define GRUB_AHCI_BIOS_HANDOFF_OS_OWNERSHIP_CHANGED 8 +#define GRUB_AHCI_BIOS_HANDOFF_RWC 8 + grub_uint32_t unused2[53]; + struct grub_ahci_hba_port ports[32]; +}; + +struct grub_ahci_device +{ + struct grub_ahci_device *next; + volatile struct grub_ahci_hba *hba; + int port; + int num; + struct grub_pci_dma_chunk *command_list_chunk; + volatile struct grub_ahci_cmd_head *command_list; +}; + +static struct grub_ahci_device *grub_ahci_devices; +static int numdevs; + +static int NESTED_FUNC_ATTR +grub_ahci_pciinit (grub_pci_device_t dev, + grub_pci_id_t pciid __attribute__ ((unused))) +{ + grub_pci_address_t addr; + grub_uint32_t class; + grub_uint32_t bar; + int nports; + volatile struct grub_ahci_hba *hba; + + /* Read class. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + /* Check if this class ID matches that of a PCI IDE Controller. */ + if (class >> 8 != 0x010601) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG5); + bar = grub_pci_read (addr); + + if (bar & (GRUB_PCI_ADDR_SPACE_MASK | GRUB_PCI_ADDR_MEM_TYPE_MASK + | GRUB_PCI_ADDR_MEM_PREFETCH) + != (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32)) + return 0; + + hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK, + sizeof (hba)); + + hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; + + nports = hba->cap & GRUB_AHCI_HBA_CAP_MASK; + + if (! (hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_OS_OWNED)) + { + grub_uint64_t endtime; + + grub_dprintf ("ahci", "Requesting AHCI ownership\n"); + hba->bios_handoff = (hba->bios_handoff & ~GRUB_AHCI_BIOS_HANDOFF_RWC) + | GRUB_AHCI_BIOS_HANDOFF_OS_OWNED; + grub_dprintf ("ahci", "Waiting for BIOS to give up ownership\n"); + endtime = grub_get_time_ms () + 1000; + while ((hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED) + && grub_get_time_ms () < endtime); + if (hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED) + { + grub_dprintf ("ahci", "Forcibly taking ownership\n"); + hba->bios_handoff = GRUB_AHCI_BIOS_HANDOFF_OS_OWNED; + hba->bios_handoff |= GRUB_AHCI_BIOS_HANDOFF_OS_OWNERSHIP_CHANGED; + } + else + grub_dprintf ("ahci", "AHCI ownership obtained\n"); + } + else + grub_dprintf ("ahci", "AHCI is already in OS mode\n"); + + for (i = 0; i < nports; i++) + { + struct grub_ahci_device *adev; + struct grub_pci_dma_chunk *command_list; + + if (!(hba->ports_implemented & (1 << i))) + continue; + + command_list = grub_memalign_dma32 (1024, + sizeof (struct grub_ahci_cmd_head)); + if (!command_list) + return 1; + + adev = grub_malloc (sizeof (*adev)); + if (!adev) + { + grub_dma_free (command_list); + return 1; + } + + adev->hba = hba; + adev->port = i; + adev->num = numdevs++; + adev->command_list_chunk = command_list; + adev->command_list = grub_dma_get_virt (command_list); + adev->hba->ports[i].command_list_base = grub_dma_get_phys (command_list); + grub_list_push (GRUB_AS_LIST_P (&grub_ahci_devices), + GRUB_AS_LIST (adev)); + } + + return 0; +} + +static grub_err_t +grub_ahci_initialize (void) +{ + grub_pci_iterate (grub_ahci_pciinit); + return grub_errno; +} + + + + +static int +grub_ahci_iterate (int (*hook) (int bus, int luns)) +{ + struct grub_ahci_device *dev; + + FOR_LIST_ELEMENTS(dev, grub_ahci_devices) + if (hook (dev->num, 1)) + return 1; + + return 0; +} + +#if 0 +static int +find_free_cmd_slot (struct grub_ahci_device *dev) +{ + int i; + for (i = 0; i < 32; i++) + { + if (dev->hda->ports[dev->port].command_issue & (1 << i)) + continue; + if (dev->hda->ports[dev->port].sata_active & (1 << i)) + continue; + return i; + } + return -1; +} +#endif + +static grub_err_t +grub_ahci_packet (struct grub_ahci_device *dev, char *packet, + grub_size_t size) +{ + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ahci_read (struct grub_scsi *scsi, + grub_size_t cmdsize __attribute__((unused)), + char *cmd, grub_size_t size, char *buf) +{ + struct grub_ahci_device *dev = (struct grub_ahci_device *) scsi->data; + + grub_dprintf("ahci", "grub_ahci_read (size=%llu)\n", (unsigned long long) size); + + if (grub_atapi_packet (dev, cmd, size)) + return grub_errno; + + grub_size_t nread = 0; + while (nread < size) + { + /* Wait for !BSY, DRQ, I/O, !C/D. */ + if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + /* Get byte count for this DRQ assertion. */ + unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 + | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW); + grub_dprintf("ata", "DRQ count=%u\n", cnt); + + /* Count of last transfer may be uneven. */ + if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread))) + return grub_error (GRUB_ERR_READ_ERROR, "invalid ATAPI transfer count"); + + /* Read the data. */ + grub_ata_pio_read (dev, buf + nread, cnt); + + if (cnt & 1) + buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA)); + + nread += cnt; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ahci_write (struct grub_scsi *scsi __attribute__((unused)), + grub_size_t cmdsize __attribute__((unused)), + char *cmd __attribute__((unused)), + grub_size_t size __attribute__((unused)), + char *buf __attribute__((unused))) +{ + // XXX: scsi.mod does not use write yet. + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "AHCI write not implemented"); +} + +static grub_err_t +grub_ahci_open (int devnum, struct grub_scsi *scsi) +{ + struct grub_ahci_device *dev; + + FOR_LIST_ELEMENTS(dev, grub_ahci_devices) + { + if (dev->num == devnum) + break; + } + + grub_dprintf ("ata", "opening AHCI dev `ahci%d'\n", devnum); + + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such AHCI device"); + + scsi->data = dev; + + return GRUB_ERR_NONE; +} + + +static struct grub_scsi_dev grub_ahci_dev = + { + .name = "ahci", + .id = GRUB_SCSI_SUBSYSTEM_AHCI, + .iterate = grub_ahci_iterate, + .open = grub_ahci_open, + .read = grub_ahci_read, + .write = grub_ahci_write + }; + + + +GRUB_MOD_INIT(ahci) +{ + /* To prevent two drivers operating on the same disks. */ + grub_disk_firmware_is_tainted = 1; + if (grub_disk_firmware_fini) + { + grub_disk_firmware_fini (); + grub_disk_firmware_fini = NULL; + } + + /* AHCI initialization. */ + grub_ahci_initialize (); + + /* AHCI devices are handled by scsi.mod. */ + grub_scsi_dev_register (&grub_ahci_dev); +} + +GRUB_MOD_FINI(ahci) +{ + grub_scsi_dev_unregister (&grub_ahci_dev); +} diff --git a/include/grub/scsi.h b/include/grub/scsi.h index b3c60f3e8..289cd8e4a 100644 --- a/include/grub/scsi.h +++ b/include/grub/scsi.h @@ -29,7 +29,8 @@ struct grub_scsi; enum { GRUB_SCSI_SUBSYSTEM_USBMS, - GRUB_SCSI_SUBSYSTEM_ATAPI + GRUB_SCSI_SUBSYSTEM_ATAPI, + GRUB_SCSI_SUBSYSTEM_AHCI }; #define GRUB_SCSI_ID_SUBSYSTEM_SHIFT 24 From 818a356eb196a2c2ca5af7d580b9920c8564ebcc Mon Sep 17 00:00:00 2001 From: Paulo de Rezende Pinatti Date: Thu, 29 Jul 2010 16:36:17 -0300 Subject: [PATCH 0037/1414] Fixed get_card_packet to correctly read data from network card into buffer. * net/ieee1275/interface.c (get_card_packet): read data regardless of ethernet header --- net/ieee1275/interface.c | 54 +++------------------------------------- 1 file changed, 4 insertions(+), 50 deletions(-) diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c index be9810fb2..342044041 100644 --- a/net/ieee1275/interface.c +++ b/net/ieee1275/interface.c @@ -1,9 +1,4 @@ #include -#include -#include -#include -#include -#include #include #include @@ -37,56 +32,15 @@ int send_card_buffer (struct grub_net_buff *pack) int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) { - int actual; - char *datap; - struct iphdr *iph; - struct etherhdr *eth; - struct arphdr *arph; - struct ip6hdr *ip6h; + int actual, rc; pack->data = pack->tail = pack->head; - datap = pack->data; do { - grub_ieee1275_read (handle,datap,sizeof (*eth),&actual); + rc = grub_ieee1275_read (handle,pack->data,1500,&actual); - }while (actual <= 0); - eth = (struct etherhdr *) datap; - datap += sizeof(*eth); - + }while (actual <= 0 || rc < 0); + grub_netbuff_put (pack, actual); - switch (eth->type) - { - case 0x806: - - grub_ieee1275_read (handle,datap,sizeof (*arph),&actual); - arph = (struct arphdr *) datap; - - grub_netbuff_put (pack,sizeof (*eth) + sizeof (*arph)); - break; - case 0x800: - grub_ieee1275_read (handle,datap,sizeof (*iph),&actual); - iph = (struct iphdr *) datap; - datap += sizeof(*iph); - - - grub_ieee1275_read (handle,datap,iph->len - sizeof (*iph),&actual); - - - grub_netbuff_put (pack,sizeof (*eth) + iph->len); - break; - - case 0x86DD: - grub_ieee1275_read (handle,datap,sizeof (*ip6h),&actual); - ip6h = (struct ip6hdr *) datap; - - datap += sizeof(*ip6h); - grub_ieee1275_read (handle,datap,ip6h->payload_len - sizeof (*ip6h),&actual); - break; - - default: - grub_printf("Unknow packet %x\n",eth->type); - break; - } // grub_printf("packsize %d\n",pack->tail - pack->data); return 0;// sizeof (eth) + iph.len; } From 11d1ea5df607d8d2e6463f482f24e92c9cb609be Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 17:52:54 -0300 Subject: [PATCH 0038/1414] Use server and client IP from the bootp packet. --- net/ip.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/ip.c b/net/ip.c index 044cfde6b..65b0f2b70 100644 --- a/net/ip.c +++ b/net/ip.c @@ -72,7 +72,9 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, { trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); iph = (struct iphdr *) nb->data; - if (iph->dest == 0x0908eaaa && iph->src == 0x0908ea92 && iph->protocol == 0x11) + if (iph->protocol == 0x11 && + iph->dest == (grub_uint32_t) bootp_pckt -> yiaddr && + iph->src == (grub_uint32_t) bootp_pckt -> siaddr ) { grub_netbuff_pull(nb,sizeof(*iph)); return 0; @@ -82,11 +84,11 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, if (current_time - start_time > TIMEOUT_TIME_MS) return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } -/* grub_printf("ip.src 0x%x\n",iph->src); - grub_printf("ip.dst 0x%x\n",iph->dest); - grub_printf("ip.len 0x%x\n",iph->len); - grub_printf("ip.protocol 0x%x\n",iph->protocol); - */ +// grub_printf("ip.src 0x%x\n",iph->src); +// grub_printf("ip.dst 0x%x\n",iph->dest); +// grub_printf("ip.len 0x%x\n",iph->len); +// grub_printf("ip.protocol 0x%x\n",iph->protocol); + /* - get ip header - verify if is the next layer is correct -*/ From f89661762a82b0784965ca27d88473e704648cf2 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 18:07:09 -0300 Subject: [PATCH 0039/1414] Only open the card in netboot. --- fs/ieee1275/ofnet.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 9010317ba..82b5235cc 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -141,6 +141,7 @@ grub_ofnet_open (const char *name, grub_disk_t disk) grub_uint32_t server_ip = 0; if (grub_strcmp (name, "net")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a net disk"); p1 = find_sep(disk->name); @@ -258,7 +259,7 @@ grub_ofnetfs_dir (grub_device_t device , int (*hook) (const char *filename, const struct grub_dirhook_info *info) __attribute((unused))) { - if(grub_strcmp (device->disk->name,"net")) + if(grub_strncmp (device->disk->name,"net",3)) { return grub_error (GRUB_ERR_BAD_FS, "not an net filesystem"); } @@ -287,9 +288,10 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) { //void *buffer; //grub_addr_t addr; + if (name[0] == '/') name++; - if(grub_strcmp (file->device->disk->name,"net")) + if(grub_strncmp (file->device->disk->name,"net",3)) { return 1; @@ -311,15 +313,17 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) - { - if (grub_claimmap (found_addr , file_size) != -1) - break; - } + { + if (grub_claimmap (found_addr , file_size) != -1) + break; + } file->data = (void *) found_addr; grub_netbuff_clear(pack); grub_netbuff_reserve (pack,80*1024); app_interface->app_prot->open (NULL,stack,pack,(char *) name); + if (grub_errno != GRUB_ERR_NONE) + goto error; do { @@ -401,7 +405,7 @@ grub_ofnet_detect (void) } devalias = grub_ieee1275_get_aliasdevname (bootpath); - if (grub_strcmp(devalias ,"network")) + if (grub_strncmp(devalias ,"net",3)) return 0; grub_net = grub_malloc (sizeof *grub_net ); @@ -455,8 +459,8 @@ grub_ofnet_init(void) grub_get_netinfo (grub_net, bootp_pckt ); grub_disk_dev_register (&grub_ofnet_dev); grub_fs_register (&grub_ofnetfs_fs); + card_open (); } - card_open (); } void grub_ofnet_fini(void) From 17ef14c91669b1c7a8c32f106148c142a488a9c4 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 18:13:00 -0300 Subject: [PATCH 0040/1414] Process errot packets in TFTP reply. --- net/tftp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index dff0f134c..0fb43105d 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -140,7 +140,7 @@ tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)) } //buff_clean - nb->data = nb->tail; + grub_netbuff_clear(nb); // grub_printf("OACK---------------------------------------------------------\n"); //grub_printf("block_size=%d\n",tftp_file.block_size); // grub_printf("file_size=%d\n",tftp_file.size); @@ -155,7 +155,8 @@ tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)) grub_netbuff_clear(nb); break; case TFTP_ERROR: - nb->data = nb->tail; + grub_netbuff_clear (nb); + return grub_error (GRUB_ERR_ACCESS_DENIED, (char *)tftph->u.err.errmsg); break; } From 7c978f06900fc81e185bc0c8977f935c0185927c Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 29 Jul 2010 18:17:01 -0300 Subject: [PATCH 0041/1414] Implement the size field. --- include/grub/net/ethernet.h | 24 ++++++++++++-- net/ethernet.c | 65 ++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 46aa04f60..9043a5f02 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -1,11 +1,31 @@ #ifndef GRUB_NET_ETHERNET_HEADER #define GRUB_NET_ETHERNET_HEADER 1 #include -struct etherhdr { +#define LLCADDRMASK 0x7f + +struct etherhdr +{ grub_uint8_t dst[6]; grub_uint8_t src[6]; grub_uint16_t type; -} __attribute__ ((packed)) ; +} __attribute__ ((packed)); + +#define PCP (x) x & 0xe000 +#define CFI (x) x & 0x1000 +#define VID (x) x & 0x0fff + +struct llchdr +{ +grub_uint8_t dsap; +grub_uint8_t ssap; +grub_uint8_t ctrl; +} __attribute__ ((packed)); + +struct snaphdr +{ +grub_uint8_t oui[3]; +grub_uint16_t type; +} __attribute__ ((packed)); void ethernet_ini(void); void ethernet_fini(void); diff --git a/net/ethernet.c b/net/ethernet.c index 2bcb8107d..ab5992133 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -18,19 +18,13 @@ send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ grub_netbuff_push (nb,sizeof(*eth)); eth = (struct etherhdr *) nb->data; - eth->dst[0] =0x00; - eth->dst[1] =0x11; - eth->dst[2] =0x25; - eth->dst[3] =0xca; - eth->dst[4] =0x1f; - eth->dst[5] =0x01; - eth->src[0] =0x0a; - eth->src[1] =0x11; - eth->src[2] =0xbd; - eth->src[3] =0xe3; - eth->src[4] =0xe3; - eth->src[5] =0x04; - + eth->dst[0] = 0x00; + eth->dst[1] = 0x11; + eth->dst[2] = 0x25; + eth->dst[3] = 0xca; + eth->dst[4] = 0x1f; + eth->dst[5] = 0x01; + grub_memcpy (eth->src, bootp_pckt -> chaddr,6); eth->type = 0x0800; return send_card_buffer(nb); @@ -44,25 +38,38 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ { struct etherhdr *eth; grub_uint64_t start_time, current_time; + struct llchdr *llch; + struct snaphdr *snaph; + grub_uint16_t type; start_time = grub_get_time_ms(); - while (1) - { - get_card_packet (nb); - eth = (struct etherhdr *) nb->data; + while (1) + { + get_card_packet (nb); + eth = (struct etherhdr *) nb->data; + type = eth->type; + grub_netbuff_pull(nb,sizeof (*eth)); + // grub_printf("ethernet type 58 %x\n",type); + // grub_printf("ethernet eth->type 58 %x\n",type); + if (eth->type <=1500) + { + llch = (struct llchdr *) nb->data; + type = llch->dsap & LLCADDRMASK; + + if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3) + { + grub_netbuff_pull (nb,sizeof(*llch)); + snaph = (struct snaphdr *) nb->data; + type = snaph->type; + } + } + /*change for grub_memcmp*/ - if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && - eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && eth->type == 0x800) - { - //grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0], - // eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]); - // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1], - // eth->src[2],eth->src[3],eth->src[4],eth->src[5]); - //grub_printf("ethernet eth->type 0x%x\n",eth->type); - //grub_printf("out from ethernet\n"); - grub_netbuff_pull(nb,sizeof(*eth)); + //if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && + // eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && type == 0x800) + if(type == 0x800) return 0; - } - current_time = grub_get_time_ms(); + + current_time = grub_get_time_ms (); if (current_time - start_time > TIMEOUT_TIME_MS) return grub_error (GRUB_ERR_TIMEOUT, "Time out."); } From 10830203a09d8afdb8f10ab322042bbcdecece16 Mon Sep 17 00:00:00 2001 From: Paulo de Rezende Pinatti Date: Fri, 13 Aug 2010 14:42:16 -0300 Subject: [PATCH 0042/1414] Added ARP protocol to network stack and fixed bug in grub_netbuff_alloc function. * include/grub/net/arp.h: added arp header, arp cache entry and related constants and functions * net/arp.c: added functions arp_init_table, arp_find_entry, arp_resolve and arp_receive * net/ethernet.c (send_ethernet_packet): replaced hardcoded hardware address by parameter target_addr * net/ethernet.c (recv_ethernet_packet): added call to arp_receive when packet is of type 0x803 (ARP) and only return when packet is of type determined by parameter ethertype * net/ip.c (send_ip_packet): added call to arp_resolve to determine hardware address of destination * net/netbuff.c (grub_netbuff_alloc): fixed swapped parameters in call to grub_memalign --- fs/ieee1275/ofnet.c | 48 +++++--- include/grub/net/arp.h | 49 +++++++-- include/grub/net/interface.h | 2 +- include/grub/net/ip.h | 1 + include/grub/net/protocol.h | 10 +- net/arp.c | 207 +++++++++++++++++++++++++++++++++++ net/ethernet.c | 38 ++++--- net/interface.c | 1 - net/ip.c | 27 ++++- net/netbuff.c | 2 +- net/tftp.c | 4 +- normal/misc.c | 2 +- 12 files changed, 335 insertions(+), 56 deletions(-) diff --git a/fs/ieee1275/ofnet.c b/fs/ieee1275/ofnet.c index 82b5235cc..cf7eeb5b2 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/ieee1275/ofnet.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -95,7 +96,7 @@ retrieve_field(const char *src, char **field, const char **rest) static grub_err_t parse_ip (const char *val, grub_uint32_t *ip, const char **rest) { - grub_uint32_t newip = 0; + grub_uint8_t *p = (grub_uint8_t *) ip; unsigned long t; int i; const char *ptr = val; @@ -107,8 +108,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) return grub_errno; if (t & ~0xff) return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); - newip >>= 8; - newip |= (t << 24); + p[i] = (grub_uint8_t) t; if (i != 3 && *ptr != '.') return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); ptr++; @@ -116,7 +116,6 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) ptr = ptr - 1; if ( *ptr != '\0' && *ptr != ',') return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); - *ip = newip; if (rest) *rest = ptr; return 0; @@ -305,12 +304,33 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) char *datap; int amount = 0; grub_addr_t found_addr; + grub_netdisk_data_t netdisk_data = (grub_netdisk_data_t) file->device->disk->data; + // TODO: replace getting IP and MAC from bootp by routing functions + struct grub_net_network_layer_interface net_interface; + struct grub_net_card net_card; + struct grub_net_addr ila, lla; + ila.addr = (grub_uint8_t *) &(bootp_pckt->yiaddr); + ila.len = 4; + lla.addr = (grub_uint8_t *) &(bootp_pckt->chaddr); + lla.len = 6; + net_card.ila = &ila; + net_card.lla = &lla; + net_interface.card = &net_card; + // END TODO + + if(! netdisk_data) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing"); + + if(netdisk_data->protocol == GRUB_NETDISK_PROTOCOL_TFTP) + stack = grub_net_protocol_stack_get ("tftp"); + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid protocol specified"); - stack = grub_net_protocol_stack_get ("tftp"); app_interface = (struct grub_net_application_transport_interface *) stack->interface; - pack = grub_netbuff_alloc (80*1024); - grub_netbuff_reserve (pack,80*1024); - file_size = app_interface->app_prot->get_file_size(NULL,stack,pack,(char *) name); + app_interface->inner_layer->data = (void *) &(netdisk_data->server_ip); + pack = grub_netbuff_alloc (2048); + grub_netbuff_reserve (pack,2048); + file_size = app_interface->app_prot->get_file_size(&net_interface,stack,pack,(char *) name); for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) { @@ -320,16 +340,16 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) file->data = (void *) found_addr; grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,80*1024); - app_interface->app_prot->open (NULL,stack,pack,(char *) name); + grub_netbuff_reserve (pack,2048); + app_interface->app_prot->open (&net_interface,stack,pack,(char *) name); if (grub_errno != GRUB_ERR_NONE) goto error; do { grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,80*1024); - app_interface->app_prot->recv (NULL,stack,pack); + grub_netbuff_reserve (pack,2048); + app_interface->app_prot->recv (&net_interface,stack,pack); if (grub_errno != GRUB_ERR_NONE) goto error; if ((pack->tail - pack->data)) @@ -340,8 +360,8 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) grub_memcpy(datap , pack->data, pack->tail - pack->data); } grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,80*1024); - app_interface->app_prot->send_ack (NULL,stack,pack); + grub_netbuff_reserve (pack,2048); + app_interface->app_prot->send_ack (&net_interface,stack,pack); if (grub_errno != GRUB_ERR_NONE) goto error; diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 86ae2deea..75260aeb3 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -1,17 +1,42 @@ #ifndef GRUB_NET_ARP_HEADER #define GRUB_NET_ARP_HEADER 1 +#include +#include +#include -#include -struct arphdr{ - grub_int16_t hwtype; /* hardware type (must be ARPHRD_ETHER) */ - grub_int16_t protocol; /* protocol type (must be ETH_P_IP) */ - grub_int8_t hwlen; /* hardware address length (must be 6) */ - grub_int8_t protolen; /* protocol address length (must be 4) */ - grub_uint16_t opcode; /* ARP opcode */ - grub_uint8_t shwaddr[6]; /* sender's hardware address */ - grub_uint32_t sipaddr; /* sender's IP address */ - grub_uint8_t thwaddr[6]; /* target's hardware address */ - grub_uint32_t tipaddr; /* target's IP address */ -}__attribute__ ((packed)); +/* IANA ARP constant to define hardware type as ethernet */ +#define ARPHRD_ETHERNET 1 +/* IANA Ethertype */ +#define ARP_ETHERTYPE 0x806 + +/* Size for cache table */ +#define SIZE_ARP_TABLE 5 + +/* ARP header operation codes */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +struct arp_entry { + grub_uint8_t avail; + struct grub_net_network_layer_protocol *nl_protocol; + struct grub_net_link_layer_protocol *ll_protocol; + struct grub_net_addr nl_address; + struct grub_net_addr ll_address; +}; + +struct arphdr { + grub_uint16_t hrd; + grub_uint16_t pro; + grub_uint8_t hln; + grub_uint8_t pln; + grub_uint16_t op; +} __attribute__ ((packed)); + +extern grub_err_t arp_receive(struct grub_net_network_layer_interface *inf __attribute__ ((unused)), +struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); + +extern grub_err_t arp_resolve(struct grub_net_network_layer_interface *inf __attribute__ ((unused)), +struct grub_net_network_link_interface *net_link_inf, struct grub_net_addr *proto_addr, +struct grub_net_addr *hw_addr); #endif diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h index 4d100fd75..cf24dd22e 100644 --- a/include/grub/net/interface.h +++ b/include/grub/net/interface.h @@ -37,7 +37,7 @@ struct grub_net_network_link_interface }; -extern struct grub_net_protocol_stack *grub_net_protocol_stacks; +struct grub_net_protocol_stack *grub_net_protocol_stacks; static inline void grub_net_stack_register (struct grub_net_protocol_stack *stack) { diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index cb119ac6f..5baacd439 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -2,6 +2,7 @@ #define GRUB_NET_IP_HEADER 1 #include +#define IP_ETHERTYPE 0x800 /* IANA Ethertype */ struct iphdr { grub_uint8_t verhdrlen; diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index b7a3e5d3b..ffc3dd719 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -8,7 +8,7 @@ struct grub_net_protocol; struct grub_net_protocol_stack; struct grub_net_network_layer_interface; - +struct grub_net_addr; typedef enum grub_network_layer_protocol_id { @@ -57,6 +57,7 @@ struct grub_net_network_layer_protocol struct grub_net_network_layer_protocol *next; char *name; grub_net_protocol_id_t id; + grub_uint16_t type; /* IANA Ethertype */ //grub_network_layer_protocol_id_t id; grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr); char * (*aton) (union grub_net_network_layer_address addr); @@ -76,11 +77,14 @@ struct grub_net_link_layer_protocol struct grub_net_link_layer_protocol *next; char *name; + grub_uint16_t type; /* ARP hardware type */ grub_net_protocol_id_t id; grub_err_t (*send) (struct grub_net_network_layer_interface *inf , - struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); + struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb, + struct grub_net_addr target_addr, grub_uint16_t ethertype); grub_err_t (*recv) (struct grub_net_network_layer_interface *inf , - struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb); + struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb, + grub_uint16_t ethertype); }; extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols; diff --git a/net/arp.c b/net/arp.c index e69de29bb..c02ea011d 100644 --- a/net/arp.c +++ b/net/arp.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct arp_entry arp_table[SIZE_ARP_TABLE]; +static grub_int8_t new_table_entry = -1; + +static void arp_init_table(void) +{ + struct arp_entry *entry = &(arp_table[0]); + for(;entry<=&(arp_table[SIZE_ARP_TABLE-1]);entry++) + { + entry->avail = 0; + entry->nl_protocol = NULL; + entry->ll_protocol = NULL; + entry->nl_address.addr = NULL; + entry->nl_address.len = 0; + entry->ll_address.addr = NULL; + entry->ll_address.len = 0; + } + new_table_entry = 0; +} + +static struct arp_entry * +arp_find_entry(struct grub_net_network_link_interface *net_link_inf, const void *proto_address, grub_uint8_t address_len) +{ + grub_uint8_t i; + for(i=0;i < SIZE_ARP_TABLE; i++) + { + if(arp_table[i].avail == 1 && + arp_table[i].nl_protocol->type == net_link_inf->net_prot->type && + arp_table[i].ll_protocol->type == net_link_inf->link_prot->type && + (!grub_memcmp(arp_table[i].nl_address.addr, proto_address, address_len))) + return &(arp_table[i]); + } + return NULL; +} + +grub_err_t arp_resolve(struct grub_net_network_layer_interface *inf __attribute__ ((unused)), +struct grub_net_network_link_interface *net_link_inf, struct grub_net_addr *proto_addr, +struct grub_net_addr *hw_addr) +{ + struct arp_entry *entry; + struct grub_net_buff *nb; + struct arphdr *arp_header; + struct grub_net_addr target_hw_addr; + grub_uint8_t *aux, i; + + /* Check cache table */ + entry = arp_find_entry(net_link_inf, proto_addr->addr, proto_addr->len); + if (entry) + { + hw_addr->addr = grub_malloc(entry->ll_address.len); + if (! hw_addr->addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(hw_addr->addr, entry->ll_address.addr, entry->ll_address.len); + hw_addr->len = entry->ll_address.len; + return GRUB_ERR_NONE; + } + /* Build a request packet */ + nb = grub_netbuff_alloc (2048); + grub_netbuff_reserve(nb, 2048); + grub_netbuff_push(nb, sizeof(*arp_header) + 2*(inf->card->lla->len + inf->card->ila->len)); + arp_header = (struct arphdr *)nb->data; + arp_header->hrd = net_link_inf->link_prot->type; + arp_header->pro = net_link_inf->net_prot->type; + arp_header->hln = inf->card->lla->len; + arp_header->pln = inf->card->ila->len; + arp_header->op = ARP_REQUEST; + aux = (grub_uint8_t *)arp_header + sizeof(*arp_header); + /* Sender hardware address */ + grub_memcpy(aux, inf->card->lla->addr, inf->card->lla->len); + aux += inf->card->lla->len; + /* Sender protocol address */ + grub_memcpy(aux, inf->card->ila->addr, inf->card->ila->len); + aux += inf->card->ila->len; + /* Target hardware address */ + for(i=0; i < inf->card->lla->len; i++) + aux[i] = 0x00; + aux += inf->card->lla->len; + /* Target protocol address */ + grub_memcpy(aux, proto_addr->addr, inf->card->ila->len); + + target_hw_addr.addr = grub_malloc(inf->card->lla->len); + target_hw_addr.len = inf->card->lla->len; + for(i=0; i < target_hw_addr.len; i++) + (target_hw_addr.addr)[i] = 0xFF; + net_link_inf->link_prot->send(inf, net_link_inf, nb, target_hw_addr, ARP_ETHERTYPE); + grub_free(target_hw_addr.addr); + grub_netbuff_clear(nb); + grub_netbuff_reserve(nb, 2048); + + grub_uint64_t start_time, current_time; + start_time = grub_get_time_ms(); + do + { + net_link_inf->link_prot->recv(inf, net_link_inf, nb, ARP_ETHERTYPE); + /* Now check cache table again */ + entry = arp_find_entry(net_link_inf, proto_addr->addr, proto_addr->len); + if (entry) + { + hw_addr->addr = grub_malloc(entry->ll_address.len); + if (! hw_addr->addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(hw_addr->addr, entry->ll_address.addr, entry->ll_address.len); + hw_addr->len = entry->ll_address.len; + grub_netbuff_clear(nb); + return GRUB_ERR_NONE; + } + current_time = grub_get_time_ms(); + if (current_time - start_time > TIMEOUT_TIME_MS) + break; + } while (! entry); + grub_netbuff_clear(nb); + return grub_error (GRUB_ERR_TIMEOUT, "Timeout: could not resolve hardware address."); +} + +grub_err_t arp_receive(struct grub_net_network_layer_interface *inf __attribute__ ((unused)), +struct grub_net_network_link_interface *net_link_inf, struct grub_net_buff *nb) +{ + struct arphdr *arp_header = (struct arphdr *)nb->data; + struct arp_entry *entry; + grub_uint8_t merge = 0; + + /* Verify hardware type, protocol type, hardware address length, protocol address length */ + if (arp_header->hrd != net_link_inf->link_prot->type || arp_header->pro != net_link_inf->net_prot->type || + arp_header->hln != inf->card->lla->len || arp_header->pln != inf->card->ila->len) + return GRUB_ERR_NONE; + + grub_uint8_t *sender_hardware_address, *sender_protocol_address, *target_hardware_address, *target_protocol_address; + sender_hardware_address = (grub_uint8_t *)arp_header + sizeof(*arp_header); + sender_protocol_address = sender_hardware_address + arp_header->hln; + target_hardware_address = sender_protocol_address + arp_header->pln; + target_protocol_address = target_hardware_address + arp_header->hln; + /* Check if the sender is in the cache table */ + entry = arp_find_entry(net_link_inf, sender_protocol_address, arp_header->pln); + /* Update sender hardware address */ + if (entry) + { + if (entry->ll_address.addr) + grub_free(entry->ll_address.addr); + entry->ll_address.addr = grub_malloc(arp_header->hln); + if (! entry->ll_address.addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(entry->ll_address.addr, sender_hardware_address, arp_header->hln); + entry->ll_address.len = arp_header->hln; + merge = 1; + } + /* Am I the protocol address target? */ + if (! grub_memcmp(target_protocol_address, inf->card->ila->addr, arp_header->pln)) + { + /* Add sender to cache table */ + if (! merge) + { + if (new_table_entry == -1) + arp_init_table(); + entry = &(arp_table[new_table_entry]); + entry->avail = 1; + entry->ll_protocol = net_link_inf->link_prot; + entry->nl_protocol = net_link_inf->net_prot; + if (entry->nl_address.addr) + grub_free(entry->nl_address.addr); + entry->nl_address.addr = grub_malloc(arp_header->pln); + if (! entry->nl_address.addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(entry->nl_address.addr, sender_protocol_address, arp_header->pln); + entry->nl_address.len = arp_header->pln; + if (entry->ll_address.addr) + grub_free(entry->ll_address.addr); + entry->ll_address.addr = grub_malloc(arp_header->hln); + if (! entry->ll_address.addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(entry->ll_address.addr, sender_hardware_address, arp_header->hln); + entry->ll_address.len = arp_header->hln; + new_table_entry++; + if (new_table_entry == SIZE_ARP_TABLE) + new_table_entry = 0; + } + if (arp_header->op == ARP_REQUEST) + { + struct grub_net_addr aux; + /* Swap hardware fields */ + grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln); + grub_memcpy(sender_hardware_address, inf->card->lla->addr, arp_header->hln); + /* Swap protocol fields */ + aux.addr = grub_malloc(arp_header->pln); + if (! aux.addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(aux.addr, sender_protocol_address, arp_header->pln); + grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln); + grub_memcpy(target_protocol_address, aux.addr, arp_header->pln); + grub_free(aux.addr); + /* Change operation to REPLY and send packet */ + arp_header->op = ARP_REPLY; + aux.addr = target_hardware_address; + aux.len = arp_header->hln; + net_link_inf->link_prot->send(inf, net_link_inf, nb, aux, ARP_ETHERTYPE); + } + } + return GRUB_ERR_NONE; +} diff --git a/net/ethernet.c b/net/ethernet.c index ab5992133..14bc41c5b 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -8,24 +8,21 @@ #include #include #include +#include static grub_err_t send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), - struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) +struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb, +struct grub_net_addr target_addr, grub_uint16_t ethertype) { struct etherhdr *eth; grub_netbuff_push (nb,sizeof(*eth)); eth = (struct etherhdr *) nb->data; - eth->dst[0] = 0x00; - eth->dst[1] = 0x11; - eth->dst[2] = 0x25; - eth->dst[3] = 0xca; - eth->dst[4] = 0x1f; - eth->dst[5] = 0x01; - grub_memcpy (eth->src, bootp_pckt -> chaddr,6); - eth->type = 0x0800; + grub_memcpy(eth->dst, target_addr.addr, target_addr.len); + grub_memcpy(eth->src, bootp_pckt->chaddr, 6); + eth->type = ethertype; return send_card_buffer(nb); // return inf->card->driver->send(inf->card,nb); @@ -34,7 +31,8 @@ send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ static grub_err_t recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)), - struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb) +struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb, +grub_uint16_t ethertype) { struct etherhdr *eth; grub_uint64_t start_time, current_time; @@ -63,12 +61,17 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ } } - /*change for grub_memcmp*/ - //if( eth->src[0] == 0x00 && eth->src[1] == 0x11 && eth->src[2] == 0x25 && - // eth->src[3] == 0xca && eth->src[4] == 0x1f && eth->src[5] == 0x01 && type == 0x800) - if(type == 0x800) - return 0; - + /* ARP packet */ + if (type == ARP_ETHERTYPE) + { + arp_receive(inf, net_link_inf, nb); + if (ethertype == ARP_ETHERTYPE) + return GRUB_ERR_NONE; + } + /* IP packet */ + else if(type == IP_ETHERTYPE && ethertype == IP_ETHERTYPE) + return GRUB_ERR_NONE; + current_time = grub_get_time_ms (); if (current_time - start_time > TIMEOUT_TIME_MS) return grub_error (GRUB_ERR_TIMEOUT, "Time out."); @@ -77,7 +80,7 @@ recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ - verify if the next layer is the desired one. - if not. get another packet. - remove ethernet header from buffer*/ - return 0; + return GRUB_ERR_NONE; } @@ -85,6 +88,7 @@ static struct grub_net_link_layer_protocol grub_ethernet_protocol = { .name = "ethernet", .id = GRUB_NET_ETHERNET_ID, + .type = ARPHRD_ETHERNET, .send = send_ethernet_packet, .recv = recv_ethernet_packet }; diff --git a/net/interface.c b/net/interface.c index bacabf4cb..f17b3e66b 100644 --- a/net/interface.c +++ b/net/interface.c @@ -22,7 +22,6 @@ INTERFACE_REGISTER_FUNCTIONS("link");*/ #include #include -struct grub_net_protocol_stack *grub_net_protocol_stacks; struct grub_net_protocol_stack *grub_net_protocol_stack_get (char *name) { diff --git a/net/ip.c b/net/ip.c index 65b0f2b70..142f33e70 100644 --- a/net/ip.c +++ b/net/ip.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ send_ip_packet (struct grub_net_network_layer_interface *inf, struct iphdr *iph; static int id = 0x2400; + struct grub_net_addr nl_target_addr, ll_target_addr; + grub_err_t rc; grub_netbuff_push(nb,sizeof(*iph)); iph = (struct iphdr *) nb->data; @@ -51,12 +54,26 @@ send_ip_packet (struct grub_net_network_layer_interface *inf, iph->ttl = 0xff; iph->protocol = 0x11; iph->src = (grub_uint32_t) bootp_pckt -> yiaddr; //inf->address.ipv4; // *((grub_uint32_t *)inf->card->ila->addr); - iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr); + // iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr); + iph->dest = *((grub_uint32_t *) (trans_net_inf->data)); iph->chksum = 0 ; iph->chksum = ipchksum((void *)nb->data, sizeof(*iph)); - return trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb); + /* Determine link layer target address via ARP */ + nl_target_addr.len = sizeof(iph->dest); + nl_target_addr.addr = grub_malloc(nl_target_addr.len); + if (! nl_target_addr.addr) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "fail to alloc memory"); + grub_memcpy(nl_target_addr.addr, &(iph->dest), nl_target_addr.len); + rc = arp_resolve(inf, trans_net_inf->inner_layer, &nl_target_addr, &ll_target_addr); + grub_free(nl_target_addr.addr); + if (rc != GRUB_ERR_NONE) + return rc; + + rc = trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb,ll_target_addr, IP_ETHERTYPE); + grub_free(ll_target_addr.addr); + return rc; //return protstack->next->prot->send(inf,protstack->next,nb); } @@ -70,11 +87,12 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, start_time = grub_get_time_ms(); while (1) { - trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb); + trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb,IP_ETHERTYPE); iph = (struct iphdr *) nb->data; if (iph->protocol == 0x11 && iph->dest == (grub_uint32_t) bootp_pckt -> yiaddr && - iph->src == (grub_uint32_t) bootp_pckt -> siaddr ) + //iph->src == (grub_uint32_t) bootp_pckt -> siaddr ) + iph->src == *((grub_uint32_t *) (trans_net_inf->data)) ) { grub_netbuff_pull(nb,sizeof(*iph)); return 0; @@ -99,6 +117,7 @@ static struct grub_net_network_layer_protocol grub_ipv4_protocol = { .name = "ipv4", .id = GRUB_NET_IPV4_ID, + .type = IP_ETHERTYPE, .send = send_ip_packet, .recv = recv_ip_packet }; diff --git a/net/netbuff.c b/net/netbuff.c index ce52233b6..4f6a1da84 100644 --- a/net/netbuff.c +++ b/net/netbuff.c @@ -72,7 +72,7 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) len = NETBUFFMINLEN; len = ALIGN_UP (len,NETBUFF_ALIGN); - data = grub_memalign (len + sizeof (*nb),NETBUFF_ALIGN); + data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); nb = (struct grub_net_buff *) ((int)data + len); nb->head = nb->data = nb->tail = data; nb->end = (char *) nb; diff --git a/net/tftp.c b/net/tftp.c index 0fb43105d..2aeae38e9 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -113,7 +113,7 @@ tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)), app_interface->trans_prot->send (inf,protstack->interface,nb); /*Receive OACK*/ grub_netbuff_clear (nb); - grub_netbuff_reserve (nb,80*1024); + grub_netbuff_reserve (nb,2048); return app_interface->app_prot->recv(inf,protstack,nb); } @@ -215,7 +215,7 @@ static int tftp_file_size (struct grub_net_network_layer_interface* inf , tftp_open (inf, protocol_stack,nb, filename); grub_netbuff_clear (nb); - grub_netbuff_reserve (nb,80*1024); + grub_netbuff_reserve (nb,2048); tftp_send_err (inf, protocol_stack,nb,"Abort transference.",0); return tftp_file.size; diff --git a/normal/misc.c b/normal/misc.c index d53fe711c..30967e174 100644 --- a/normal/misc.c +++ b/normal/misc.c @@ -54,7 +54,7 @@ grub_normal_print_device_info (const char *name) grub_printf_(N_("Protocol: %s"), "Unknown"); grub_putchar ('\n'); grub_putchar ('\t'); - grub_printf_(N_("Server IP: %d.%d.%d.%d"), data->server_ip & 0xff, data->server_ip >> 8 & 0xff, data->server_ip >> 16 & 0xff, data->server_ip >> 24 & 0xff); + grub_printf_(N_("Server IP: %d.%d.%d.%d"), data->server_ip >> 24 & 0xff, data->server_ip >> 16 & 0xff, data->server_ip >> 8 & 0xff, data->server_ip & 0xff); if (data->username) { grub_putchar ('\n'); From 7a6459e12d3dbc01020f0e6c6dcf12a2afdd3bc1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 01:07:50 +0200 Subject: [PATCH 0043/1414] support for Fn keys --- commands/keylayouts.c | 67 ++++++--------------------- commands/keystatus.c | 2 +- include/grub/at_keyboard.h | 24 ++++++++++ include/grub/term.h | 17 ++++++- normal/main.c | 15 +++++- normal/menu_entry.c | 3 ++ normal/menu_text.c | 9 +--- term/at_keyboard.c | 19 +------- term/efi/console.c | 94 +++++++------------------------------- term/terminfo.c | 34 +++++++------- term/usb_keyboard.c | 24 ++++++---- 11 files changed, 123 insertions(+), 185 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 370d55c4f..58baabe67 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -23,39 +23,13 @@ #include #include #include +#include -static int keyboard_map[128] = -{ - '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '\n', '\0', 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', '\0', '*', - '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, - GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, - GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC -}; - -/* Define scan codes. */ -#define GRUB_TERM_AT_KEY_LEFT 0x4B00 -#define GRUB_TERM_AT_KEY_RIGHT 0x4D00 -#define GRUB_TERM_AT_KEY_UP 0x4800 -#define GRUB_TERM_AT_KEY_DOWN 0x5000 -#define GRUB_TERM_AT_KEY_IC 0x5200 -#define GRUB_TERM_AT_KEY_DC 0x5300 -#define GRUB_TERM_AT_KEY_BACKSPACE 0x0008 -#define GRUB_TERM_AT_KEY_HOME 0x4700 -#define GRUB_TERM_AT_KEY_END 0x4F00 -#define GRUB_TERM_AT_KEY_NPAGE 0x5100 -#define GRUB_TERM_AT_KEY_PPAGE 0x4900 +GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); static int get_abstract_code (grub_term_input_t term, int in) { - unsigned flags = 0; switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) { case GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES: @@ -64,32 +38,18 @@ get_abstract_code (grub_term_input_t term, int in) case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS: { unsigned status = 0; - struct { - int from, to; - } translations[] = - { - {GRUB_TERM_AT_KEY_LEFT, GRUB_TERM_KEY_LEFT}, - {GRUB_TERM_AT_KEY_RIGHT, GRUB_TERM_KEY_RIGHT}, - {GRUB_TERM_AT_KEY_UP, GRUB_TERM_KEY_UP}, - {GRUB_TERM_AT_KEY_DOWN, GRUB_TERM_KEY_DOWN}, - {GRUB_TERM_AT_KEY_HOME, GRUB_TERM_KEY_HOME}, - {GRUB_TERM_AT_KEY_END, GRUB_TERM_KEY_END}, - {GRUB_TERM_AT_KEY_DC, GRUB_TERM_KEY_DC}, - {GRUB_TERM_AT_KEY_PPAGE, GRUB_TERM_KEY_PPAGE}, - {GRUB_TERM_AT_KEY_NPAGE, GRUB_TERM_KEY_NPAGE}, - {0x5600 | '\\', GRUB_TERM_KEY_102}, - {0x5600 | '|', GRUB_TERM_KEY_SHIFT_102}, - }; - unsigned i; + unsigned flags = 0; if (term->getkeystatus) - status = term->getkeystatus (); + status = term->getkeystatus (term); if (status & GRUB_TERM_CAPS) flags |= GRUB_TERM_CAPS; - for (i = 0; i < ARRAY_SIZE (translations); i++) - if (translations[i].from == (in & 0xffff)) - return translations[i].to | flags; + if ((0x5600 | '\\') == (in & 0xffff)) + return GRUB_TERM_KEY_102 | flags; + + if ((0x5600 | '|') == (in & 0xffff)) + return GRUB_TERM_KEY_SHIFT_102 | flags; /* Detect CTRL'ed keys. */ if ((in & 0xff) > 0 && (in & 0xff) < 0x20 @@ -105,6 +65,9 @@ get_abstract_code (grub_term_input_t term, int in) && keyboard_map[(in & 0xff00) >> 8] <= 'z') return keyboard_map[(in & 0xff00) >> 8] | flags | GRUB_TERM_ALT_GR; + if ((in & 0xff) == 0) + return keyboard_map[(in & 0xff00) >> 8] | flags; + return (in & 0xff) | flags; } } @@ -165,9 +128,9 @@ grub_getkey_smart (void) { FOR_ACTIVE_TERM_INPUTS(term) { - int key = term->checkkey (); + int key = term->checkkey (term); if (key != -1) - return translate (term, term->getkey ()); + return translate (term, term->getkey (term)); } grub_cpu_idle (); @@ -181,7 +144,7 @@ grub_checkkey (void) FOR_ACTIVE_TERM_INPUTS(term) { - int key = term->checkkey (); + int key = term->checkkey (term); if (key != -1) return translate (term, key); } diff --git a/commands/keystatus.c b/commands/keystatus.c index fc4d11d73..9db92b942 100644 --- a/commands/keystatus.c +++ b/commands/keystatus.c @@ -40,7 +40,7 @@ grub_getkeystatus (void) FOR_ACTIVE_TERM_INPUTS(term) { if (term->getkeystatus) - status |= term->getkeystatus (); + status |= term->getkeystatus (term); } return status; diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 10421540a..3f72fa879 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -51,4 +51,28 @@ #define OLPC_RIGHT '\0' #endif +#define GRUB_AT_KEY_KEYBOARD_MAP(name) \ +static const int name[128] = \ +{ \ + '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', \ + '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, \ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', \ + 'o', 'p', '[', ']', '\n', '\0', 'a', 's', \ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', \ + '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', \ + 'b', 'n', 'm', ',', '.', '/', '\0', '*', \ + '\0', ' ', '\0', 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, '\0', '\0', GRUB_TERM_KEY_HOME, \ + GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, \ + '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, \ + GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, \ + GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, \ + '\0', '\0', GRUB_TERM_KEY_102, GRUB_TERM_KEY_F11, \ + GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', \ + '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, \ + OLPC_RIGHT \ +} + #endif diff --git a/include/grub/term.h b/include/grub/term.h index 7871c656f..dbafef0e1 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -38,10 +38,23 @@ #define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 7) #define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 8) #define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 9) +#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 10) +#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 11) +#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 12) +#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 13) +#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 14) +#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 15) +#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 16) +#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 17) +#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 18) +#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 19) +#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 20) +#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 21) +#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 22) /* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_KEY_102 (GRUB_TERM_EXTENDED | 10) -#define GRUB_TERM_KEY_SHIFT_102 (GRUB_TERM_EXTENDED | 11) +#define GRUB_TERM_KEY_102 (GRUB_TERM_EXTENDED | 23) +#define GRUB_TERM_KEY_SHIFT_102 (GRUB_TERM_EXTENDED | 24) #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' diff --git a/normal/main.c b/normal/main.c index 7582c7f13..6eee57799 100644 --- a/normal/main.c +++ b/normal/main.c @@ -164,7 +164,20 @@ static struct { {"backspace", '\b'}, {"tab", '\t'}, - {"delete", GRUB_TERM_KEY_DC} + {"delete", GRUB_TERM_KEY_DC}, + {"insert", GRUB_TERM_KEY_INSERT}, + {"f1", GRUB_TERM_KEY_F1}, + {"f2", GRUB_TERM_KEY_F2}, + {"f3", GRUB_TERM_KEY_F3}, + {"f4", GRUB_TERM_KEY_F4}, + {"f5", GRUB_TERM_KEY_F5}, + {"f6", GRUB_TERM_KEY_F6}, + {"f7", GRUB_TERM_KEY_F7}, + {"f8", GRUB_TERM_KEY_F8}, + {"f9", GRUB_TERM_KEY_F9}, + {"f10", GRUB_TERM_KEY_F10}, + {"f11", GRUB_TERM_KEY_F11}, + {"f12", GRUB_TERM_KEY_F12}, }; /* Add a menu entry to the current menu context (as given by the environment diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 8e943612a..87292d445 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -1337,6 +1337,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) break; case GRUB_TERM_CTRL | 'h': + case '\b': if (! backward_delete_char (screen, 1)) goto fail; break; @@ -1375,10 +1376,12 @@ grub_menu_entry_run (grub_menu_entry_t entry) return; case GRUB_TERM_CTRL | 'c': + case GRUB_TERM_KEY_F2: grub_cmdline_run (1); goto refresh; case GRUB_TERM_CTRL | 'x': + case GRUB_TERM_KEY_F10: { int chars_before = grub_normal_get_char_counter (); run (screen); diff --git a/normal/menu_text.c b/normal/menu_text.c index 3e3e7e2fa..fc4a89196 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -120,17 +120,10 @@ print_message (int nested, int edit, struct grub_term_output *term) if (edit) { grub_putcode ('\n', term); -#ifdef GRUB_MACHINE_EFI grub_print_message_indented (_("Minimum Emacs-like screen editing is \ -supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \ -F4 for a command-line or ESC to discard edits and return to the GRUB menu."), - STANDARD_MARGIN, STANDARD_MARGIN, term); -#else - grub_print_message_indented (_("Minimum Emacs-like screen editing is \ -supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \ +supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \ command-line or ESC to discard edits and return to the GRUB menu."), STANDARD_MARGIN, STANDARD_MARGIN, term); -#endif } else { diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 683981be3..e89f3bf5b 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -41,24 +41,7 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_CAPS (1 << 2) -static int keyboard_map[128] = -{ - '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '\n', '\0', 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', '\0', '*', - '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, - GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, - GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC, '\0', '\0', - GRUB_TERM_KEY_102, '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, - OLPC_RIGHT -}; +GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); static int keyboard_map_shift[128] = { diff --git a/term/efi/console.c b/term/efi/console.c index dca002910..f47263ee4 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -100,6 +100,17 @@ grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), efi_call_2 (o->output_string, o, str); } +const unsigned efi_codes[] = + { + 0, GRUB_TERM_UP, GRUB_TERM_DOWN, GRUB_TERM_RIGHT, + GRUB_TERM_LEFT, GRUB_TERM_HOME, GRUB_TERM_END, GRUB_TERM_KEY_INSERT, + GRUB_TERM_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, 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, 0, 0, '\e' + }; + + static int grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused))) { @@ -112,85 +123,14 @@ grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused))) i = grub_efi_system_table->con_in; status = efi_call_2 (i->read_key_stroke, i, &key); -#if 0 - switch (status) - { - case GRUB_EFI_SUCCESS: - { - grub_uint16_t xy; - xy = grub_getxy (); - grub_gotoxy (0, 0); - grub_printf ("scan_code=%x,unicode_char=%x ", - (unsigned) key.scan_code, - (unsigned) key.unicode_char); - grub_gotoxy (xy >> 8, xy & 0xff); - } - break; + if (status != GRUB_EFI_SUCCESS) + return -1; - case GRUB_EFI_NOT_READY: - //grub_printf ("not ready "); - break; - - default: - //grub_printf ("device error "); - break; - } -#endif - - if (status == GRUB_EFI_SUCCESS) - { - switch (key.scan_code) - { - case 0x00: - read_key = key.unicode_char; - break; - case 0x01: - read_key = GRUB_TERM_UP; - break; - case 0x02: - read_key = GRUB_TERM_DOWN; - break; - case 0x03: - read_key = GRUB_TERM_RIGHT; - break; - case 0x04: - read_key = GRUB_TERM_LEFT; - break; - case 0x05: - read_key = GRUB_TERM_HOME; - break; - case 0x06: - read_key = GRUB_TERM_END; - break; - case 0x07: - break; - case 0x08: - read_key = GRUB_TERM_DC; - break; - case 0x09: - break; - case 0x0a: - break; - case 0x0b: - read_key = 24; - break; - case 0x0c: - read_key = 1; - break; - case 0x0d: - read_key = 5; - break; - case 0x0e: - read_key = 3; - break; - case 0x17: - read_key = '\e'; - break; - default: - break; - } - } + if (key.scan_code == 0) + read_key = key.unicode_char; + else if (key.scan_code < ARRAY_SIZE (efi_codes)) + read_key = efi_codes[key.scan_code]; return read_key; } diff --git a/term/terminfo.c b/term/terminfo.c index ff54e5dba..9030c2580 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -402,34 +402,34 @@ grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void)) static struct { char key; - char ascii; + unsigned ascii; } three_code_table[] = { - {'4', GRUB_TERM_DC}, - {'A', GRUB_TERM_UP}, - {'B', GRUB_TERM_DOWN}, - {'C', GRUB_TERM_RIGHT}, - {'D', GRUB_TERM_LEFT}, - {'F', GRUB_TERM_END}, - {'H', GRUB_TERM_HOME}, - {'K', GRUB_TERM_END}, - {'P', GRUB_TERM_DC}, - {'?', GRUB_TERM_PPAGE}, - {'/', GRUB_TERM_NPAGE} + {'4', GRUB_TERM_KEY_DC}, + {'A', GRUB_TERM_KEY_UP}, + {'B', GRUB_TERM_KEY_DOWN}, + {'C', GRUB_TERM_KEY_RIGHT}, + {'D', GRUB_TERM_KEY_LEFT}, + {'F', GRUB_TERM_KEY_END}, + {'H', GRUB_TERM_KEY_HOME}, + {'K', GRUB_TERM_KEY_END}, + {'P', GRUB_TERM_KEY_DC}, + {'?', GRUB_TERM_KEY_PPAGE}, + {'/', GRUB_TERM_KEY_NPAGE} }; static struct { char key; - char ascii; + unsigned ascii; } four_code_table[] = { - {'1', GRUB_TERM_HOME}, - {'3', GRUB_TERM_DC}, - {'5', GRUB_TERM_PPAGE}, - {'6', GRUB_TERM_NPAGE} + {'1', GRUB_TERM_KEY_HOME}, + {'3', GRUB_TERM_KEY_DC}, + {'5', GRUB_TERM_KEY_PPAGE}, + {'6', GRUB_TERM_KEY_NPAGE} }; unsigned i; diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index ba67e2b85..e18f205e8 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -27,7 +27,7 @@ #include -static int keyboard_map[128] = +static unsigned keyboard_map[128] = { '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', @@ -36,13 +36,17 @@ static int keyboard_map[128] = '3', '4', '5', '6', '7', '8', '9', '0', '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[', ']', '\\', '#', ';', '\'', '`', ',', '.', - '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, - GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP + '/', '\0', 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, '\0', '\0', + '\0', GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, + GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, + GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP, + [0x64] = GRUB_TERM_KEY_102 }; -static char keyboard_map_shift[128] = +static unsigned keyboard_map_shift[128] = { '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', @@ -51,7 +55,8 @@ static char keyboard_map_shift[128] = '#', '$', '%', '^', '&', '*', '(', ')', '\n', '\0', '\0', '\0', ' ', '_', '+', '{', '}', '|', '#', ':', '"', '`', '<', '>', - '?' + '?', + [0x64] = GRUB_TERM_KEY_SHIFT_102 }; static grub_usb_device_t usbdev; @@ -157,8 +162,9 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) #define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 /* Check if the Shift key was pressed. */ - if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT - || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) + if ((data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT + || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) + && keyboard_map_shift[data[2]]) key = keyboard_map_shift[data[2]]; else key = keyboard_map[data[2]]; From b6f7b4ba03559d7340a811bfe03a1a47b49f8dc6 Mon Sep 17 00:00:00 2001 From: Carles Pina i Estany Date: Thu, 19 Aug 2010 02:15:29 +0200 Subject: [PATCH 0044/1414] Reimported heavily modified version of cpina's grub-mklayout --- ChangeLog.keyboard_layouts | 7 + conf/common.rmk | 4 + include/grub/at_keyboard.h | 15 +- include/grub/keyboard_layouts.h | 28 ++++ include/grub/term.h | 4 +- term/at_keyboard.c | 13 +- util/grub-mklayouts.c | 279 ++++++++++++++++++++++++++++++++ 7 files changed, 335 insertions(+), 15 deletions(-) create mode 100644 ChangeLog.keyboard_layouts create mode 100644 include/grub/keyboard_layouts.h create mode 100644 util/grub-mklayouts.c diff --git a/ChangeLog.keyboard_layouts b/ChangeLog.keyboard_layouts new file mode 100644 index 000000000..65af097ff --- /dev/null +++ b/ChangeLog.keyboard_layouts @@ -0,0 +1,7 @@ +2010-01-18 Carles Pina i Estany + + Adds keyboard layouts support. + + * conf/common.rmk (bin_UTILITIES): Add grub-mklayouts rules. + * include/grub/keyboard_layouts.h: New file. + * util/grub-mklayouts.c: New file. diff --git a/conf/common.rmk b/conf/common.rmk index ee6b94032..745b1837e 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -80,6 +80,10 @@ endif bin_UTILITIES += grub-mkrelpath grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c +# For grub-mklayouts. +bin_UTILITIES += grub-mklayouts +grub_mklayouts_SOURCES = gnulib/progname.c util/grub-mklayouts.c util/misc.c kern/emu/misc.c + bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 3f72fa879..8bb090d2a 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -52,7 +52,7 @@ #endif #define GRUB_AT_KEY_KEYBOARD_MAP(name) \ -static const int name[128] = \ +static const unsigned name[128] = \ { \ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', \ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, \ @@ -75,4 +75,17 @@ static const int name[128] = \ OLPC_RIGHT \ } +#define GRUB_AT_KEY_KEYBOARD_MAP_SHIFT(name) \ +static unsigned name[128] = \ +{ \ + '\0', '\0', '!', '@', '#', '$', '%', '^', \ + '&', '*', '(', ')', '_', '+', '\0', '\0', \ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', \ + 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', \ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', \ + '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', \ + 'B', 'N', 'M', '<', '>', '?', \ + [0x56] = GRUB_TERM_KEY_SHIFT_102 \ +} + #endif diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h new file mode 100644 index 000000000..1d263e268 --- /dev/null +++ b/include/grub/keyboard_layouts.h @@ -0,0 +1,28 @@ +/* + * 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_KEYBOARD_LAYOUTS_H +#define GRUB_KEYBOARD_LAYOUTS_H 1 + +#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" +#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) +#define GRUB_KEYBOARD_LAYOUTS_VERSION 2 + +#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 256 + +#endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/include/grub/term.h b/include/grub/term.h index dbafef0e1..fa813d1b5 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -53,8 +53,8 @@ #define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 22) /* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_KEY_102 (GRUB_TERM_EXTENDED | 23) -#define GRUB_TERM_KEY_SHIFT_102 (GRUB_TERM_EXTENDED | 24) +#define GRUB_TERM_KEY_102 0x80 +#define GRUB_TERM_KEY_SHIFT_102 0x81 #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' diff --git a/term/at_keyboard.c b/term/at_keyboard.c index e89f3bf5b..4c9c2a23a 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -42,18 +42,7 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_CAPS (1 << 2) GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); - -static int keyboard_map_shift[128] = -{ - '\0', '\0', '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\0', '\0', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', - [0x56] = GRUB_TERM_KEY_SHIFT_102 -}; +GRUB_AT_KEY_KEYBOARD_MAP_SHIFT (keyboard_map_shift); static grub_uint8_t grub_keyboard_controller_orig; diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c new file mode 100644 index 000000000..48b17e798 --- /dev/null +++ b/util/grub-mklayouts.c @@ -0,0 +1,279 @@ +/* + * 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 +#include + +#include "progname.h" + +#define CKBCOMP "ckbcomp" + +static struct option options[] = { + {"output", required_argument, 0, 'o'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; + +struct console_grub_equivalence +{ + char *layout; + grub_uint32_t grub; +}; + +static struct console_grub_equivalence console_grub_equivalences[] = { + {"KP_1", '1'}, + {"KP_2", '2'}, + {"KP_3", '3'}, + {"KP_4", '4'}, + {"KP_5", '5'}, + {"KP_6", '6'}, + {"KP_7", '7'}, + {"KP_8", '8'}, + {"KP_9", '9'}, + + {"KP_Multiply", '*'}, + {"KP_Substract", '-'}, + {"KP_Add", '+'}, + {"KP_Divide", '/'}, + + {"KP_Enter", '\n'}, + {"Return", '\n'}, + {"", '\0'} +}; + +GRUB_AT_KEY_KEYBOARD_MAP (us_keyboard_map); +GRUB_AT_KEY_KEYBOARD_MAP_SHIFT (us_keyboard_map_shifted); + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + else + printf ("\ +Usage: %s [OPTIONS] LAYOUT\n\ + -o, --output set output base name file. Default is LAYOUT.gkb\n\ + -h, --help display this message and exit.\n\ + -V, --version print version information and exit.\n\ + -v, --verbose print verbose messages.\n\ +\n\ +Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); + + exit (status); +} + +char +lookup (char *code) +{ + int i; + + for (i = 0; console_grub_equivalences[i].grub != '\0'; i++) + if (strcmp (code, console_grub_equivalences[i].layout) == 0) + return console_grub_equivalences[i].grub; + + return '\0'; +} + +unsigned int +get_grub_code (char *layout_code) +{ + unsigned int code; + + if (strncmp (layout_code, "U+", sizeof ("U+") - 1) == 0) + sscanf (layout_code, "U+%x", &code); + else if (strncmp (layout_code, "+U+", sizeof ("+U+") - 1) == 0) + sscanf (layout_code, "+U+%x", &code); + else + code = lookup (layout_code); + return code; +} + +void +write_file (char* filename, grub_uint32_t *keyboard_map) +{ + FILE *fp_output; + grub_uint32_t version; + unsigned i; + + version = grub_cpu_to_le32 (GRUB_KEYBOARD_LAYOUTS_VERSION); + + for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) + keyboard_map[i] = grub_cpu_to_le32 (keyboard_map[i]); + + fp_output = fopen (filename, "w"); + + if (!fp_output) + { + grub_util_error ("cannot open `%s'", filename); + exit (1); + } + + fwrite (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, 1, + GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE, fp_output); + fwrite (&version, sizeof (version), 1, fp_output); + fwrite (keyboard_map, sizeof (keyboard_map[0]), + GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output); + fclose (fp_output); +} + +void +write_keymaps (char *keymap, char *file_basename) +{ + grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + + char line[2048]; + pid_t pid; + int pipe_communication[2]; + int ok; + + FILE *fp_pipe; + + if (pipe (pipe_communication) == -1) + { + grub_util_error ("cannot prepare the pipe"); + exit (2); + } + + pid = fork (); + if (pid < 0) + { + grub_util_error ("cannot fork"); + exit (2); + } + else if (pid == 0) + { + close (1); + dup (pipe_communication[1]); + close (pipe_communication[0]); + execlp (CKBCOMP, CKBCOMP, keymap, NULL); + grub_util_error ("%s %s cannot be executed", CKBCOMP, keymap); + exit (3); + } + close (pipe_communication[1]); + fp_pipe = fdopen (pipe_communication[0], "r"); + + memset (keyboard_map, 0, sizeof (keyboard_map)); + + /* Process the ckbcomp output and prepare the layouts. */ + ok = 0; + while (fgets (line, sizeof (line), fp_pipe)) + { + if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0) + { + unsigned keycode; + char normal[64]; + char shift[64]; + sscanf (line, "keycode %u = %60s %60s", &keycode, normal, shift); + if (keycode < ARRAY_SIZE (us_keyboard_map) + && us_keyboard_map[keycode] < ARRAY_SIZE (keyboard_map)) + { + keyboard_map[us_keyboard_map[keycode]] = get_grub_code (normal); + ok = 1; + } + if (keycode < ARRAY_SIZE (us_keyboard_map_shifted) + && us_keyboard_map_shifted[keycode] < ARRAY_SIZE (keyboard_map)) + { + keyboard_map[us_keyboard_map_shifted[keycode]] + = get_grub_code (shift); + ok = 1; + } + } + } + + if (ok == 0) + { + fprintf (stderr, "ERROR: no keycodes found. Check output of %s %s.\n", + CKBCOMP, keymap); + exit (1); + } + + write_file (file_basename, keyboard_map); +} + +int +main (int argc, char *argv[]) +{ + int verbosity; + char *file_basename = NULL; + + set_program_name (argv[0]); + + verbosity = 0; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "o:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'h': + usage (0); + break; + + case 'o': + file_basename = optarg; + break; + + case 'V': + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, + PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + /* Obtain LAYOUT. */ + if (optind >= argc) + { + fprintf (stderr, "No layout is specified.\n"); + usage (1); + } + + if (file_basename == NULL) + { + file_basename = xasprintf ("%s.gkb", argv[optind]); + write_keymaps (argv[optind], file_basename); + free (file_basename); + } + else + write_keymaps (argv[optind], file_basename); + + return 0; +} From 211144767584a29193a70172b134ee2f4ea0e6c9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 02:21:36 +0200 Subject: [PATCH 0045/1414] Add new flag SHIFT --- include/grub/term.h | 6 ++++-- term/at_keyboard.c | 12 ++++++++---- term/usb_keyboard.c | 10 +++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index fa813d1b5..1f64bebc7 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -20,6 +20,8 @@ #define GRUB_TERM_HEADER 1 /* Internal codes used by GRUB to represent terminal input. */ +/* Only for keys otherwise not having shifted modification. */ +#define GRUB_TERM_SHIFT 0x01000000 #define GRUB_TERM_CTRL 0x02000000 #define GRUB_TERM_ALT 0x04000000 /* Used by keylayouts code. Never returned in grub_getkey. */ @@ -27,8 +29,8 @@ #define GRUB_TERM_CAPS 0x10000000 /* Keys without associated character. */ -#define GRUB_TERM_EXTENDED 0x1000000 -#define GRUB_TERM_KEY_MASK 0x1ffffff +#define GRUB_TERM_EXTENDED 0x00800000 +#define GRUB_TERM_KEY_MASK 0x00ffffff #define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 1) #define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 2) #define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 3) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 4c9c2a23a..cc0c69e22 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -187,10 +187,14 @@ grub_at_keyboard_getkey_noblock (void) key = -1; break; default: - if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L - | KEYBOARD_STATUS_SHIFT_R)) - && keyboard_map_shift[code]) - key = keyboard_map_shift[code]; + if (at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L + | KEYBOARD_STATUS_SHIFT_R)) + { + if (keyboard_map_shift[code]) + key = keyboard_map_shift[code]; + else + key = keyboard_map[code] | GRUB_TERM_SHIFT; + } else key = keyboard_map[code]; diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index e18f205e8..9e1ce5e60 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -162,10 +162,14 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) #define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 /* Check if the Shift key was pressed. */ - if ((data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT + if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) - && keyboard_map_shift[data[2]]) - key = keyboard_map_shift[data[2]]; + { + if (keyboard_map_shift[data[2]]) + key = keyboard_map_shift[data[2]]; + else + key = keyboard_map[data[2]] | GRUB_TERM_SHIFT; + } else key = keyboard_map[data[2]]; From d90aa78482dfa4eebcf226484a386c0c6c3581a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 02:57:05 +0200 Subject: [PATCH 0046/1414] KEyboard layout support --- commands/keylayouts.c | 112 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 58baabe67..05595f8d1 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -24,6 +24,10 @@ #include #include #include +#include +#include +#include +#include GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); @@ -73,20 +77,21 @@ get_abstract_code (grub_term_input_t term, int in) } } +static grub_uint32_t mapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + static int -map (grub_term_input_t term, int in) +map (grub_term_input_t term __attribute__ ((unused)), int in) { - /* No match with AltGr. Interpret it as Alt rather than as L3 modifier then. - */ + /* AltGr isn't supported yet. */ if (in & GRUB_TERM_ALT_GR) - return map (term, in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT_GR; + in = (in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT_GR; - if (in == GRUB_TERM_KEY_102) - return '\\'; - if (in == GRUB_TERM_KEY_SHIFT_102) - return '|'; + if ((in & GRUB_TERM_EXTENDED) || (in & GRUB_TERM_KEY_MASK) == '\b' + || (in & GRUB_TERM_KEY_MASK) == '\t' || (in & GRUB_TERM_KEY_MASK) == '\e' + || (in & GRUB_TERM_KEY_MASK) >= ARRAY_SIZE (mapping)) + return in; - return in; + return mapping[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK); } static int @@ -152,15 +157,104 @@ grub_checkkey (void) return -1; } +static grub_err_t +grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + char *filename; + grub_file_t file; + grub_uint32_t version; + grub_uint8_t magic[GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE]; + grub_uint32_t newmapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + unsigned i; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file or layout name required"); + if (argv[0][0] != '(' && argv[0][0] != '/' && argv[0][0] != '+') + { + const char *prefix = grub_env_get ("prefix"); + if (!prefix) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "No prefix set"); + filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]); + if (!filename) + return grub_errno; + } + else + filename = argv[0]; + + file = grub_gzfile_open (filename, 1); + if (! file) + goto fail; + + if (grub_file_read (file, magic, sizeof (magic)) != sizeof (magic)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); + goto fail; + } + + if (grub_memcmp (magic, GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, + GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE) != 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid magic"); + goto fail; + } + + if (grub_file_read (file, &version, sizeof (version)) != sizeof (version)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); + goto fail; + } + + if (grub_le_to_cpu32 (version) != GRUB_KEYBOARD_LAYOUTS_VERSION) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid version"); + goto fail; + } + + if (grub_file_read (file, newmapping, sizeof (newmapping)) + != sizeof (newmapping)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); + goto fail; + } + + for (i = 0; i < ARRAY_SIZE (mapping); i++) + mapping[i] = grub_le_to_cpu32(newmapping[i]); + + return GRUB_ERR_NONE; + + fail: + if (filename != argv[0]) + grub_free (filename); + if (file) + grub_file_close (file); + return grub_errno; +} + static int (*grub_getkey_saved) (void); +static grub_command_t cmd; + GRUB_MOD_INIT(keylayouts) { + unsigned i; + for (i = 0; i < ARRAY_SIZE (mapping); i++) + mapping[i] = i; + mapping[GRUB_TERM_KEY_102] = '\\'; + mapping[GRUB_TERM_KEY_SHIFT_102] = '|'; + grub_getkey_saved = grub_getkey; grub_getkey = grub_getkey_smart; + + cmd = grub_register_command ("keymap", grub_cmd_keymap, + 0, N_("Load a keyboard layout.")); } GRUB_MOD_FINI(keylayouts) { grub_getkey = grub_getkey_saved; + grub_unregister_command (cmd); } From 7ea82054f562055adb3d5c44ca402ec894cd89d4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 04:13:32 +0200 Subject: [PATCH 0047/1414] Solve keypad-related issues --- commands/keylayouts.c | 44 ++++++++++++++++++++++-------- include/grub/at_keyboard.h | 56 +++++++++++++++++++++++--------------- include/grub/term.h | 6 ++-- 3 files changed, 70 insertions(+), 36 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 05595f8d1..419cdf45a 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -55,6 +55,11 @@ get_abstract_code (grub_term_input_t term, int in) if ((0x5600 | '|') == (in & 0xffff)) return GRUB_TERM_KEY_SHIFT_102 | flags; + if ((in & 0xff00) == 0x3500 || (in & 0xff00) == 0x3700 + || (in & 0xff00) == 0x4500 + || ((in & 0xff00) >= 0x4700 && (in & 0xff00) <= 0x5300)) + flags |= GRUB_TERM_KEYPAD; + /* Detect CTRL'ed keys. */ if ((in & 0xff) > 0 && (in & 0xff) < 0x20 && ((in & 0xffff) != (0x0100 | '\e')) @@ -79,19 +84,33 @@ get_abstract_code (grub_term_input_t term, int in) static grub_uint32_t mapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; -static int -map (grub_term_input_t term __attribute__ ((unused)), int in) +static unsigned +clear_internal_flags (unsigned in) { + if (in & GRUB_TERM_ALT_GR) + in = (in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT; + return in & ~GRUB_TERM_CAPS & ~GRUB_TERM_KEYPAD; +} + +static unsigned +map (grub_term_input_t term __attribute__ ((unused)), unsigned in) +{ + if (in & GRUB_TERM_KEYPAD) + return clear_internal_flags (in); + /* AltGr isn't supported yet. */ if (in & GRUB_TERM_ALT_GR) - in = (in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT_GR; + in = (in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT; if ((in & GRUB_TERM_EXTENDED) || (in & GRUB_TERM_KEY_MASK) == '\b' + || (in & GRUB_TERM_KEY_MASK) == '\n' || (in & GRUB_TERM_KEY_MASK) == ' ' || (in & GRUB_TERM_KEY_MASK) == '\t' || (in & GRUB_TERM_KEY_MASK) == '\e' + || (in & GRUB_TERM_KEY_MASK) == '\r' || (in & GRUB_TERM_KEY_MASK) >= ARRAY_SIZE (mapping)) - return in; + return clear_internal_flags (in); - return mapping[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK); + return mapping[in & GRUB_TERM_KEY_MASK] + | clear_internal_flags (in & ~GRUB_TERM_KEY_MASK); } static int @@ -99,14 +118,15 @@ translate (grub_term_input_t term, int in) { int code, flags; code = get_abstract_code (term, in); - if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'a' && (code & 0xff) <= 'z') - code = (code & 0xff) + 'A' - 'a'; - else if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'A' - && (code & 0xff) <= 'Z') - code = (code & 0xff) + 'a' - 'A'; + if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'a' + && (code & GRUB_TERM_KEY_MASK) <= 'z') + code = (code & GRUB_TERM_KEY_MASK) + 'A' - 'a'; + else if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'A' + && (code & GRUB_TERM_KEY_MASK) <= 'Z') + code = (code & GRUB_TERM_KEY_MASK) + 'a' - 'A'; - flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR); - code &= (GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR); + flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD); + code &= (GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD); code = map (term, code); /* Transform unconsumed AltGr into Alt. */ if (code & GRUB_TERM_ALT_GR) diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 8bb090d2a..e8289d672 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -51,28 +51,40 @@ #define OLPC_RIGHT '\0' #endif -#define GRUB_AT_KEY_KEYBOARD_MAP(name) \ -static const unsigned name[128] = \ -{ \ - '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', \ - '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, \ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', \ - 'o', 'p', '[', ']', '\n', '\0', 'a', 's', \ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', \ - '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', \ - 'b', 'n', 'm', ',', '.', '/', '\0', '*', \ - '\0', ' ', '\0', 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, '\0', '\0', GRUB_TERM_KEY_HOME, \ - GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, \ - '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, \ - GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, \ - GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, \ - '\0', '\0', GRUB_TERM_KEY_102, GRUB_TERM_KEY_F11, \ - GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', \ - '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, \ - OLPC_RIGHT \ +#define GRUB_AT_KEY_KEYBOARD_MAP(name) \ +static const unsigned name[128] = \ +{ \ + /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', \ + /* 0x08 */ '7', '8', '9', '0', \ + /* 0x0c */ '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, \ + /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', \ + /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', \ + /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', \ + /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', \ + /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*' | GRUB_TERM_KEYPAD, \ + /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, \ + /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, \ + /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, \ + /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, \ + /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, \ + /* 0x44 */ GRUB_TERM_KEY_F10, '\0', \ + /* 0x46 */ '\0', GRUB_TERM_KEY_HOME, \ + /* 0x48 */ GRUB_TERM_KEY_UP, \ + /* 0x49 */ GRUB_TERM_KEY_NPAGE, \ + /* 0x4a */ '-' | GRUB_TERM_KEYPAD, \ + /* 0x4b */ GRUB_TERM_KEY_LEFT, \ + /* 0x4c */ GRUB_TERM_KEY_CENTER | GRUB_TERM_KEYPAD, \ + /* 0x4d */ GRUB_TERM_KEY_RIGHT, \ + /* 0x4e */ '+' | GRUB_TERM_KEYPAD, \ + /* 0x4f */ GRUB_TERM_KEY_END, \ + /* 0x50 */ GRUB_TERM_KEY_DOWN, \ + /* 0x51 */ GRUB_TERM_KEY_PPAGE, \ + /* 0x52 */ GRUB_TERM_KEY_INSERT, \ + /* 0x53 */ GRUB_TERM_KEY_DC, \ + /* 0x54 */ '\0', '\0', GRUB_TERM_KEY_102, GRUB_TERM_KEY_F11, \ + /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', \ + /* 0x60 */ '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, \ + /* 0x68 */ OLPC_RIGHT \ } #define GRUB_AT_KEY_KEYBOARD_MAP_SHIFT(name) \ diff --git a/include/grub/term.h b/include/grub/term.h index 1f64bebc7..f2f80152f 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -25,8 +25,9 @@ #define GRUB_TERM_CTRL 0x02000000 #define GRUB_TERM_ALT 0x04000000 /* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_ALT_GR 0x08000000 -#define GRUB_TERM_CAPS 0x10000000 +#define GRUB_TERM_ALT_GR 0x08000000 +#define GRUB_TERM_CAPS 0x10000000 +#define GRUB_TERM_KEYPAD 0x20000000 /* Keys without associated character. */ #define GRUB_TERM_EXTENDED 0x00800000 @@ -53,6 +54,7 @@ #define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 20) #define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 21) #define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 22) +#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 23) /* Used by keylayouts code. Never returned in grub_getkey. */ #define GRUB_TERM_KEY_102 0x80 From eb628338dbd4198d517c91090207b0a651d8088a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 11:44:49 +0200 Subject: [PATCH 0048/1414] AltGr support --- commands/keylayouts.c | 54 ++++++++++++++++++++++----------- include/grub/keyboard_layouts.h | 2 +- term/at_keyboard.c | 45 +++++++++++++++------------ util/grub-mklayouts.c | 21 +++++++++++-- 4 files changed, 82 insertions(+), 40 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 419cdf45a..25a117560 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -73,6 +73,18 @@ get_abstract_code (grub_term_input_t term, int in) if (((in & 0xff) == 0) && keyboard_map[(in & 0xff00) >> 8] >= 'a' && keyboard_map[(in & 0xff00) >> 8] <= 'z') return keyboard_map[(in & 0xff00) >> 8] | flags | GRUB_TERM_ALT_GR; + if ((in & 0xff) == 0 && (in & 0xff00) >= 0x7800 + && (in & 0xff00) <= 0x8000) + return (((in & 0xff00) >> 8) - 0x78 + '1') | flags | GRUB_TERM_ALT_GR; + + if ((in & 0xff00) == 0x8100) + return '0' | flags | GRUB_TERM_ALT_GR; + + if ((in & 0xffff) == 0x8200) + return '-' | flags | GRUB_TERM_ALT_GR; + + if ((in & 0xffff) == 0x8300) + return '+' | flags | GRUB_TERM_ALT_GR; if ((in & 0xff) == 0) return keyboard_map[(in & 0xff00) >> 8] | flags; @@ -83,34 +95,25 @@ get_abstract_code (grub_term_input_t term, int in) } static grub_uint32_t mapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - -static unsigned -clear_internal_flags (unsigned in) -{ - if (in & GRUB_TERM_ALT_GR) - in = (in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT; - return in & ~GRUB_TERM_CAPS & ~GRUB_TERM_KEYPAD; -} +static grub_uint32_t mapping_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; static unsigned map (grub_term_input_t term __attribute__ ((unused)), unsigned in) { if (in & GRUB_TERM_KEYPAD) - return clear_internal_flags (in); - - /* AltGr isn't supported yet. */ - if (in & GRUB_TERM_ALT_GR) - in = (in & ~GRUB_TERM_ALT_GR) | GRUB_TERM_ALT; + return in; if ((in & GRUB_TERM_EXTENDED) || (in & GRUB_TERM_KEY_MASK) == '\b' || (in & GRUB_TERM_KEY_MASK) == '\n' || (in & GRUB_TERM_KEY_MASK) == ' ' || (in & GRUB_TERM_KEY_MASK) == '\t' || (in & GRUB_TERM_KEY_MASK) == '\e' || (in & GRUB_TERM_KEY_MASK) == '\r' || (in & GRUB_TERM_KEY_MASK) >= ARRAY_SIZE (mapping)) - return clear_internal_flags (in); + return in; - return mapping[in & GRUB_TERM_KEY_MASK] - | clear_internal_flags (in & ~GRUB_TERM_KEY_MASK); + if ((in & GRUB_TERM_ALT_GR) && mapping_alt[in & GRUB_TERM_KEY_MASK]) + return mapping_alt[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK & ~GRUB_TERM_ALT_GR); + + return mapping[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK); } static int @@ -118,6 +121,9 @@ translate (grub_term_input_t term, int in) { int code, flags; code = get_abstract_code (term, in); + + flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD | GRUB_TERM_CAPS); + if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'a' && (code & GRUB_TERM_KEY_MASK) <= 'z') code = (code & GRUB_TERM_KEY_MASK) + 'A' - 'a'; @@ -125,7 +131,6 @@ translate (grub_term_input_t term, int in) && (code & GRUB_TERM_KEY_MASK) <= 'Z') code = (code & GRUB_TERM_KEY_MASK) + 'a' - 'A'; - flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD); code &= (GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD); code = map (term, code); /* Transform unconsumed AltGr into Alt. */ @@ -134,6 +139,8 @@ translate (grub_term_input_t term, int in) flags |= GRUB_TERM_ALT; code &= ~GRUB_TERM_ALT_GR; } + code &= ~GRUB_TERM_KEYPAD; + if ((flags & GRUB_TERM_CAPS) && code >= 'a' && code <= 'z') code += 'A' - 'a'; else if ((flags & GRUB_TERM_CAPS) && code >= 'A' @@ -186,6 +193,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), grub_uint32_t version; grub_uint8_t magic[GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE]; grub_uint32_t newmapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t newmapping_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; unsigned i; if (argc < 1) @@ -241,9 +249,20 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), goto fail; } + if (grub_file_read (file, newmapping_alt, sizeof (newmapping_alt)) + != sizeof (newmapping_alt)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); + goto fail; + } + for (i = 0; i < ARRAY_SIZE (mapping); i++) mapping[i] = grub_le_to_cpu32(newmapping[i]); + for (i = 0; i < ARRAY_SIZE (mapping_alt); i++) + mapping_alt[i] = grub_le_to_cpu32(newmapping_alt[i]); + return GRUB_ERR_NONE; fail: @@ -263,6 +282,7 @@ GRUB_MOD_INIT(keylayouts) unsigned i; for (i = 0; i < ARRAY_SIZE (mapping); i++) mapping[i] = i; + grub_memset (mapping_alt, 0, sizeof (mapping_alt)); mapping[GRUB_TERM_KEY_102] = '\\'; mapping[GRUB_TERM_KEY_SHIFT_102] = '|'; diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index 1d263e268..081e9ca98 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,7 +21,7 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 2 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 3 #define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 256 diff --git a/term/at_keyboard.c b/term/at_keyboard.c index cc0c69e22..5adc8b4da 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -34,6 +34,7 @@ static int pending_key = -1; #define KEYBOARD_STATUS_CTRL_R (1 << 5) #define KEYBOARD_STATUS_CAPS_LOCK (1 << 6) #define KEYBOARD_STATUS_NUM_LOCK (1 << 7) +#define KEYBOARD_STATUS_EXTENDED (1 << 8) static grub_uint8_t led_status; @@ -80,12 +81,10 @@ keyboard_controller_led (grub_uint8_t leds) /* FIXME: This should become an interrupt service routine. For now it's just used to catch events from control keys. */ static void -grub_keyboard_isr (char key) +grub_keyboard_isr (grub_uint8_t key) { - char is_make = KEYBOARD_ISMAKE (key); - key = KEYBOARD_SCANCODE (key); - if (is_make) - switch (key) + if (KEYBOARD_ISMAKE (key)) + switch (KEYBOARD_SCANCODE (key)) { case SHIFT_L: at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L; @@ -97,14 +96,14 @@ grub_keyboard_isr (char key) at_keyboard_status |= KEYBOARD_STATUS_CTRL_L; break; case ALT: - at_keyboard_status |= KEYBOARD_STATUS_ALT_L; + if (at_keyboard_status & KEYBOARD_STATUS_EXTENDED) + at_keyboard_status |= KEYBOARD_STATUS_ALT_R; + else + at_keyboard_status |= KEYBOARD_STATUS_ALT_L; break; - default: - /* Skip grub_dprintf. */ - return; } else - switch (key) + switch (KEYBOARD_SCANCODE (key)) { case SHIFT_L: at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L; @@ -116,15 +115,17 @@ grub_keyboard_isr (char key) at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L; break; case ALT: - at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L; + if (at_keyboard_status & KEYBOARD_STATUS_EXTENDED) + at_keyboard_status &= ~KEYBOARD_STATUS_ALT_R; + else + at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L; break; - default: - /* Skip grub_dprintf. */ - return; } -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "Control key 0x%0x was %s\n", key, is_make ? "pressed" : "unpressed"); -#endif + if (key == 0xe0) + at_keyboard_status |= KEYBOARD_STATUS_EXTENDED; + else + at_keyboard_status &= ~KEYBOARD_STATUS_EXTENDED; + } /* If there is a raw key pending, return it; otherwise return -1. */ @@ -210,9 +211,15 @@ grub_at_keyboard_getkey_noblock (void) } if (at_keyboard_status & KEYBOARD_STATUS_ALT_L) - key |= GRUB_TERM_ALT; + { + key |= GRUB_TERM_ALT; + grub_printf ("AltL"); + } if (at_keyboard_status & KEYBOARD_STATUS_ALT_R) - key |= GRUB_TERM_ALT_GR; + { + key |= GRUB_TERM_ALT_GR; + grub_printf ("AltGr"); + } if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) key |= GRUB_TERM_CTRL; diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 48b17e798..434f9f4f8 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -115,7 +115,8 @@ get_grub_code (char *layout_code) } void -write_file (char* filename, grub_uint32_t *keyboard_map) +write_file (char* filename, grub_uint32_t *keyboard_map, + grub_uint32_t *keyboard_map_alt) { FILE *fp_output; grub_uint32_t version; @@ -126,6 +127,9 @@ write_file (char* filename, grub_uint32_t *keyboard_map) for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) keyboard_map[i] = grub_cpu_to_le32 (keyboard_map[i]); + for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) + keyboard_map_alt[i] = grub_cpu_to_le32 (keyboard_map_alt[i]); + fp_output = fopen (filename, "w"); if (!fp_output) @@ -139,6 +143,8 @@ write_file (char* filename, grub_uint32_t *keyboard_map) fwrite (&version, sizeof (version), 1, fp_output); fwrite (keyboard_map, sizeof (keyboard_map[0]), GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output); + fwrite (keyboard_map_alt, sizeof (keyboard_map_alt[0]), + GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output); fclose (fp_output); } @@ -146,6 +152,7 @@ void write_keymaps (char *keymap, char *file_basename) { grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; char line[2048]; pid_t pid; @@ -189,11 +196,17 @@ write_keymaps (char *keymap, char *file_basename) unsigned keycode; char normal[64]; char shift[64]; - sscanf (line, "keycode %u = %60s %60s", &keycode, normal, shift); + char normalalt[64]; + char shiftalt[64]; + + sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode, + normal, shift, normalalt, shiftalt); if (keycode < ARRAY_SIZE (us_keyboard_map) && us_keyboard_map[keycode] < ARRAY_SIZE (keyboard_map)) { keyboard_map[us_keyboard_map[keycode]] = get_grub_code (normal); + keyboard_map_alt[us_keyboard_map[keycode]] + = get_grub_code (normalalt); ok = 1; } if (keycode < ARRAY_SIZE (us_keyboard_map_shifted) @@ -201,6 +214,8 @@ write_keymaps (char *keymap, char *file_basename) { keyboard_map[us_keyboard_map_shifted[keycode]] = get_grub_code (shift); + keyboard_map_alt[us_keyboard_map_shifted[keycode]] + = get_grub_code (shiftalt); ok = 1; } } @@ -213,7 +228,7 @@ write_keymaps (char *keymap, char *file_basename) exit (1); } - write_file (file_basename, keyboard_map); + write_file (file_basename, keyboard_map, keyboard_map_alt); } int From ed19677fe3e6a1217260186d9e1a2494b9ff6cd2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 13:32:36 +0200 Subject: [PATCH 0049/1414] Revert all parts done for BIOS keymap translation --- commands/keylayouts.c | 204 ++++---------------------------- include/grub/at_keyboard.h | 49 -------- include/grub/i386/pc/console.h | 13 -- include/grub/keyboard_layouts.h | 24 +++- include/grub/term.h | 63 ++++------ kern/i386/pc/startup.S | 34 +++++- kern/term.c | 23 +++- term/at_keyboard.c | 55 ++++++--- term/i386/pc/console.c | 3 +- term/usb_keyboard.c | 7 +- util/grub-fstest.c | 6 +- util/grub-mklayouts.c | 20 ---- util/grub-probe.c | 6 +- util/i386/pc/grub-setup.c | 6 +- 14 files changed, 166 insertions(+), 347 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 25a117560..bfe30d2ab 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -23,167 +23,11 @@ #include #include #include -#include #include #include #include #include -GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); - -static int -get_abstract_code (grub_term_input_t term, int in) -{ - switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) - { - case GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES: - default: - return in; - case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS: - { - unsigned status = 0; - unsigned flags = 0; - - if (term->getkeystatus) - status = term->getkeystatus (term); - if (status & GRUB_TERM_CAPS) - flags |= GRUB_TERM_CAPS; - - if ((0x5600 | '\\') == (in & 0xffff)) - return GRUB_TERM_KEY_102 | flags; - - if ((0x5600 | '|') == (in & 0xffff)) - return GRUB_TERM_KEY_SHIFT_102 | flags; - - if ((in & 0xff00) == 0x3500 || (in & 0xff00) == 0x3700 - || (in & 0xff00) == 0x4500 - || ((in & 0xff00) >= 0x4700 && (in & 0xff00) <= 0x5300)) - flags |= GRUB_TERM_KEYPAD; - - /* Detect CTRL'ed keys. */ - if ((in & 0xff) > 0 && (in & 0xff) < 0x20 - && ((in & 0xffff) != (0x0100 | '\e')) - && ((in & 0xffff) != (0x0f00 | '\t')) - && ((in & 0xffff) != (0x0e00 | '\b')) - && ((in & 0xffff) != (0x1c00 | '\r')) - && ((in & 0xffff) != (0x1c00 | '\n'))) - return ((in & 0xff) - 1 + 'a') | flags | GRUB_TERM_CTRL; - /* Detect ALT'ed keys. */ - /* XXX no way to distinguish left and right ALT. */ - if (((in & 0xff) == 0) && keyboard_map[(in & 0xff00) >> 8] >= 'a' - && keyboard_map[(in & 0xff00) >> 8] <= 'z') - return keyboard_map[(in & 0xff00) >> 8] | flags | GRUB_TERM_ALT_GR; - if ((in & 0xff) == 0 && (in & 0xff00) >= 0x7800 - && (in & 0xff00) <= 0x8000) - return (((in & 0xff00) >> 8) - 0x78 + '1') | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xff00) == 0x8100) - return '0' | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xffff) == 0x8200) - return '-' | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xffff) == 0x8300) - return '+' | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xff) == 0) - return keyboard_map[(in & 0xff00) >> 8] | flags; - - return (in & 0xff) | flags; - } - } -} - -static grub_uint32_t mapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; -static grub_uint32_t mapping_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - -static unsigned -map (grub_term_input_t term __attribute__ ((unused)), unsigned in) -{ - if (in & GRUB_TERM_KEYPAD) - return in; - - if ((in & GRUB_TERM_EXTENDED) || (in & GRUB_TERM_KEY_MASK) == '\b' - || (in & GRUB_TERM_KEY_MASK) == '\n' || (in & GRUB_TERM_KEY_MASK) == ' ' - || (in & GRUB_TERM_KEY_MASK) == '\t' || (in & GRUB_TERM_KEY_MASK) == '\e' - || (in & GRUB_TERM_KEY_MASK) == '\r' - || (in & GRUB_TERM_KEY_MASK) >= ARRAY_SIZE (mapping)) - return in; - - if ((in & GRUB_TERM_ALT_GR) && mapping_alt[in & GRUB_TERM_KEY_MASK]) - return mapping_alt[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK & ~GRUB_TERM_ALT_GR); - - return mapping[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK); -} - -static int -translate (grub_term_input_t term, int in) -{ - int code, flags; - code = get_abstract_code (term, in); - - flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD | GRUB_TERM_CAPS); - - if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'a' - && (code & GRUB_TERM_KEY_MASK) <= 'z') - code = (code & GRUB_TERM_KEY_MASK) + 'A' - 'a'; - else if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'A' - && (code & GRUB_TERM_KEY_MASK) <= 'Z') - code = (code & GRUB_TERM_KEY_MASK) + 'a' - 'A'; - - code &= (GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD); - code = map (term, code); - /* Transform unconsumed AltGr into Alt. */ - if (code & GRUB_TERM_ALT_GR) - { - flags |= GRUB_TERM_ALT; - code &= ~GRUB_TERM_ALT_GR; - } - code &= ~GRUB_TERM_KEYPAD; - - if ((flags & GRUB_TERM_CAPS) && code >= 'a' && code <= 'z') - code += 'A' - 'a'; - else if ((flags & GRUB_TERM_CAPS) && code >= 'A' - && code <= 'Z') - code += 'a' - 'A'; - return code | flags; -} - -static int -grub_getkey_smart (void) -{ - grub_term_input_t term; - - grub_refresh (); - - while (1) - { - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->checkkey (term); - if (key != -1) - return translate (term, term->getkey (term)); - } - - grub_cpu_idle (); - } -} - -int -grub_checkkey (void) -{ - grub_term_input_t term; - - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->checkkey (term); - if (key != -1) - return translate (term, key); - } - - return -1; -} - static grub_err_t grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), int argc, char *argv[]) @@ -192,8 +36,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), grub_file_t file; grub_uint32_t version; grub_uint8_t magic[GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE]; - grub_uint32_t newmapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t newmapping_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + struct grub_keyboard_layout *newmap = NULL; unsigned i; if (argc < 1) @@ -241,60 +84,53 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), goto fail; } - if (grub_file_read (file, newmapping, sizeof (newmapping)) - != sizeof (newmapping)) + newmap = grub_malloc (sizeof (*newmap)); + if (!newmap) + goto fail; + + if (grub_file_read (file, newmap, sizeof (*newmap)) != sizeof (*newmap)) { if (!grub_errno) grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); goto fail; } - if (grub_file_read (file, newmapping_alt, sizeof (newmapping_alt)) - != sizeof (newmapping_alt)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); - goto fail; - } + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map); i++) + newmap->at.keyboard_map[i] = grub_le_to_cpu32(newmap->at.keyboard_map[i]); - for (i = 0; i < ARRAY_SIZE (mapping); i++) - mapping[i] = grub_le_to_cpu32(newmapping[i]); + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_shift); i++) + newmap->at.keyboard_map_shift[i] + = grub_le_to_cpu32(newmap->at.keyboard_map_shift[i]); - for (i = 0; i < ARRAY_SIZE (mapping_alt); i++) - mapping_alt[i] = grub_le_to_cpu32(newmapping_alt[i]); + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_l3); i++) + newmap->at.keyboard_map_l3[i] + = grub_le_to_cpu32(newmap->at.keyboard_map_l3[i]); + + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_shift_l3); i++) + newmap->at.keyboard_map_shift_l3[i] + = grub_le_to_cpu32(newmap->at.keyboard_map_shift_l3[i]); return GRUB_ERR_NONE; fail: if (filename != argv[0]) grub_free (filename); + grub_free (newmap); if (file) grub_file_close (file); return grub_errno; } -static int (*grub_getkey_saved) (void); - static grub_command_t cmd; GRUB_MOD_INIT(keylayouts) { - unsigned i; - for (i = 0; i < ARRAY_SIZE (mapping); i++) - mapping[i] = i; - grub_memset (mapping_alt, 0, sizeof (mapping_alt)); - mapping[GRUB_TERM_KEY_102] = '\\'; - mapping[GRUB_TERM_KEY_SHIFT_102] = '|'; - - grub_getkey_saved = grub_getkey; - grub_getkey = grub_getkey_smart; - cmd = grub_register_command ("keymap", grub_cmd_keymap, 0, N_("Load a keyboard layout.")); } GRUB_MOD_FINI(keylayouts) { - grub_getkey = grub_getkey_saved; + grub_current_layout = NULL; grub_unregister_command (cmd); } diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index e8289d672..10421540a 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -51,53 +51,4 @@ #define OLPC_RIGHT '\0' #endif -#define GRUB_AT_KEY_KEYBOARD_MAP(name) \ -static const unsigned name[128] = \ -{ \ - /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', \ - /* 0x08 */ '7', '8', '9', '0', \ - /* 0x0c */ '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, \ - /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', \ - /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', \ - /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', \ - /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', \ - /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*' | GRUB_TERM_KEYPAD, \ - /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, \ - /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, \ - /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, \ - /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, \ - /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, \ - /* 0x44 */ GRUB_TERM_KEY_F10, '\0', \ - /* 0x46 */ '\0', GRUB_TERM_KEY_HOME, \ - /* 0x48 */ GRUB_TERM_KEY_UP, \ - /* 0x49 */ GRUB_TERM_KEY_NPAGE, \ - /* 0x4a */ '-' | GRUB_TERM_KEYPAD, \ - /* 0x4b */ GRUB_TERM_KEY_LEFT, \ - /* 0x4c */ GRUB_TERM_KEY_CENTER | GRUB_TERM_KEYPAD, \ - /* 0x4d */ GRUB_TERM_KEY_RIGHT, \ - /* 0x4e */ '+' | GRUB_TERM_KEYPAD, \ - /* 0x4f */ GRUB_TERM_KEY_END, \ - /* 0x50 */ GRUB_TERM_KEY_DOWN, \ - /* 0x51 */ GRUB_TERM_KEY_PPAGE, \ - /* 0x52 */ GRUB_TERM_KEY_INSERT, \ - /* 0x53 */ GRUB_TERM_KEY_DC, \ - /* 0x54 */ '\0', '\0', GRUB_TERM_KEY_102, GRUB_TERM_KEY_F11, \ - /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', \ - /* 0x60 */ '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, \ - /* 0x68 */ OLPC_RIGHT \ -} - -#define GRUB_AT_KEY_KEYBOARD_MAP_SHIFT(name) \ -static unsigned name[128] = \ -{ \ - '\0', '\0', '!', '@', '#', '$', '%', '^', \ - '&', '*', '(', ')', '_', '+', '\0', '\0', \ - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', \ - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', \ - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', \ - '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', \ - 'B', 'N', 'M', '<', '>', '?', \ - [0x56] = GRUB_TERM_KEY_SHIFT_102 \ -} - #endif diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index 7f58344ec..fabb13d5c 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -19,19 +19,6 @@ #ifndef GRUB_CONSOLE_MACHINE_HEADER #define GRUB_CONSOLE_MACHINE_HEADER 1 -/* Define scan codes. */ -#define GRUB_CONSOLE_KEY_LEFT 0x4B00 -#define GRUB_CONSOLE_KEY_RIGHT 0x4D00 -#define GRUB_CONSOLE_KEY_UP 0x4800 -#define GRUB_CONSOLE_KEY_DOWN 0x5000 -#define GRUB_CONSOLE_KEY_IC 0x5200 -#define GRUB_CONSOLE_KEY_DC 0x5300 -#define GRUB_CONSOLE_KEY_BACKSPACE 0x0008 -#define GRUB_CONSOLE_KEY_HOME 0x4700 -#define GRUB_CONSOLE_KEY_END 0x4F00 -#define GRUB_CONSOLE_KEY_NPAGE 0x5100 -#define GRUB_CONSOLE_KEY_PPAGE 0x4900 - #ifndef ASM_FILE #include diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index 081e9ca98..2d6e3d54c 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,8 +21,28 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 3 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 4 -#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 256 +#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 + +struct grub_keyboard_layout +{ + struct + { + grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + } at; + struct + { + grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + } usb; +}; + +struct grub_keyboard_layout *EXPORT_VAR (grub_current_layout); #endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/include/grub/term.h b/include/grub/term.h index f2f80152f..036e8caaa 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -24,41 +24,34 @@ #define GRUB_TERM_SHIFT 0x01000000 #define GRUB_TERM_CTRL 0x02000000 #define GRUB_TERM_ALT 0x04000000 -/* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_ALT_GR 0x08000000 -#define GRUB_TERM_CAPS 0x10000000 -#define GRUB_TERM_KEYPAD 0x20000000 /* Keys without associated character. */ #define GRUB_TERM_EXTENDED 0x00800000 #define GRUB_TERM_KEY_MASK 0x00ffffff -#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 1) -#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 2) -#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 3) -#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 4) -#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 5) -#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 6) -#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 7) -#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 8) -#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 9) -#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 10) -#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 11) -#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 12) -#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 13) -#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 14) -#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 15) -#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 16) -#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 17) -#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 18) -#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 19) -#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 20) -#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 21) -#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 22) -#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 23) -/* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_KEY_102 0x80 -#define GRUB_TERM_KEY_SHIFT_102 0x81 +#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 0x4b) +#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 0x4d) +#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 0x48) +#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 0x50) +#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 0x47) +#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 0x4f) +#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 0x53) +#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 0x49) +#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 0x51) +#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 0x3b) +#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 0x3c) +#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 0x3d) +#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 0x3e) +#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 0x3f) +#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 0x40) +#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 0x41) +#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 0x42) +#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 0x43) +#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 0x44) +#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 0x57) +#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 0x58) +#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52) +#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c) #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' @@ -168,16 +161,10 @@ struct grub_term_input /* Get keyboard modifier status. */ int (*getkeystatus) (struct grub_term_input *term); - grub_uint32_t flags; - void *data; }; typedef struct grub_term_input *grub_term_input_t; -#define GRUB_TERM_INPUT_FLAGS_TYPE_MASK 0xf -#define GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES 0x0 -#define GRUB_TERM_INPUT_FLAGS_TYPE_BIOS 0x1 - struct grub_term_output { /* The next terminal. */ @@ -314,8 +301,8 @@ grub_term_unregister_output (grub_term_output_t term) #define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) void grub_putcode (grub_uint32_t code, struct grub_term_output *term); -extern int (*EXPORT_VAR(grub_getkey)) (void); -int grub_checkkey (void); +int EXPORT_FUNC(grub_getkey) (void); +int EXPORT_FUNC(grub_checkkey) (void); void grub_cls (void); void EXPORT_FUNC(grub_refresh) (void); void grub_puts_terminal (const char *str, struct grub_term_output *term); diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index cbc4c5cfb..ef5904bb2 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1147,6 +1147,11 @@ FUNCTION(grub_console_putchar) ret +LOCAL(bypass_table): + .word 0x0100 | '\e',0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r' + .word 0x1c00 | '\n' +LOCAL(bypass_table_end): + /* * int grub_console_getkey (void) * BIOS call "INT 16H Function 00H" to read character from keyboard @@ -1180,17 +1185,39 @@ FUNCTION(grub_console_getkey) movb $0, %ah int $0x16 + xorl %edx, %edx movw %ax, %dx /* real_to_prot uses %eax */ DATA32 call real_to_prot .code32 - movw %dx, %ax + movl $0xff, %eax + testl %eax, %edx + jz 1f + + andl %edx, %eax + cmp %eax, 0x20 + ja 2f + movl %edx, %eax + leal LOCAL(bypass_table), %esi + movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx + repne cmpsw + jz 3f + + addl $('a' - 1 | GRUB_TERM_CTRL), %eax + jmp 2f +3: + andl $0xff, %eax + jmp 2f + +1: movl %edx, %eax + shrl $8, %eax + orl $GRUB_TERM_EXTENDED, %eax +2: popl %ebp ret - /* * int grub_console_checkkey (void) * if there is a character pending, return it; otherwise return -1 @@ -1216,6 +1243,7 @@ FUNCTION(grub_console_checkkey) jz notpending + xorl %edx, %edx movw %ax, %dx DATA32 jmp pending @@ -1226,8 +1254,6 @@ pending: DATA32 call real_to_prot .code32 - movl %edx, %eax - popl %ebp ret diff --git a/kern/term.c b/kern/term.c index d582dbb68..04d20364a 100644 --- a/kern/term.c +++ b/kern/term.c @@ -22,11 +22,13 @@ #include #include #include +#include struct grub_term_output *grub_term_outputs_disabled; struct grub_term_input *grub_term_inputs_disabled; struct grub_term_output *grub_term_outputs; struct grub_term_input *grub_term_inputs; +struct grub_keyboard_layout *grub_current_layout; /* Put a Unicode character. */ static void @@ -76,8 +78,8 @@ grub_xputs_dumb (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_dumb; -static int -grub_getkey_dumb (void) +int +grub_getkey (void) { grub_term_input_t term; @@ -89,14 +91,27 @@ grub_getkey_dumb (void) { int key = term->checkkey (term); if (key != -1) - return term->getkey (term) & 0xff; + return term->getkey (term); } grub_cpu_idle (); } } -int (*grub_getkey) (void) = grub_getkey_dumb; +int +grub_checkkey (void) +{ + grub_term_input_t term; + + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->checkkey (term); + if (key != -1) + return key; + } + + return -1; +} void grub_refresh (void) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 5adc8b4da..492075115 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -42,8 +42,43 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_CAPS (1 << 2) -GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); -GRUB_AT_KEY_KEYBOARD_MAP_SHIFT (keyboard_map_shift); +static const unsigned keyboard_map[128] = +{ + /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', + /* 0x08 */ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, + /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', + /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', + /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', + /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, + /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, + /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, + /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, + /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, + /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, + /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, + /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, + /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, + /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, + /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, + /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', + /* 0x60 */ '\0', '\0', '\0', '\0', + /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, + /* 0x68 */ GRUB_TERM_KEY_RIGHT +}; + +static unsigned keyboard_map_shift[128] = +{ + '\0', '\0', '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '\0', '\0', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', + [0x56] = '|' +}; static grub_uint8_t grub_keyboard_controller_orig; @@ -211,21 +246,12 @@ grub_at_keyboard_getkey_noblock (void) } if (at_keyboard_status & KEYBOARD_STATUS_ALT_L) - { - key |= GRUB_TERM_ALT; - grub_printf ("AltL"); - } + key |= GRUB_TERM_ALT; if (at_keyboard_status & KEYBOARD_STATUS_ALT_R) - { - key |= GRUB_TERM_ALT_GR; - grub_printf ("AltGr"); - } + key |= GRUB_TERM_ALT; if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) key |= GRUB_TERM_CTRL; - - if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK) - key |= GRUB_TERM_CAPS; } return key; } @@ -284,8 +310,7 @@ static struct grub_term_input grub_at_keyboard_term = .init = grub_keyboard_controller_init, .fini = grub_keyboard_controller_fini, .checkkey = grub_at_keyboard_checkkey, - .getkey = grub_at_keyboard_getkey, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES + .getkey = grub_at_keyboard_getkey }; GRUB_MOD_INIT(at_keyboard) diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 1bf954874..74df4c27f 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -50,8 +50,7 @@ static struct grub_term_input grub_console_term_input = .name = "console", .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, - .getkeystatus = grub_console_getkeystatus, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_BIOS + .getkeystatus = grub_console_getkeystatus }; static struct grub_term_output grub_console_term_output = diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 9e1ce5e60..3432f700c 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -43,7 +43,7 @@ static unsigned keyboard_map[128] = '\0', GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP, - [0x64] = GRUB_TERM_KEY_102 + [0x64] = '\\' }; static unsigned keyboard_map_shift[128] = @@ -56,7 +56,7 @@ static unsigned keyboard_map_shift[128] = '\n', '\0', '\0', '\0', ' ', '_', '+', '{', '}', '|', '#', ':', '"', '`', '<', '>', '?', - [0x64] = GRUB_TERM_KEY_SHIFT_102 + [0x64] = '|' }; static grub_usb_device_t usbdev; @@ -186,7 +186,7 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) key |= GRUB_TERM_ALT; if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT) - key |= GRUB_TERM_ALT_GR; + key |= GRUB_TERM_ALT; #if 0 /* Wait until the key is released. */ @@ -341,7 +341,6 @@ static struct grub_term_input grub_usb_keyboard_term = .checkkey = grub_usb_keyboard_checkkey, .getkey = grub_usb_keyboard_getkey, .getkeystatus = grub_usb_keyboard_getkeystatus, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES, .next = 0 }; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 715dfe2dd..2c80b964c 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -51,14 +51,12 @@ grub_xputs_real (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_real; -static int -grub_getkey_real (void) +int +grub_getkey (void) { return -1; } -int (*grub_getkey) (void) = grub_getkey_real; - void grub_refresh (void) { diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 434f9f4f8..9aca88cb1 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -67,9 +67,6 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"", '\0'} }; -GRUB_AT_KEY_KEYBOARD_MAP (us_keyboard_map); -GRUB_AT_KEY_KEYBOARD_MAP_SHIFT (us_keyboard_map_shifted); - static void usage (int status) { @@ -201,23 +198,6 @@ write_keymaps (char *keymap, char *file_basename) sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode, normal, shift, normalalt, shiftalt); - if (keycode < ARRAY_SIZE (us_keyboard_map) - && us_keyboard_map[keycode] < ARRAY_SIZE (keyboard_map)) - { - keyboard_map[us_keyboard_map[keycode]] = get_grub_code (normal); - keyboard_map_alt[us_keyboard_map[keycode]] - = get_grub_code (normalalt); - ok = 1; - } - if (keycode < ARRAY_SIZE (us_keyboard_map_shifted) - && us_keyboard_map_shifted[keycode] < ARRAY_SIZE (keyboard_map)) - { - keyboard_map[us_keyboard_map_shifted[keycode]] - = get_grub_code (shift); - keyboard_map_alt[us_keyboard_map_shifted[keycode]] - = get_grub_code (shiftalt); - ok = 1; - } } } diff --git a/util/grub-probe.c b/util/grub-probe.c index e4d3f2906..56cbc5592 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -68,14 +68,12 @@ grub_xputs_real (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_real; -static int -grub_getkey_real (void) +int +grub_getkey (void) { return -1; } -int (*grub_getkey) (void) = grub_getkey_real; - void grub_refresh (void) { diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 4e3980965..524572fad 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -72,14 +72,12 @@ grub_xputs_real (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_real; -static int -grub_getkey_real (void) +int +grub_getkey (void) { return -1; } -int (*grub_getkey) (void) = grub_getkey_real; - void grub_refresh (void) { From e55e09628d0f67ecf87b0d3b0bdad140bd48bdce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 15:00:31 +0200 Subject: [PATCH 0050/1414] Hook AT keyboard mapping --- commands/keylayouts.c | 127 ++++++++++++++++++++++++++++++- commands/keystatus.c | 6 +- include/grub/keyboard_layouts.h | 30 ++++---- include/grub/term.h | 12 ++- kern/term.c | 2 - term/at_keyboard.c | 129 ++++++-------------------------- term/i386/pc/console.c | 18 +---- term/usb_keyboard.c | 20 +++-- util/grub-mklayouts.c | 119 ++++++++++++++++++++++++----- 9 files changed, 290 insertions(+), 173 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index bfe30d2ab..b7aee7fab 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -28,6 +28,115 @@ #include #include +static struct grub_keyboard_layout layout_us = { + .at = { + .keyboard_map = { + /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', + /* 0x08 */ '7', '8', '9', '0', + /* 0x0c */ '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, + /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', + /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', + /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', + /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, + /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, + /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, + /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, + /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, + /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, + /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, + /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, + /* 0x4e */ '+', GRUB_TERM_KEY_END, + /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, + /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, + /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, + /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', + /* 0x60 */ '\0', '\0', '\0', '\0', + /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, + /* 0x68 */ GRUB_TERM_KEY_RIGHT + }, + .keyboard_map_shift = { + '\0', '\0', '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '\0', '\0', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', + [0x56] = '|' + } + } +}; + +static struct grub_keyboard_layout *grub_current_layout = &layout_us; + +static int +map_key_core (int code, int status, int *alt_gr_consumed) +{ + *alt_gr_consumed = 0; + + if (status & GRUB_TERM_STATUS_RALT) + { + if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) + { + if (grub_current_layout->at.keyboard_map_shift_l3[code]) + { + *alt_gr_consumed = 1; + return grub_current_layout->at.keyboard_map_shift_l3[code]; + } + else if (grub_current_layout->at.keyboard_map_shift[code]) + { + *alt_gr_consumed = 1; + return grub_current_layout->at.keyboard_map_l3[code] + | GRUB_TERM_SHIFT; + } + } + else if (grub_current_layout->at.keyboard_map_shift[code]) + { + *alt_gr_consumed = 1; + return grub_current_layout->at.keyboard_map_l3[code]; + } + } + if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) + { + if (grub_current_layout->at.keyboard_map_shift[code]) + return grub_current_layout->at.keyboard_map_shift[code]; + else + return grub_current_layout->at.keyboard_map[code] | GRUB_TERM_SHIFT; + } + else + return grub_current_layout->at.keyboard_map[code]; +} + +unsigned +grub_term_map_key (int code, int status) +{ + int alt_gr_consumed; + int key; + + key = map_key_core (code, status, &alt_gr_consumed); + + if (key == 0 || key == GRUB_TERM_SHIFT) + grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); + + if (status & GRUB_TERM_STATUS_CAPS) + { + if ((key >= 'a') && (key <= 'z')) + key += 'A' - 'a'; + else if ((key >= 'A') && (key <= 'Z')) + key += 'a' - 'A'; + } + + if ((status & GRUB_TERM_STATUS_LALT) || + ((status & GRUB_TERM_STATUS_RALT) && !alt_gr_consumed)) + key |= GRUB_TERM_ALT; + if (status & (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL)) + key |= GRUB_TERM_CTRL; + + return key; +} + static grub_err_t grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), int argc, char *argv[]) @@ -110,6 +219,23 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), newmap->at.keyboard_map_shift_l3[i] = grub_le_to_cpu32(newmap->at.keyboard_map_shift_l3[i]); + for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map); i++) + newmap->usb.keyboard_map[i] = grub_le_to_cpu32(newmap->usb.keyboard_map[i]); + + for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_shift); i++) + newmap->usb.keyboard_map_shift[i] + = grub_le_to_cpu32(newmap->usb.keyboard_map_shift[i]); + + for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_l3); i++) + newmap->usb.keyboard_map_l3[i] + = grub_le_to_cpu32(newmap->usb.keyboard_map_l3[i]); + + for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_shift_l3); i++) + newmap->usb.keyboard_map_shift_l3[i] + = grub_le_to_cpu32(newmap->usb.keyboard_map_shift_l3[i]); + + grub_current_layout = newmap; + return GRUB_ERR_NONE; fail: @@ -131,6 +257,5 @@ GRUB_MOD_INIT(keylayouts) GRUB_MOD_FINI(keylayouts) { - grub_current_layout = NULL; grub_unregister_command (cmd); } diff --git a/commands/keystatus.c b/commands/keystatus.c index 9db92b942..9c7ab84b0 100644 --- a/commands/keystatus.c +++ b/commands/keystatus.c @@ -56,11 +56,11 @@ grub_cmd_keystatus (grub_extcmd_t cmd, int mods; if (state[0].set) - expect_mods |= GRUB_TERM_STATUS_SHIFT; + expect_mods |= (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT); if (state[1].set) - expect_mods |= GRUB_TERM_STATUS_CTRL; + expect_mods |= (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL); if (state[2].set) - expect_mods |= GRUB_TERM_STATUS_ALT; + expect_mods |= (GRUB_TERM_STATUS_LALT | GRUB_TERM_STATUS_RALT); grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods); diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index 2d6e3d54c..6d4b620c2 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,28 +21,24 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 4 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 5 #define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 -struct grub_keyboard_layout +struct grub_keyboard_layout_kbd { - struct - { - grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - } at; - struct - { - grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - } usb; + grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; }; -struct grub_keyboard_layout *EXPORT_VAR (grub_current_layout); +struct grub_keyboard_layout +{ + struct grub_keyboard_layout_kbd at; + struct grub_keyboard_layout_kbd usb; +}; + +unsigned grub_term_map_key (int code, int status); #endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/include/grub/term.h b/include/grub/term.h index 036e8caaa..de430d66f 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -110,9 +110,15 @@ grub_term_color_state; /* Bitmasks for modifier keys returned by grub_getkeystatus. */ -#define GRUB_TERM_STATUS_SHIFT (1 << 0) -#define GRUB_TERM_STATUS_CTRL (1 << 1) -#define GRUB_TERM_STATUS_ALT (1 << 2) +#define GRUB_TERM_STATUS_RSHIFT (1 << 0) +#define GRUB_TERM_STATUS_LSHIFT (1 << 1) +#define GRUB_TERM_STATUS_RCTRL (1 << 2) +#define GRUB_TERM_STATUS_RALT (1 << 3) +#define GRUB_TERM_STATUS_SCROLL (1 << 4) +#define GRUB_TERM_STATUS_NUM (1 << 5) +#define GRUB_TERM_STATUS_CAPS (1 << 6) +#define GRUB_TERM_STATUS_LCTRL (1 << 8) +#define GRUB_TERM_STATUS_LALT (1 << 9) /* Menu-related geometrical constants. */ diff --git a/kern/term.c b/kern/term.c index 04d20364a..6ddf63208 100644 --- a/kern/term.c +++ b/kern/term.c @@ -22,13 +22,11 @@ #include #include #include -#include struct grub_term_output *grub_term_outputs_disabled; struct grub_term_input *grub_term_inputs_disabled; struct grub_term_output *grub_term_outputs; struct grub_term_input *grub_term_inputs; -struct grub_keyboard_layout *grub_current_layout; /* Put a Unicode character. */ static void diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 492075115..054dc9805 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -22,64 +22,18 @@ #include #include #include +#include static short at_keyboard_status = 0; +static int extended_pending = 0; static int pending_key = -1; -#define KEYBOARD_STATUS_SHIFT_L (1 << 0) -#define KEYBOARD_STATUS_SHIFT_R (1 << 1) -#define KEYBOARD_STATUS_ALT_L (1 << 2) -#define KEYBOARD_STATUS_ALT_R (1 << 3) -#define KEYBOARD_STATUS_CTRL_L (1 << 4) -#define KEYBOARD_STATUS_CTRL_R (1 << 5) -#define KEYBOARD_STATUS_CAPS_LOCK (1 << 6) -#define KEYBOARD_STATUS_NUM_LOCK (1 << 7) -#define KEYBOARD_STATUS_EXTENDED (1 << 8) - static grub_uint8_t led_status; #define KEYBOARD_LED_SCROLL (1 << 0) #define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_CAPS (1 << 2) -static const unsigned keyboard_map[128] = -{ - /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', - /* 0x08 */ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, - /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', - /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', - /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, - /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, - /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, - /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, - /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, - /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, - /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, - /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, - /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, - /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, - /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', - /* 0x60 */ '\0', '\0', '\0', '\0', - /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, - /* 0x68 */ GRUB_TERM_KEY_RIGHT -}; - -static unsigned keyboard_map_shift[128] = -{ - '\0', '\0', '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\0', '\0', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', - [0x56] = '|' -}; - static grub_uint8_t grub_keyboard_controller_orig; static void @@ -122,45 +76,41 @@ grub_keyboard_isr (grub_uint8_t key) switch (KEYBOARD_SCANCODE (key)) { case SHIFT_L: - at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L; + at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT; break; case SHIFT_R: - at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R; + at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT; break; case CTRL: - at_keyboard_status |= KEYBOARD_STATUS_CTRL_L; + at_keyboard_status |= GRUB_TERM_STATUS_LCTRL; break; case ALT: - if (at_keyboard_status & KEYBOARD_STATUS_EXTENDED) - at_keyboard_status |= KEYBOARD_STATUS_ALT_R; + if (extended_pending) + at_keyboard_status |= GRUB_TERM_STATUS_RALT; else - at_keyboard_status |= KEYBOARD_STATUS_ALT_L; + at_keyboard_status |= GRUB_TERM_STATUS_LALT; break; } else switch (KEYBOARD_SCANCODE (key)) { case SHIFT_L: - at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L; + at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; break; case SHIFT_R: - at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R; + at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT; break; case CTRL: - at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L; + at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL; break; case ALT: - if (at_keyboard_status & KEYBOARD_STATUS_EXTENDED) - at_keyboard_status &= ~KEYBOARD_STATUS_ALT_R; + if (extended_pending) + at_keyboard_status &= ~GRUB_TERM_STATUS_RALT; else - at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L; + at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; break; } - if (key == 0xe0) - at_keyboard_status |= KEYBOARD_STATUS_EXTENDED; - else - at_keyboard_status &= ~KEYBOARD_STATUS_EXTENDED; - + extended_pending = (key == 0xe0); } /* If there is a raw key pending, return it; otherwise return -1. */ @@ -177,11 +127,12 @@ grub_keyboard_getkey (void) return (KEYBOARD_SCANCODE (key)); } + /* If there is a character pending, return it; otherwise return -1. */ static int grub_at_keyboard_getkey_noblock (void) { - int code, key; + int code; code = grub_keyboard_getkey (); if (code == -1) return -1; @@ -194,66 +145,34 @@ grub_at_keyboard_getkey_noblock (void) /* Caps lock sends scan code twice. Get the second one and discard it. */ while (grub_keyboard_getkey () == -1); - at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK; + at_keyboard_status ^= GRUB_TERM_STATUS_CAPS; led_status ^= KEYBOARD_LED_CAPS; keyboard_controller_led (led_status); #ifdef DEBUG_AT_KEYBOARD grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)); #endif - key = -1; - break; + return -1; case NUM_LOCK: /* Num lock sends scan code twice. Get the second one and discard it. */ while (grub_keyboard_getkey () == -1); - at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK; + at_keyboard_status ^= GRUB_TERM_STATUS_NUM; led_status ^= KEYBOARD_LED_NUM; keyboard_controller_led (led_status); #ifdef DEBUG_AT_KEYBOARD grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK)); #endif - key = -1; - break; + return -1; case SCROLL_LOCK: - /* For scroll lock we don't keep track of status. Only update its led. */ + at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL; led_status ^= KEYBOARD_LED_SCROLL; keyboard_controller_led (led_status); - key = -1; - break; + return -1; default: - if (at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L - | KEYBOARD_STATUS_SHIFT_R)) - { - if (keyboard_map_shift[code]) - key = keyboard_map_shift[code]; - else - key = keyboard_map[code] | GRUB_TERM_SHIFT; - } - else - key = keyboard_map[code]; - - if (key == 0) - grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); - - if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK) - { - if ((key >= 'a') && (key <= 'z')) - key += 'A' - 'a'; - else if ((key >= 'A') && (key <= 'Z')) - key += 'a' - 'A'; - } - - if (at_keyboard_status & KEYBOARD_STATUS_ALT_L) - key |= GRUB_TERM_ALT; - if (at_keyboard_status & KEYBOARD_STATUS_ALT_R) - key |= GRUB_TERM_ALT; - if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L - | KEYBOARD_STATUS_CTRL_R)) - key |= GRUB_TERM_CTRL; + return grub_term_map_key (code, at_keyboard_status); } - return key; } static int diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 74df4c27f..009647c4c 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -24,25 +24,11 @@ static const struct grub_machine_bios_data_area *bios_data_area = (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; -#define KEYBOARD_LEFT_SHIFT (1 << 0) -#define KEYBOARD_RIGHT_SHIFT (1 << 1) -#define KEYBOARD_CTRL (1 << 2) -#define KEYBOARD_ALT (1 << 3) - static int grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused))) { - grub_uint8_t status = bios_data_area->keyboard_flag_lower; - int mods = 0; - - if (status & (KEYBOARD_LEFT_SHIFT | KEYBOARD_RIGHT_SHIFT)) - mods |= GRUB_TERM_STATUS_SHIFT; - if (status & KEYBOARD_CTRL) - mods |= GRUB_TERM_STATUS_CTRL; - if (status & KEYBOARD_ALT) - mods |= GRUB_TERM_STATUS_ALT; - - return mods; + /* conveniently GRUB keystatus is modelled after BIOS one. */ + return bios_data_area->keyboard_flag_lower & ~0x80; } static struct grub_term_input grub_console_term_input = diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 3432f700c..f35cc4b65 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -163,7 +163,7 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) /* Check if the Shift key was pressed. */ if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT - || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) + || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) { if (keyboard_map_shift[data[2]]) key = keyboard_map_shift[data[2]]; @@ -323,12 +323,18 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unu data[4], data[5], data[6], data[7]); /* Check Shift, Control, and Alt status. */ - if (data[0] & 0x02 || data[0] & 0x20) - mods |= GRUB_TERM_STATUS_SHIFT; - if (data[0] & 0x01 || data[0] & 0x10) - mods |= GRUB_TERM_STATUS_CTRL; - if (data[0] & 0x04 || data[0] & 0x40) - mods |= GRUB_TERM_STATUS_ALT; + if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT) + mods |= GRUB_TERM_STATUS_LSHIFT; + if (data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) + mods |= GRUB_TERM_STATUS_RSHIFT; + if (data[0] & GRUB_USB_KEYBOARD_LEFT_CTRL) + mods |= GRUB_TERM_STATUS_LCTRL; + if (data[0] & GRUB_USB_KEYBOARD_RIGHT_CTRL) + mods |= GRUB_TERM_STATUS_RCTRL; + if (data[0] & GRUB_USB_KEYBOARD_LEFT_ALT) + mods |= GRUB_TERM_STATUS_LALT; + if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT) + mods |= GRUB_TERM_STATUS_RALT; grub_errno = GRUB_ERR_NONE; diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 9aca88cb1..43aa745a5 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -46,6 +46,26 @@ struct console_grub_equivalence grub_uint32_t grub; }; +static int at_to_usb_map[128] = +{ + 0, 41, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 45, 46, 42, 43, + 20, 26, 8, 21, 23, 28, 24, 12, + 18, 19, 47, 48, 40, 0, 4, 22, + 7, 9, 10, 11, 13, 14, 15, 51, + 52, 53, 0, 49, 29, 27, 6, 25, + 5, 17, 16, 54, 55, 56, 0, 0, + 0, 44, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 74, + 82, 78, 45, 80, 0, 79, 0, 77, + 81, 75, 0, 76, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + static struct console_grub_equivalence console_grub_equivalences[] = { {"KP_1", '1'}, {"KP_2", '2'}, @@ -85,7 +105,26 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); exit (status); } -char +void +add_special_keys (struct grub_keyboard_layout *layout) +{ + layout->at.keyboard_map[71] = GRUB_TERM_KEY_HOME; + layout->at.keyboard_map[72] = GRUB_TERM_KEY_UP; + layout->at.keyboard_map[73] = GRUB_TERM_KEY_NPAGE; + layout->at.keyboard_map[75] = GRUB_TERM_KEY_LEFT; + layout->at.keyboard_map[77] = GRUB_TERM_KEY_RIGHT; + layout->at.keyboard_map[79] = GRUB_TERM_KEY_END; + layout->at.keyboard_map[80] = GRUB_TERM_KEY_DOWN; + layout->at.keyboard_map[81] = GRUB_TERM_KEY_PPAGE; + layout->at.keyboard_map[83] = GRUB_TERM_KEY_DC; + + layout->at.keyboard_map[101] = GRUB_TERM_KEY_UP; + layout->at.keyboard_map[102] = GRUB_TERM_KEY_DOWN; + layout->at.keyboard_map[103] = GRUB_TERM_KEY_LEFT; + layout->at.keyboard_map[104] = GRUB_TERM_KEY_RIGHT; +} + +static char lookup (char *code) { int i; @@ -97,7 +136,7 @@ lookup (char *code) return '\0'; } -unsigned int +static unsigned int get_grub_code (char *layout_code) { unsigned int code; @@ -111,9 +150,8 @@ get_grub_code (char *layout_code) return code; } -void -write_file (char* filename, grub_uint32_t *keyboard_map, - grub_uint32_t *keyboard_map_alt) +static void +write_file (char* filename, struct grub_keyboard_layout *layout) { FILE *fp_output; grub_uint32_t version; @@ -121,11 +159,35 @@ write_file (char* filename, grub_uint32_t *keyboard_map, version = grub_cpu_to_le32 (GRUB_KEYBOARD_LAYOUTS_VERSION); - for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) - keyboard_map[i] = grub_cpu_to_le32 (keyboard_map[i]); + for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map); i++) + layout->at.keyboard_map[i] = grub_cpu_to_le32(layout->at.keyboard_map[i]); - for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) - keyboard_map_alt[i] = grub_cpu_to_le32 (keyboard_map_alt[i]); + for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_shift); i++) + layout->at.keyboard_map_shift[i] + = grub_cpu_to_le32(layout->at.keyboard_map_shift[i]); + + for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_l3); i++) + layout->at.keyboard_map_l3[i] + = grub_cpu_to_le32(layout->at.keyboard_map_l3[i]); + + for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_shift_l3); i++) + layout->at.keyboard_map_shift_l3[i] + = grub_cpu_to_le32(layout->at.keyboard_map_shift_l3[i]); + + for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map); i++) + layout->usb.keyboard_map[i] = grub_cpu_to_le32(layout->usb.keyboard_map[i]); + + for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_shift); i++) + layout->usb.keyboard_map_shift[i] + = grub_cpu_to_le32(layout->usb.keyboard_map_shift[i]); + + for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_l3); i++) + layout->usb.keyboard_map_l3[i] + = grub_cpu_to_le32(layout->usb.keyboard_map_l3[i]); + + for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_shift_l3); i++) + layout->usb.keyboard_map_shift_l3[i] + = grub_cpu_to_le32(layout->usb.keyboard_map_shift_l3[i]); fp_output = fopen (filename, "w"); @@ -138,23 +200,19 @@ write_file (char* filename, grub_uint32_t *keyboard_map, fwrite (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, 1, GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE, fp_output); fwrite (&version, sizeof (version), 1, fp_output); - fwrite (keyboard_map, sizeof (keyboard_map[0]), - GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output); - fwrite (keyboard_map_alt, sizeof (keyboard_map_alt[0]), - GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output); + fwrite (layout, 1, sizeof (*layout), fp_output); fclose (fp_output); } -void +static void write_keymaps (char *keymap, char *file_basename) { - grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - + struct grub_keyboard_layout layout; char line[2048]; pid_t pid; int pipe_communication[2]; int ok; + unsigned i; FILE *fp_pipe; @@ -182,7 +240,7 @@ write_keymaps (char *keymap, char *file_basename) close (pipe_communication[1]); fp_pipe = fdopen (pipe_communication[0], "r"); - memset (keyboard_map, 0, sizeof (keyboard_map)); + memset (&layout, 0, sizeof (layout)); /* Process the ckbcomp output and prepare the layouts. */ ok = 0; @@ -198,9 +256,30 @@ write_keymaps (char *keymap, char *file_basename) sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode, normal, shift, normalalt, shiftalt); + if (keycode < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) + { + layout.at.keyboard_map[keycode] = get_grub_code (normal); + layout.at.keyboard_map_shift[keycode] = get_grub_code (shift); + layout.at.keyboard_map_l3[keycode] = get_grub_code (normalalt); + layout.at.keyboard_map_shift_l3[keycode] + = get_grub_code (shiftalt); + ok = 1; + } } } + for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) + { + layout.usb.keyboard_map[at_to_usb_map[i]] = layout.at.keyboard_map[i]; + layout.usb.keyboard_map_shift[at_to_usb_map[i]] + = layout.at.keyboard_map_shift[i]; + layout.usb.keyboard_map_l3[at_to_usb_map[i]] + = layout.at.keyboard_map_l3[i]; + layout.usb.keyboard_map_shift_l3[at_to_usb_map[i]] + = layout.at.keyboard_map_shift_l3[i]; + } + + if (ok == 0) { fprintf (stderr, "ERROR: no keycodes found. Check output of %s %s.\n", @@ -208,7 +287,9 @@ write_keymaps (char *keymap, char *file_basename) exit (1); } - write_file (file_basename, keyboard_map, keyboard_map_alt); + add_special_keys (&layout); + + write_file (file_basename, &layout); } int From 5ef4e08416445b1b4245b09bc80725d4aca45f82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 15:32:43 +0200 Subject: [PATCH 0051/1414] add usb keymap support --- commands/keylayouts.c | 128 ++++++++++++--------------- include/grub/keyboard_layouts.h | 10 +-- term/usb_keyboard.c | 151 +++++++++++++++----------------- util/grub-mklayouts.c | 103 ++++++---------------- 4 files changed, 157 insertions(+), 235 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index b7aee7fab..df8b95e02 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -29,43 +29,40 @@ #include static struct grub_keyboard_layout layout_us = { - .at = { - .keyboard_map = { - /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', - /* 0x08 */ '7', '8', '9', '0', - /* 0x0c */ '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, - /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', - /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', - /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, - /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, - /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, - /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, - /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, - /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, - /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, - /* 0x4e */ '+', GRUB_TERM_KEY_END, - /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, - /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, - /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, - /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', - /* 0x60 */ '\0', '\0', '\0', '\0', - /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, - /* 0x68 */ GRUB_TERM_KEY_RIGHT - }, - .keyboard_map_shift = { - '\0', '\0', '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\0', '\0', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', - [0x56] = '|' - } + .keyboard_map = { + /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', + /* 0x08 */ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, + /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', + /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', + /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', + /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, + /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, + /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, + /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, + /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, + /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, + /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, + /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, + /* 0x4e */ '+', GRUB_TERM_KEY_END, + /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, + /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, + /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, + /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', + /* 0x60 */ '\0', '\0', '\0', '\0', + /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, + /* 0x68 */ GRUB_TERM_KEY_RIGHT + }, + .keyboard_map_shift = { + '\0', '\0', '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '\0', '\0', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', + [0x56] = '|' } }; @@ -80,33 +77,33 @@ map_key_core (int code, int status, int *alt_gr_consumed) { if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) { - if (grub_current_layout->at.keyboard_map_shift_l3[code]) + if (grub_current_layout->keyboard_map_shift_l3[code]) { *alt_gr_consumed = 1; - return grub_current_layout->at.keyboard_map_shift_l3[code]; + return grub_current_layout->keyboard_map_shift_l3[code]; } - else if (grub_current_layout->at.keyboard_map_shift[code]) + else if (grub_current_layout->keyboard_map_shift[code]) { *alt_gr_consumed = 1; - return grub_current_layout->at.keyboard_map_l3[code] + return grub_current_layout->keyboard_map_l3[code] | GRUB_TERM_SHIFT; } } - else if (grub_current_layout->at.keyboard_map_shift[code]) + else if (grub_current_layout->keyboard_map_shift[code]) { *alt_gr_consumed = 1; - return grub_current_layout->at.keyboard_map_l3[code]; + return grub_current_layout->keyboard_map_l3[code]; } } if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) { - if (grub_current_layout->at.keyboard_map_shift[code]) - return grub_current_layout->at.keyboard_map_shift[code]; + if (grub_current_layout->keyboard_map_shift[code]) + return grub_current_layout->keyboard_map_shift[code]; else - return grub_current_layout->at.keyboard_map[code] | GRUB_TERM_SHIFT; + return grub_current_layout->keyboard_map[code] | GRUB_TERM_SHIFT; } else - return grub_current_layout->at.keyboard_map[code]; + return grub_current_layout->keyboard_map[code]; } unsigned @@ -204,35 +201,20 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), goto fail; } - for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map); i++) - newmap->at.keyboard_map[i] = grub_le_to_cpu32(newmap->at.keyboard_map[i]); + for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map); i++) + newmap->keyboard_map[i] = grub_le_to_cpu32(newmap->keyboard_map[i]); - for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_shift); i++) - newmap->at.keyboard_map_shift[i] - = grub_le_to_cpu32(newmap->at.keyboard_map_shift[i]); + for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_shift); i++) + newmap->keyboard_map_shift[i] + = grub_le_to_cpu32(newmap->keyboard_map_shift[i]); - for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_l3); i++) - newmap->at.keyboard_map_l3[i] - = grub_le_to_cpu32(newmap->at.keyboard_map_l3[i]); + for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_l3); i++) + newmap->keyboard_map_l3[i] + = grub_le_to_cpu32(newmap->keyboard_map_l3[i]); - for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_shift_l3); i++) - newmap->at.keyboard_map_shift_l3[i] - = grub_le_to_cpu32(newmap->at.keyboard_map_shift_l3[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map); i++) - newmap->usb.keyboard_map[i] = grub_le_to_cpu32(newmap->usb.keyboard_map[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_shift); i++) - newmap->usb.keyboard_map_shift[i] - = grub_le_to_cpu32(newmap->usb.keyboard_map_shift[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_l3); i++) - newmap->usb.keyboard_map_l3[i] - = grub_le_to_cpu32(newmap->usb.keyboard_map_l3[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_shift_l3); i++) - newmap->usb.keyboard_map_shift_l3[i] - = grub_le_to_cpu32(newmap->usb.keyboard_map_shift_l3[i]); + for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_shift_l3); i++) + newmap->keyboard_map_shift_l3[i] + = grub_le_to_cpu32(newmap->keyboard_map_shift_l3[i]); grub_current_layout = newmap; diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index 6d4b620c2..1920b8887 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,11 +21,11 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 5 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 6 #define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 -struct grub_keyboard_layout_kbd +struct grub_keyboard_layout { grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; @@ -33,12 +33,6 @@ struct grub_keyboard_layout_kbd grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; }; -struct grub_keyboard_layout -{ - struct grub_keyboard_layout_kbd at; - struct grub_keyboard_layout_kbd usb; -}; - unsigned grub_term_map_key (int code, int status); #endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index f35cc4b65..6f1e1a9e8 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -25,39 +25,45 @@ #include #include #include +#include -static unsigned keyboard_map[128] = - { - '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', - '3', '4', '5', '6', '7', '8', '9', '0', - '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[', - ']', '\\', '#', ';', '\'', '`', ',', '.', - '/', '\0', 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, '\0', '\0', - '\0', GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, - GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, - GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP, - [0x64] = '\\' - }; -static unsigned keyboard_map_shift[128] = - { - '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D', - 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', - '#', '$', '%', '^', '&', '*', '(', ')', - '\n', '\0', '\0', '\0', ' ', '_', '+', '{', - '}', '|', '#', ':', '"', '`', '<', '>', - '?', - [0x64] = '|' - }; +static grub_uint8_t usb_to_at_map[128] = +{ + /* 0x00 */ 0x00, 0x00, 0x00, 0x00, + /* 0x04 */ 0x1e /* a */, 0x30 /* b */, 0x2e /* c */, 0x20 /* d */, + /* 0x08 */ 0x12 /* e */, 0x21 /* f */, 0x22 /* g */, 0x23 /* h */, + /* 0x0c */ 0x17 /* i */, 0x24 /* j */, 0x25 /* k */, 0x26 /* l */, + /* 0x10 */ 0x32 /* m */, 0x31 /* n */, 0x18 /* o */, 0x19 /* p */, + /* 0x14 */ 0x10 /* q */, 0x13 /* r */, 0x1f /* s */, 0x14 /* t */, + /* 0x18 */ 0x16 /* u */, 0x2f /* v */, 0x11 /* w */, 0x2d /* x */, + /* 0x1c */ 0x15 /* y */, 0x2c /* z */, 0x02 /* 1 */, 0x03 /* 2 */, + /* 0x20 */ 0x04 /* 3 */, 0x05 /* 4 */, 0x06 /* 5 */, 0x07 /* 6 */, + /* 0x24 */ 0x08 /* 7 */, 0x09 /* 8 */, 0x0a /* 9 */, 0x0b /* 0 */, + /* 0x28 */ 0x1c /* Enter */, 0x01 /* Escape */, 0x0e /* \b */, 0x0f /* \t */, + /* 0x2c */ 0x39 /* Space */, 0x4a /* - */, 0x0d /* = */, 0x1a /* [ */, + /* 0x30 */ 0x1b /* ] */, 0x2b /* \ */, 0x00, 0x27 /* ; */, + /* 0x34 */ 0x28 /* " */, 0x29 /* ` */, 0x33 /* , */, 0x34 /* . */, + /* 0x38 */ 0x35 /* / */, 0x00, 0x00, 0x00, + /* 0x3c */ 0x00, 0x00, 0x00, 0x00, + /* 0x40 */ 0x00, 0x00, 0x00, 0x00, + /* 0x44 */ 0x00, 0x00, 0x00, 0x00, + /* 0x48 */ 0x00, 0x00, 0x47 /* HOME */, 0x51 /* PPAGE */, + /* 0x4c */ 0x53 /* DC */, 0x4f /* END */, 0x49 /* NPAGE */, 0x4d /* RIGHT */, + /* 0x50 */ 0x4b /* LEFT */, 0x50 /* DOWN */, 0x48 /* UP */, 0x00, + /* 0x54 */ 0x00, 0x00, 0x00, 0x00, + /* 0x58 */ 0x00, 0x00, 0x00, 0x00, + /* 0x5c */ 0x00, 0x00, 0x00, 0x00, + /* 0x60 */ 0x00, 0x00, 0x00, 0x00, + /* 0x64 */ 0x56 /* 102nd key. */, 0x00, 0x00, 0x00, + /* 0x68 */ 0x00, 0x00, 0x00, 0x00, + /* 0x6c */ 0x00, 0x00, 0x00, 0x00, + /* 0x70 */ 0x00, 0x00, 0x00, 0x00, + /* 0x74 */ 0x00, 0x00, 0x00, 0x00, + /* 0x78 */ 0x00, 0x00, 0x00, 0x00, + /* 0x7c */ 0x00, 0x00, 0x00, 0x00, +}; static grub_usb_device_t usbdev; @@ -74,6 +80,35 @@ static grub_usb_device_t usbdev; #define USB_HID_SET_IDLE 0x0A #define USB_HID_SET_PROTOCOL 0x0B +#define GRUB_USB_KEYBOARD_LEFT_CTRL 0x01 +#define GRUB_USB_KEYBOARD_LEFT_SHIFT 0x02 +#define GRUB_USB_KEYBOARD_LEFT_ALT 0x04 +#define GRUB_USB_KEYBOARD_RIGHT_CTRL 0x10 +#define GRUB_USB_KEYBOARD_RIGHT_SHIFT 0x20 +#define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 + +static int +interpret_status (grub_uint8_t data0) +{ + int mods = 0; + + /* Check Shift, Control, and Alt status. */ + if (data0 & GRUB_USB_KEYBOARD_LEFT_SHIFT) + mods |= GRUB_TERM_STATUS_LSHIFT; + if (data0 & GRUB_USB_KEYBOARD_RIGHT_SHIFT) + mods |= GRUB_TERM_STATUS_RSHIFT; + if (data0 & GRUB_USB_KEYBOARD_LEFT_CTRL) + mods |= GRUB_TERM_STATUS_LCTRL; + if (data0 & GRUB_USB_KEYBOARD_RIGHT_CTRL) + mods |= GRUB_TERM_STATUS_RCTRL; + if (data0 & GRUB_USB_KEYBOARD_LEFT_ALT) + mods |= GRUB_TERM_STATUS_LALT; + if (data0 & GRUB_USB_KEYBOARD_RIGHT_ALT) + mods |= GRUB_TERM_STATUS_RALT; + + return mods; +} + static void grub_usb_hid (void) { @@ -127,7 +162,7 @@ static int grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused))) { grub_uint8_t data[8]; - int key; + int key = 0; grub_err_t err; grub_uint64_t currtime; int timeout = 50; @@ -154,39 +189,14 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); -#define GRUB_USB_KEYBOARD_LEFT_CTRL 0x01 -#define GRUB_USB_KEYBOARD_LEFT_SHIFT 0x02 -#define GRUB_USB_KEYBOARD_LEFT_ALT 0x04 -#define GRUB_USB_KEYBOARD_RIGHT_CTRL 0x10 -#define GRUB_USB_KEYBOARD_RIGHT_SHIFT 0x20 -#define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 - - /* Check if the Shift key was pressed. */ - if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT - || data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) - { - if (keyboard_map_shift[data[2]]) - key = keyboard_map_shift[data[2]]; - else - key = keyboard_map[data[2]] | GRUB_TERM_SHIFT; - } - else - key = keyboard_map[data[2]]; - - if (key == 0) + if (usb_to_at_map[data[2]] == 0) grub_printf ("Unknown key 0x%x detected\n", data[2]); + else + key = grub_term_map_key (usb_to_at_map[data[2]], interpret_status (data[0])); - /* Check if the Ctrl key was pressed. */ - if (data[0] & GRUB_USB_KEYBOARD_LEFT_CTRL - || data[0] & GRUB_USB_KEYBOARD_RIGHT_CTRL) - key |= GRUB_TERM_CTRL; + grub_errno = GRUB_ERR_NONE; - /* Check if the Alt key was pressed. */ - if (data[0] & GRUB_USB_KEYBOARD_LEFT_ALT) - key |= GRUB_TERM_ALT; - - if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT) - key |= GRUB_TERM_ALT; + return key; #if 0 /* Wait until the key is released. */ @@ -203,8 +213,6 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) } #endif - grub_errno = GRUB_ERR_NONE; - return key; } @@ -284,7 +292,6 @@ static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unused))) { grub_uint8_t data[8]; - int mods = 0; grub_err_t err; grub_uint64_t currtime; int timeout = 50; @@ -322,23 +329,9 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unu data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - /* Check Shift, Control, and Alt status. */ - if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT) - mods |= GRUB_TERM_STATUS_LSHIFT; - if (data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT) - mods |= GRUB_TERM_STATUS_RSHIFT; - if (data[0] & GRUB_USB_KEYBOARD_LEFT_CTRL) - mods |= GRUB_TERM_STATUS_LCTRL; - if (data[0] & GRUB_USB_KEYBOARD_RIGHT_CTRL) - mods |= GRUB_TERM_STATUS_RCTRL; - if (data[0] & GRUB_USB_KEYBOARD_LEFT_ALT) - mods |= GRUB_TERM_STATUS_LALT; - if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT) - mods |= GRUB_TERM_STATUS_RALT; - grub_errno = GRUB_ERR_NONE; - return mods; + return interpret_status (data[0]); } static struct grub_term_input grub_usb_keyboard_term = diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 43aa745a5..6a51a9a76 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -46,26 +46,6 @@ struct console_grub_equivalence grub_uint32_t grub; }; -static int at_to_usb_map[128] = -{ - 0, 41, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 45, 46, 42, 43, - 20, 26, 8, 21, 23, 28, 24, 12, - 18, 19, 47, 48, 40, 0, 4, 22, - 7, 9, 10, 11, 13, 14, 15, 51, - 52, 53, 0, 49, 29, 27, 6, 25, - 5, 17, 16, 54, 55, 56, 0, 0, - 0, 44, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 74, - 82, 78, 45, 80, 0, 79, 0, 77, - 81, 75, 0, 76, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - static struct console_grub_equivalence console_grub_equivalences[] = { {"KP_1", '1'}, {"KP_2", '2'}, @@ -108,20 +88,20 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); void add_special_keys (struct grub_keyboard_layout *layout) { - layout->at.keyboard_map[71] = GRUB_TERM_KEY_HOME; - layout->at.keyboard_map[72] = GRUB_TERM_KEY_UP; - layout->at.keyboard_map[73] = GRUB_TERM_KEY_NPAGE; - layout->at.keyboard_map[75] = GRUB_TERM_KEY_LEFT; - layout->at.keyboard_map[77] = GRUB_TERM_KEY_RIGHT; - layout->at.keyboard_map[79] = GRUB_TERM_KEY_END; - layout->at.keyboard_map[80] = GRUB_TERM_KEY_DOWN; - layout->at.keyboard_map[81] = GRUB_TERM_KEY_PPAGE; - layout->at.keyboard_map[83] = GRUB_TERM_KEY_DC; + layout->keyboard_map[71] = GRUB_TERM_KEY_HOME; + layout->keyboard_map[72] = GRUB_TERM_KEY_UP; + layout->keyboard_map[73] = GRUB_TERM_KEY_NPAGE; + layout->keyboard_map[75] = GRUB_TERM_KEY_LEFT; + layout->keyboard_map[77] = GRUB_TERM_KEY_RIGHT; + layout->keyboard_map[79] = GRUB_TERM_KEY_END; + layout->keyboard_map[80] = GRUB_TERM_KEY_DOWN; + layout->keyboard_map[81] = GRUB_TERM_KEY_PPAGE; + layout->keyboard_map[83] = GRUB_TERM_KEY_DC; - layout->at.keyboard_map[101] = GRUB_TERM_KEY_UP; - layout->at.keyboard_map[102] = GRUB_TERM_KEY_DOWN; - layout->at.keyboard_map[103] = GRUB_TERM_KEY_LEFT; - layout->at.keyboard_map[104] = GRUB_TERM_KEY_RIGHT; + layout->keyboard_map[101] = GRUB_TERM_KEY_UP; + layout->keyboard_map[102] = GRUB_TERM_KEY_DOWN; + layout->keyboard_map[103] = GRUB_TERM_KEY_LEFT; + layout->keyboard_map[104] = GRUB_TERM_KEY_RIGHT; } static char @@ -159,35 +139,20 @@ write_file (char* filename, struct grub_keyboard_layout *layout) version = grub_cpu_to_le32 (GRUB_KEYBOARD_LAYOUTS_VERSION); - for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map); i++) - layout->at.keyboard_map[i] = grub_cpu_to_le32(layout->at.keyboard_map[i]); + for (i = 0; i < ARRAY_SIZE (layout->keyboard_map); i++) + layout->keyboard_map[i] = grub_cpu_to_le32(layout->keyboard_map[i]); - for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_shift); i++) - layout->at.keyboard_map_shift[i] - = grub_cpu_to_le32(layout->at.keyboard_map_shift[i]); + for (i = 0; i < ARRAY_SIZE (layout->keyboard_map_shift); i++) + layout->keyboard_map_shift[i] + = grub_cpu_to_le32(layout->keyboard_map_shift[i]); - for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_l3); i++) - layout->at.keyboard_map_l3[i] - = grub_cpu_to_le32(layout->at.keyboard_map_l3[i]); + for (i = 0; i < ARRAY_SIZE (layout->keyboard_map_l3); i++) + layout->keyboard_map_l3[i] + = grub_cpu_to_le32(layout->keyboard_map_l3[i]); - for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_shift_l3); i++) - layout->at.keyboard_map_shift_l3[i] - = grub_cpu_to_le32(layout->at.keyboard_map_shift_l3[i]); - - for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map); i++) - layout->usb.keyboard_map[i] = grub_cpu_to_le32(layout->usb.keyboard_map[i]); - - for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_shift); i++) - layout->usb.keyboard_map_shift[i] - = grub_cpu_to_le32(layout->usb.keyboard_map_shift[i]); - - for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_l3); i++) - layout->usb.keyboard_map_l3[i] - = grub_cpu_to_le32(layout->usb.keyboard_map_l3[i]); - - for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_shift_l3); i++) - layout->usb.keyboard_map_shift_l3[i] - = grub_cpu_to_le32(layout->usb.keyboard_map_shift_l3[i]); + for (i = 0; i < ARRAY_SIZE (layout->keyboard_map_shift_l3); i++) + layout->keyboard_map_shift_l3[i] + = grub_cpu_to_le32(layout->keyboard_map_shift_l3[i]); fp_output = fopen (filename, "w"); @@ -258,28 +223,16 @@ write_keymaps (char *keymap, char *file_basename) normal, shift, normalalt, shiftalt); if (keycode < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) { - layout.at.keyboard_map[keycode] = get_grub_code (normal); - layout.at.keyboard_map_shift[keycode] = get_grub_code (shift); - layout.at.keyboard_map_l3[keycode] = get_grub_code (normalalt); - layout.at.keyboard_map_shift_l3[keycode] + layout.keyboard_map[keycode] = get_grub_code (normal); + layout.keyboard_map_shift[keycode] = get_grub_code (shift); + layout.keyboard_map_l3[keycode] = get_grub_code (normalalt); + layout.keyboard_map_shift_l3[keycode] = get_grub_code (shiftalt); ok = 1; } } } - for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++) - { - layout.usb.keyboard_map[at_to_usb_map[i]] = layout.at.keyboard_map[i]; - layout.usb.keyboard_map_shift[at_to_usb_map[i]] - = layout.at.keyboard_map_shift[i]; - layout.usb.keyboard_map_l3[at_to_usb_map[i]] - = layout.at.keyboard_map_l3[i]; - layout.usb.keyboard_map_shift_l3[at_to_usb_map[i]] - = layout.at.keyboard_map_shift_l3[i]; - } - - if (ok == 0) { fprintf (stderr, "ERROR: no keycodes found. Check output of %s %s.\n", From b09634f02706eb412f9becf9d1d4084bcad97112 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 16:12:18 +0200 Subject: [PATCH 0052/1414] Added missing values and indented USB table --- term/usb_keyboard.c | 96 ++++++++++++++++++++++++++++--------------- util/grub-mklayouts.c | 4 ++ 2 files changed, 68 insertions(+), 32 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 6f1e1a9e8..ede71bb5f 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -31,38 +31,70 @@ static grub_uint8_t usb_to_at_map[128] = { - /* 0x00 */ 0x00, 0x00, 0x00, 0x00, - /* 0x04 */ 0x1e /* a */, 0x30 /* b */, 0x2e /* c */, 0x20 /* d */, - /* 0x08 */ 0x12 /* e */, 0x21 /* f */, 0x22 /* g */, 0x23 /* h */, - /* 0x0c */ 0x17 /* i */, 0x24 /* j */, 0x25 /* k */, 0x26 /* l */, - /* 0x10 */ 0x32 /* m */, 0x31 /* n */, 0x18 /* o */, 0x19 /* p */, - /* 0x14 */ 0x10 /* q */, 0x13 /* r */, 0x1f /* s */, 0x14 /* t */, - /* 0x18 */ 0x16 /* u */, 0x2f /* v */, 0x11 /* w */, 0x2d /* x */, - /* 0x1c */ 0x15 /* y */, 0x2c /* z */, 0x02 /* 1 */, 0x03 /* 2 */, - /* 0x20 */ 0x04 /* 3 */, 0x05 /* 4 */, 0x06 /* 5 */, 0x07 /* 6 */, - /* 0x24 */ 0x08 /* 7 */, 0x09 /* 8 */, 0x0a /* 9 */, 0x0b /* 0 */, - /* 0x28 */ 0x1c /* Enter */, 0x01 /* Escape */, 0x0e /* \b */, 0x0f /* \t */, - /* 0x2c */ 0x39 /* Space */, 0x4a /* - */, 0x0d /* = */, 0x1a /* [ */, - /* 0x30 */ 0x1b /* ] */, 0x2b /* \ */, 0x00, 0x27 /* ; */, - /* 0x34 */ 0x28 /* " */, 0x29 /* ` */, 0x33 /* , */, 0x34 /* . */, - /* 0x38 */ 0x35 /* / */, 0x00, 0x00, 0x00, - /* 0x3c */ 0x00, 0x00, 0x00, 0x00, - /* 0x40 */ 0x00, 0x00, 0x00, 0x00, - /* 0x44 */ 0x00, 0x00, 0x00, 0x00, - /* 0x48 */ 0x00, 0x00, 0x47 /* HOME */, 0x51 /* PPAGE */, - /* 0x4c */ 0x53 /* DC */, 0x4f /* END */, 0x49 /* NPAGE */, 0x4d /* RIGHT */, - /* 0x50 */ 0x4b /* LEFT */, 0x50 /* DOWN */, 0x48 /* UP */, 0x00, - /* 0x54 */ 0x00, 0x00, 0x00, 0x00, - /* 0x58 */ 0x00, 0x00, 0x00, 0x00, - /* 0x5c */ 0x00, 0x00, 0x00, 0x00, - /* 0x60 */ 0x00, 0x00, 0x00, 0x00, - /* 0x64 */ 0x56 /* 102nd key. */, 0x00, 0x00, 0x00, - /* 0x68 */ 0x00, 0x00, 0x00, 0x00, - /* 0x6c */ 0x00, 0x00, 0x00, 0x00, - /* 0x70 */ 0x00, 0x00, 0x00, 0x00, - /* 0x74 */ 0x00, 0x00, 0x00, 0x00, - /* 0x78 */ 0x00, 0x00, 0x00, 0x00, - /* 0x7c */ 0x00, 0x00, 0x00, 0x00, + /* 0x00 */ 0x00, 0x00, + /* 0x02 */ 0x00, 0x00, + /* 0x04 */ 0x1e /* a */, 0x30 /* b */, + /* 0x06 */ 0x2e /* c */, 0x20 /* d */, + /* 0x08 */ 0x12 /* e */, 0x21 /* f */, + /* 0x0a */ 0x22 /* g */, 0x23 /* h */, + /* 0x0c */ 0x17 /* i */, 0x24 /* j */, + /* 0x0e */ 0x25 /* k */, 0x26 /* l */, + /* 0x10 */ 0x32 /* m */, 0x31 /* n */, + /* 0x12 */ 0x18 /* o */, 0x19 /* p */, + /* 0x14 */ 0x10 /* q */, 0x13 /* r */, + /* 0x16 */ 0x1f /* s */, 0x14 /* t */, + /* 0x18 */ 0x16 /* u */, 0x2f /* v */, + /* 0x1a */ 0x11 /* w */, 0x2d /* x */, + /* 0x1c */ 0x15 /* y */, 0x2c /* z */, + /* 0x1e */ 0x02 /* 1 */, 0x03 /* 2 */, + /* 0x20 */ 0x04 /* 3 */, 0x05 /* 4 */, + /* 0x22 */ 0x06 /* 5 */, 0x07 /* 6 */, + /* 0x24 */ 0x08 /* 7 */, 0x09 /* 8 */, + /* 0x26 */ 0x0a /* 9 */, 0x0b /* 0 */, + /* 0x28 */ 0x1c /* Enter */, 0x01 /* Escape */, + /* 0x2a */ 0x0e /* \b */, 0x0f /* \t */, + /* 0x2c */ 0x39 /* Space */, 0x0c /* - */, + /* 0x2e */ 0x0d /* = */, 0x1a /* [ */, + /* 0x30 */ 0x1b /* ] */, 0x2b /* \ */, + /* 0x32 */ 0x00, 0x27 /* ; */, + /* 0x34 */ 0x28 /* " */, 0x29 /* ` */, + /* 0x36 */ 0x33 /* , */, 0x34 /* . */, + /* 0x38 */ 0x35 /* / */, 0x00, + /* 0x3a */ 0x3b /* F1 */, 0x3c /* F2 */, + /* 0x3c */ 0x3d /* F3 */, 0x3e /* F4 */, + /* 0x3e */ 0x3f /* F5 */, 0x40 /* F6 */, + /* 0x40 */ 0x41 /* F7 */, 0x42 /* F8 */, + /* 0x42 */ 0x43 /* F9 */, 0x44 /* F10 */, + /* 0x44 */ 0x57 /* F11 */, 0x58 /* F12 */, + /* 0x46 */ 0x00, 0x00, + /* 0x48 */ 0x00, 0x00, + /* 0x4a */ 0x47 /* HOME */, 0x51 /* PPAGE */, + /* 0x4c */ 0x53 /* DC */, 0x4f /* END */, + /* 0x4e */ 0x49 /* NPAGE */, 0x4d /* RIGHT */, + /* 0x50 */ 0x4b /* LEFT */, 0x50 /* DOWN */, + /* 0x52 */ 0x48 /* UP */, 0x00, + /* 0x54 */ 0x00, 0x00, + /* 0x56 */ 0x00, 0x00, + /* 0x58 */ 0x00, 0x00, + /* 0x5a */ 0x00, 0x00, + /* 0x5c */ 0x00, 0x00, + /* 0x5e */ 0x00, 0x00, + /* 0x60 */ 0x00, 0x00, + /* 0x62 */ 0x00, 0x00, + /* 0x64 */ 0x56 /* 102nd key. */, 0x00, + /* 0x66 */ 0x00, 0x00, + /* 0x68 */ 0x00, 0x00, + /* 0x6a */ 0x00, 0x00, + /* 0x6c */ 0x00, 0x00, + /* 0x6e */ 0x00, 0x00, + /* 0x70 */ 0x00, 0x00, + /* 0x72 */ 0x00, 0x00, + /* 0x74 */ 0x00, 0x00, + /* 0x76 */ 0x00, 0x00, + /* 0x78 */ 0x00, 0x00, + /* 0x7a */ 0x00, 0x00, + /* 0x7c */ 0x00, 0x00, + /* 0x7e */ 0x00, 0x00, }; static grub_usb_device_t usbdev; diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 6a51a9a76..dde2383e2 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -47,6 +47,10 @@ struct console_grub_equivalence }; static struct console_grub_equivalence console_grub_equivalences[] = { + {"Escape", GRUB_TERM_ESC}, + {"Tab", GRUB_TERM_TAB}, + {"Delete", GRUB_TERM_BACKSPACE}, + {"KP_1", '1'}, {"KP_2", '2'}, {"KP_3", '3'}, From b17520411991170f09751a50093760dc8dbf4d31 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 19:17:36 +0200 Subject: [PATCH 0053/1414] Add missing keys to grub-mklayouts --- util/grub-mklayouts.c | 174 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 143 insertions(+), 31 deletions(-) diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index dde2383e2..49ad6be97 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -51,24 +51,136 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"Tab", GRUB_TERM_TAB}, {"Delete", GRUB_TERM_BACKSPACE}, - {"KP_1", '1'}, - {"KP_2", '2'}, - {"KP_3", '3'}, - {"KP_4", '4'}, - {"KP_5", '5'}, - {"KP_6", '6'}, - {"KP_7", '7'}, - {"KP_8", '8'}, - {"KP_9", '9'}, - {"KP_Multiply", '*'}, - {"KP_Substract", '-'}, + {"KP_Subtract", '-'}, {"KP_Add", '+'}, {"KP_Divide", '/'}, {"KP_Enter", '\n'}, {"Return", '\n'}, - {"", '\0'} + + {"F1", GRUB_TERM_KEY_F1}, + {"F2", GRUB_TERM_KEY_F2}, + {"F3", GRUB_TERM_KEY_F3}, + {"F4", GRUB_TERM_KEY_F4}, + {"F5", GRUB_TERM_KEY_F5}, + {"F6", GRUB_TERM_KEY_F6}, + {"F7", GRUB_TERM_KEY_F7}, + {"F8", GRUB_TERM_KEY_F8}, + {"F9", GRUB_TERM_KEY_F9}, + {"F10", GRUB_TERM_KEY_F10}, + {"F11", GRUB_TERM_KEY_F11}, + {"F12", GRUB_TERM_KEY_F12}, + {"F13", GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT}, + {"F14", GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT}, + {"F15", GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT}, + {"F16", GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT}, + {"F17", GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT}, + {"F18", GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT}, + {"F19", GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT}, + {"F20", GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT}, + {"F21", GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT}, + {"F22", GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT}, + {"F23", GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT}, + {"F24", GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT}, + {"Console_13", GRUB_TERM_KEY_F1 | GRUB_TERM_ALT}, + {"Console_14", GRUB_TERM_KEY_F2 | GRUB_TERM_ALT}, + {"Console_15", GRUB_TERM_KEY_F3 | GRUB_TERM_ALT}, + {"Console_16", GRUB_TERM_KEY_F4 | GRUB_TERM_ALT}, + {"Console_17", GRUB_TERM_KEY_F5 | GRUB_TERM_ALT}, + {"Console_18", GRUB_TERM_KEY_F6 | GRUB_TERM_ALT}, + {"Console_19", GRUB_TERM_KEY_F7 | GRUB_TERM_ALT}, + {"Console_20", GRUB_TERM_KEY_F8 | GRUB_TERM_ALT}, + {"Console_21", GRUB_TERM_KEY_F9 | GRUB_TERM_ALT}, + {"Console_22", GRUB_TERM_KEY_F10 | GRUB_TERM_ALT}, + {"Console_23", GRUB_TERM_KEY_F11 | GRUB_TERM_ALT}, + {"Console_24", GRUB_TERM_KEY_F12 | GRUB_TERM_ALT}, + {"Console_25", GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_26", GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_27", GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_28", GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_29", GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_30", GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_31", GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_32", GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_33", GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_34", GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_35", GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + {"Console_36", GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT | GRUB_TERM_ALT}, + + {"Insert", GRUB_TERM_KEY_INSERT}, + {"Down", GRUB_TERM_KEY_DOWN}, + {"Up", GRUB_TERM_KEY_UP}, + {"Home", GRUB_TERM_KEY_HOME}, + {"End", GRUB_TERM_KEY_END}, + {"Right", GRUB_TERM_KEY_RIGHT}, + {"Left", GRUB_TERM_KEY_LEFT}, + {"VoidSymbol", 0}, + + /* "Undead" keys since no dead key support in GRUB. */ + {"dead_acute", '\''}, + {"dead_circumflex", '^'}, + {"dead_grave", '`'}, + {"dead_tilde", '~'}, + {"dead_diaeresis", '"'}, + + /* Following ones don't provide any useful symbols for shell. */ + {"dead_cedilla", 0}, + {"dead_ogonek", 0}, + {"dead_caron", 0}, + {"dead_breve", 0}, + {"dead_doubleacute", 0}, + + /* NumLock not supported yet. */ + {"KP_0", GRUB_TERM_KEY_INSERT}, + {"KP_1", GRUB_TERM_KEY_END}, + {"KP_2", GRUB_TERM_KEY_DOWN}, + {"KP_3", GRUB_TERM_KEY_NPAGE}, + {"KP_4", GRUB_TERM_KEY_LEFT}, + {"KP_5", 0}, + {"KP_6", GRUB_TERM_KEY_RIGHT}, + {"KP_7", GRUB_TERM_KEY_HOME}, + {"KP_8", GRUB_TERM_KEY_UP}, + {"KP_9", GRUB_TERM_KEY_PPAGE}, + {"KP_Period", GRUB_TERM_KEY_DC}, + + /* Unused in GRUB. */ + {"Pause", 0}, + {"Remove", 0}, + {"Next", 0}, + {"Prior", 0}, + {"Scroll_Forward", 0}, + {"Scroll_Backward", 0}, + {"Hex_0", 0}, + {"Hex_1", 0}, + {"Hex_2", 0}, + {"Hex_3", 0}, + {"Hex_4", 0}, + {"Hex_5", 0}, + {"Hex_6", 0}, + {"Hex_7", 0}, + {"Hex_8", 0}, + {"Hex_9", 0}, + {"Hex_A", 0}, + {"Hex_B", 0}, + {"Hex_C", 0}, + {"Hex_D", 0}, + {"Hex_E", 0}, + {"Hex_F", 0}, + {"Scroll_Lock", 0}, + {"Show_Memory", 0}, + {"Show_Registers", 0}, + {"Control_backslash", 0}, + + /* Keys currently not remappable. */ + {"CtrlL_Lock", 0}, + {"Num_Lock", 0}, + {"Alt", 0}, + {"AltGr", 0}, + {"Control", 0}, + {"Shift", 0}, + + {NULL, '\0'} }; static void @@ -92,16 +204,7 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); void add_special_keys (struct grub_keyboard_layout *layout) { - layout->keyboard_map[71] = GRUB_TERM_KEY_HOME; - layout->keyboard_map[72] = GRUB_TERM_KEY_UP; - layout->keyboard_map[73] = GRUB_TERM_KEY_NPAGE; - layout->keyboard_map[75] = GRUB_TERM_KEY_LEFT; - layout->keyboard_map[77] = GRUB_TERM_KEY_RIGHT; - layout->keyboard_map[79] = GRUB_TERM_KEY_END; - layout->keyboard_map[80] = GRUB_TERM_KEY_DOWN; - layout->keyboard_map[81] = GRUB_TERM_KEY_PPAGE; - layout->keyboard_map[83] = GRUB_TERM_KEY_DC; - + /* OLPC keys. */ layout->keyboard_map[101] = GRUB_TERM_KEY_UP; layout->keyboard_map[102] = GRUB_TERM_KEY_DOWN; layout->keyboard_map[103] = GRUB_TERM_KEY_LEFT; @@ -113,10 +216,12 @@ lookup (char *code) { int i; - for (i = 0; console_grub_equivalences[i].grub != '\0'; i++) + for (i = 0; console_grub_equivalences[i].layout != NULL; i++) if (strcmp (code, console_grub_equivalences[i].layout) == 0) return console_grub_equivalences[i].grub; + printf ("Unknown key %s\n", code); + return '\0'; } @@ -174,14 +279,13 @@ write_file (char* filename, struct grub_keyboard_layout *layout) } static void -write_keymaps (char *keymap, char *file_basename) +write_keymaps (char *argv[], int argc, char *file_basename) { struct grub_keyboard_layout layout; char line[2048]; pid_t pid; int pipe_communication[2]; int ok; - unsigned i; FILE *fp_pipe; @@ -199,11 +303,19 @@ write_keymaps (char *keymap, char *file_basename) } else if (pid == 0) { + char **args; + int j; close (1); dup (pipe_communication[1]); close (pipe_communication[0]); - execlp (CKBCOMP, CKBCOMP, keymap, NULL); - grub_util_error ("%s %s cannot be executed", CKBCOMP, keymap); + args = xmalloc (sizeof (args[0]) * (argc + 2)); + args[0] = CKBCOMP; + for (j = 0; j < argc; j++) + args[j + 1] = argv[j]; + args[argc + 1] = NULL; + execvp (CKBCOMP, args); + grub_util_error ("%s cannot be executed", CKBCOMP); + free (args); exit (3); } close (pipe_communication[1]); @@ -239,8 +351,8 @@ write_keymaps (char *keymap, char *file_basename) if (ok == 0) { - fprintf (stderr, "ERROR: no keycodes found. Check output of %s %s.\n", - CKBCOMP, keymap); + fprintf (stderr, "ERROR: no keycodes found. Check output of %s.\n", + CKBCOMP); exit (1); } @@ -302,11 +414,11 @@ main (int argc, char *argv[]) if (file_basename == NULL) { file_basename = xasprintf ("%s.gkb", argv[optind]); - write_keymaps (argv[optind], file_basename); + write_keymaps (argv + optind, argc - optind, file_basename); free (file_basename); } else - write_keymaps (argv[optind], file_basename); + write_keymaps (argv + optind, argc - optind, file_basename); return 0; } From 5a3e99b388eaecaaa615300b5eb738fcdd780f7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 20:43:40 +0200 Subject: [PATCH 0054/1414] MAke grub-mklayouts do only one thing rather than doing all the piping --- util/grub-mklayouts.c | 109 ++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 68 deletions(-) diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 49ad6be97..8fdee8590 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "progname.h" @@ -240,9 +241,8 @@ get_grub_code (char *layout_code) } static void -write_file (char* filename, struct grub_keyboard_layout *layout) +write_file (FILE *out, struct grub_keyboard_layout *layout) { - FILE *fp_output; grub_uint32_t version; unsigned i; @@ -263,69 +263,24 @@ write_file (char* filename, struct grub_keyboard_layout *layout) layout->keyboard_map_shift_l3[i] = grub_cpu_to_le32(layout->keyboard_map_shift_l3[i]); - fp_output = fopen (filename, "w"); - - if (!fp_output) - { - grub_util_error ("cannot open `%s'", filename); - exit (1); - } - fwrite (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, 1, - GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE, fp_output); - fwrite (&version, sizeof (version), 1, fp_output); - fwrite (layout, 1, sizeof (*layout), fp_output); - fclose (fp_output); + GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE, out); + fwrite (&version, sizeof (version), 1, out); + fwrite (layout, 1, sizeof (*layout), out); } static void -write_keymaps (char *argv[], int argc, char *file_basename) +write_keymaps (FILE *in, FILE *out) { struct grub_keyboard_layout layout; char line[2048]; - pid_t pid; - int pipe_communication[2]; int ok; - FILE *fp_pipe; - - if (pipe (pipe_communication) == -1) - { - grub_util_error ("cannot prepare the pipe"); - exit (2); - } - - pid = fork (); - if (pid < 0) - { - grub_util_error ("cannot fork"); - exit (2); - } - else if (pid == 0) - { - char **args; - int j; - close (1); - dup (pipe_communication[1]); - close (pipe_communication[0]); - args = xmalloc (sizeof (args[0]) * (argc + 2)); - args[0] = CKBCOMP; - for (j = 0; j < argc; j++) - args[j + 1] = argv[j]; - args[argc + 1] = NULL; - execvp (CKBCOMP, args); - grub_util_error ("%s cannot be executed", CKBCOMP); - free (args); - exit (3); - } - close (pipe_communication[1]); - fp_pipe = fdopen (pipe_communication[0], "r"); - memset (&layout, 0, sizeof (layout)); /* Process the ckbcomp output and prepare the layouts. */ ok = 0; - while (fgets (line, sizeof (line), fp_pipe)) + while (fgets (line, sizeof (line), in)) { if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0) { @@ -358,14 +313,16 @@ write_keymaps (char *argv[], int argc, char *file_basename) add_special_keys (&layout); - write_file (file_basename, &layout); + write_file (out, &layout); } int main (int argc, char *argv[]) { int verbosity; - char *file_basename = NULL; + char *infile_name = NULL; + char *outfile_name = NULL; + FILE *in, *out; set_program_name (argv[0]); @@ -374,7 +331,7 @@ main (int argc, char *argv[]) /* Check for options. */ while (1) { - int c = getopt_long (argc, argv, "o:hVv", options, 0); + int c = getopt_long (argc, argv, "o:i:hVv", options, 0); if (c == -1) break; @@ -385,8 +342,12 @@ main (int argc, char *argv[]) usage (0); break; + case 'i': + infile_name = optarg; + break; + case 'o': - file_basename = optarg; + outfile_name = optarg; break; case 'V': @@ -404,21 +365,33 @@ main (int argc, char *argv[]) } } - /* Obtain LAYOUT. */ - if (optind >= argc) + if (infile_name) + in = fopen (infile_name, "r"); + else + in = stdin; + + if (!in) + grub_util_error ("Couldn't open input file: %s\n", strerror (errno)); + + if (outfile_name) + out = fopen (outfile_name, "r"); + else + out = stdout; + + if (!out) { - fprintf (stderr, "No layout is specified.\n"); - usage (1); + if (in != stdin) + fclose (in); + grub_util_error ("Couldn't open input file: %s\n", strerror (errno)); } - if (file_basename == NULL) - { - file_basename = xasprintf ("%s.gkb", argv[optind]); - write_keymaps (argv + optind, argc - optind, file_basename); - free (file_basename); - } - else - write_keymaps (argv + optind, argc - optind, file_basename); + write_keymaps (in, out); + + if (in != stdin) + fclose (in); + + if (out != stdout) + fclose (out); return 0; } From 9c9ec877cb6ab2d39b7f57525cb31b4acb47e5cb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 20:47:08 +0200 Subject: [PATCH 0055/1414] Rename grub-mklayouts to grub-mklayout --- conf/common.rmk | 6 +++--- util/{grub-mklayouts.c => grub-mklayout.c} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename util/{grub-mklayouts.c => grub-mklayout.c} (100%) diff --git a/conf/common.rmk b/conf/common.rmk index 745b1837e..82edc0aa0 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -80,9 +80,9 @@ endif bin_UTILITIES += grub-mkrelpath grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c -# For grub-mklayouts. -bin_UTILITIES += grub-mklayouts -grub_mklayouts_SOURCES = gnulib/progname.c util/grub-mklayouts.c util/misc.c kern/emu/misc.c +# For grub-mklayout. +bin_UTILITIES += grub-mklayout +grub_mklayout_SOURCES = gnulib/progname.c util/grub-mklayout.c util/misc.c kern/emu/misc.c bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c diff --git a/util/grub-mklayouts.c b/util/grub-mklayout.c similarity index 100% rename from util/grub-mklayouts.c rename to util/grub-mklayout.c From 88e543b519d930457462d6931d2c9cb55ea94ba5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 Aug 2010 20:48:31 +0200 Subject: [PATCH 0056/1414] Add grub-kbdcomp --- conf/common.rmk | 7 +++++++ util/grub-kbdcomp.in | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 util/grub-kbdcomp.in diff --git a/conf/common.rmk b/conf/common.rmk index 82edc0aa0..e21c693b0 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -180,6 +180,13 @@ CLEANFILES += grub-pe2elf grub_macho2img_SOURCES = util/grub-macho2img.c CLEANFILES += grub-macho2img +# For grub-kbdcomp +grub-kbdcomp: util/grub-kbdcomp.in config.status + ./config.status --file=$@:$< + chmod +x $@ +sbin_SCRIPTS += grub-kbdcomp +CLEANFILES += grub-kbdcomp + # For grub-mkconfig grub-mkconfig: util/grub-mkconfig.in config.status ./config.status --file=$@:$< diff --git a/util/grub-kbdcomp.in b/util/grub-kbdcomp.in new file mode 100644 index 000000000..87b24bcdf --- /dev/null +++ b/util/grub-kbdcomp.in @@ -0,0 +1,6 @@ +#!/bin/sh + +grub_mklayout=${bindir}/`echo grub-mklayout | sed ${transform}` + +ckbcomp "$@" | $grub_mklayout -o "$1".gkb + From 8bb7e81637ba2f457daf8ce4c137e9851ab10960 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Aug 2010 01:23:33 +0200 Subject: [PATCH 0057/1414] Fix printf bug --- util/grub-mklayout.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 8fdee8590..210ad646a 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -172,9 +172,12 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"Show_Memory", 0}, {"Show_Registers", 0}, {"Control_backslash", 0}, + {"Compose", 0}, /* Keys currently not remappable. */ {"CtrlL_Lock", 0}, + {"Caps_Lock", 0}, + {"ShiftL", 0}, {"Num_Lock", 0}, {"Alt", 0}, {"AltGr", 0}, @@ -221,7 +224,7 @@ lookup (char *code) if (strcmp (code, console_grub_equivalences[i].layout) == 0) return console_grub_equivalences[i].grub; - printf ("Unknown key %s\n", code); + fprintf (stderr, "Unknown key %s\n", code); return '\0'; } @@ -374,7 +377,7 @@ main (int argc, char *argv[]) grub_util_error ("Couldn't open input file: %s\n", strerror (errno)); if (outfile_name) - out = fopen (outfile_name, "r"); + out = fopen (outfile_name, "wb"); else out = stdout; @@ -382,7 +385,7 @@ main (int argc, char *argv[]) { if (in != stdin) fclose (in); - grub_util_error ("Couldn't open input file: %s\n", strerror (errno)); + grub_util_error ("Couldn't open output file: %s\n", strerror (errno)); } write_keymaps (in, out); From 0b335a9797e188032ccca7fba48ed80fa10cc738 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Aug 2010 23:33:41 +0200 Subject: [PATCH 0058/1414] Fix cutting bits by implicit conversion to char --- util/grub-mklayout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 210ad646a..91dea87a6 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -215,7 +215,7 @@ add_special_keys (struct grub_keyboard_layout *layout) layout->keyboard_map[104] = GRUB_TERM_KEY_RIGHT; } -static char +static unsigned lookup (char *code) { int i; From d9a8a9736e2c9e66a6f989c2acb8071c257aa4e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 00:05:39 +0200 Subject: [PATCH 0059/1414] Add missing insert and \ codes --- term/usb_keyboard.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index f5bd1d601..6b8891716 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -55,8 +55,10 @@ static grub_uint8_t usb_to_at_map[128] = /* 0x2a */ 0x0e /* \b */, 0x0f /* \t */, /* 0x2c */ 0x39 /* Space */, 0x0c /* - */, /* 0x2e */ 0x0d /* = */, 0x1a /* [ */, - /* 0x30 */ 0x1b /* ] */, 0x2b /* \ */, - /* 0x32 */ 0x00, 0x27 /* ; */, + /* According to usage table 0x31 should be remapped to 0x2b + but testing with real keyboard shows that 0x32 is remapped to 0x2b. */ + /* 0x30 */ 0x1b /* ] */, 0x00, + /* 0x32 */ 0x2b /* \ */, 0x27 /* ; */, /* 0x34 */ 0x28 /* " */, 0x29 /* ` */, /* 0x36 */ 0x33 /* , */, 0x34 /* . */, /* 0x38 */ 0x35 /* / */, 0x00, @@ -67,7 +69,7 @@ static grub_uint8_t usb_to_at_map[128] = /* 0x42 */ 0x43 /* F9 */, 0x44 /* F10 */, /* 0x44 */ 0x57 /* F11 */, 0x58 /* F12 */, /* 0x46 */ 0x00, 0x00, - /* 0x48 */ 0x00, 0x00, + /* 0x48 */ 0x00, 0x52 /* Insert */, /* 0x4a */ 0x47 /* HOME */, 0x51 /* PPAGE */, /* 0x4c */ 0x53 /* DC */, 0x4f /* END */, /* 0x4e */ 0x49 /* NPAGE */, 0x4d /* RIGHT */, From 735e864757e9dd158bacbf6a5c902442f65890f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 00:29:57 +0200 Subject: [PATCH 0060/1414] Implement CapsLock --- term/usb_keyboard.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 6b8891716..7b67c6e96 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -99,6 +99,8 @@ static grub_uint8_t usb_to_at_map[128] = /* 0x7e */ 0x00, 0x00, }; +#define CAPS_LOCK 0x39 +#define CAPS_LOCK_LED 0x02 /* Valid values for bRequest. See HID definition version 1.11 section 7.2. */ #define USB_HID_GET_REPORT 0x01 @@ -122,7 +124,9 @@ struct grub_usb_keyboard_data { grub_usb_device_t usbdev; grub_uint8_t status; + grub_uint16_t mods; int key; + int interfno; struct grub_usb_desc_endp *endp; }; @@ -237,6 +241,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) } data->usbdev = usbdev; + data->interfno = interfno; data->endp = endp; /* Place the device in boot mode. */ @@ -278,6 +283,8 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) } } + data->mods = 0; + grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]); return 1; @@ -285,6 +292,19 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) +static void +send_leds (struct grub_usb_keyboard_data *termdata) +{ + char report[1]; + report[0] = 0; + if (termdata->mods & GRUB_TERM_STATUS_CAPS) + report[0] |= CAPS_LOCK_LED; + grub_usb_control_msg (termdata->usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, + USB_HID_SET_REPORT, 0x0200, termdata->interfno, + sizeof (report), (char *) report); + grub_errno = GRUB_ERR_NONE; +} + static int grub_usb_keyboard_checkkey (struct grub_term_input *term) { @@ -309,6 +329,13 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) if (actual < 3 || !data[2]) return -1; + if (data[2] == CAPS_LOCK) + { + termdata->mods ^= GRUB_TERM_STATUS_CAPS; + send_leds (termdata); + return -1; + } + grub_dprintf ("usb_keyboard", "report: 0x%02x 0x%02x 0x%02x 0x%02x" " 0x%02x 0x%02x 0x%02x 0x%02x\n", @@ -320,7 +347,8 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) else termdata->key = grub_term_map_key (usb_to_at_map[data[2]], - interpret_status (data[0])); + interpret_status (data[0]) + | termdata->mods); grub_errno = GRUB_ERR_NONE; @@ -348,7 +376,7 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term) { struct grub_usb_keyboard_data *termdata = term->data; - return interpret_status (termdata->status); + return interpret_status (termdata->status) | termdata->mods; } struct grub_usb_attach_desc attach_hook = From d10d149667bd650414dcc4ce5ba055cbc4ed8d0f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 13:54:10 +0200 Subject: [PATCH 0061/1414] Return USB_ERR_INTERNAL instead of grub_errno when appropriate --- bus/usb/usbtrans.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index db2ec097a..4a2e112bf 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -209,7 +209,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, if (! transfer) { grub_dma_free (data_chunk); - return grub_errno; + return GRUB_USB_ERR_INTERNAL; } datablocks = ((size + max - 1) / max); @@ -229,7 +229,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, { grub_free (transfer); grub_dma_free (data_chunk); - return grub_errno; + return GRUB_USB_ERR_INTERNAL; } /* Set up all transfers. */ From 12cbb3ccd0876ef7731c10f22b0a426464cd064d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 13:55:06 +0200 Subject: [PATCH 0062/1414] Don't retire active transaction on a NAK --- bus/usb/uhci.c | 51 +++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 0bba24b54..d0416d7e2 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -519,32 +519,35 @@ grub_uhci_transfer (grub_usb_controller_t dev, grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status); - /* Check if the endpoint is stalled. */ - if (errtd->ctrl_status & (1 << 22)) - err = GRUB_USB_ERR_STALL; + if (!(errtd->ctrl_status & (1 << 23))) + { + /* Check if the endpoint is stalled. */ + if (errtd->ctrl_status & (1 << 22)) + err = GRUB_USB_ERR_STALL; - /* Check if an error related to the data buffer occurred. */ - if (errtd->ctrl_status & (1 << 21)) - err = GRUB_USB_ERR_DATA; + /* Check if an error related to the data buffer occurred. */ + if (errtd->ctrl_status & (1 << 21)) + err = GRUB_USB_ERR_DATA; - /* Check if a babble error occurred. */ - if (errtd->ctrl_status & (1 << 20)) - err = GRUB_USB_ERR_BABBLE; + /* Check if a babble error occurred. */ + if (errtd->ctrl_status & (1 << 20)) + err = GRUB_USB_ERR_BABBLE; - /* Check if a NAK occurred. */ - if (errtd->ctrl_status & (1 << 19)) - err = GRUB_USB_ERR_NAK; + /* Check if a NAK occurred. */ + if (errtd->ctrl_status & (1 << 19)) + err = GRUB_USB_ERR_NAK; - /* Check if a timeout occurred. */ - if (errtd->ctrl_status & (1 << 18)) - err = GRUB_USB_ERR_TIMEOUT; + /* Check if a timeout occurred. */ + if (errtd->ctrl_status & (1 << 18)) + err = GRUB_USB_ERR_TIMEOUT; - /* Check if a bitstuff error occurred. */ - if (errtd->ctrl_status & (1 << 17)) - err = GRUB_USB_ERR_BITSTUFF; + /* Check if a bitstuff error occurred. */ + if (errtd->ctrl_status & (1 << 17)) + err = GRUB_USB_ERR_BITSTUFF; - if (err) - goto fail; + if (err) + break; + } /* Fall through, no errors occurred, so the QH might be updated. */ @@ -554,17 +557,15 @@ grub_uhci_transfer (grub_usb_controller_t dev, { err = GRUB_USB_ERR_STALL; grub_dprintf ("uhci", "transaction timed out\n"); - goto fail; + break; } grub_cpu_idle (); } - grub_dprintf ("uhci", "transaction complete\n"); - - fail: - if (err != GRUB_USB_ERR_NONE) grub_dprintf ("uhci", "transaction failed\n"); + else + grub_dprintf ("uhci", "transaction complete\n"); /* Place the QH back in the free list and deallocate the associated TDs. */ From bcfa613bc4a54b5910489057231dc2fae1eacf01 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 13:56:55 +0200 Subject: [PATCH 0063/1414] correctly pass interfno and don't use GetReport --- term/usb_keyboard.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index d875ac00a..adb84fa94 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -167,11 +167,11 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) /* Place the device in boot mode. */ grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - USB_HID_SET_PROTOCOL, 0, 0, 0, 0); + USB_HID_SET_PROTOCOL, 0, interfno, 0, 0); /* Reports every time an event occurs and not more often than that. */ grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - USB_HID_SET_IDLE, 0<<8, 0, 0, 0); + USB_HID_SET_IDLE, 0<<8, interfno, 0, 0); grub_memcpy (&grub_usb_keyboards[curnum], &grub_usb_keyboard_term, sizeof (grub_usb_keyboards[curnum])); @@ -185,12 +185,18 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) return 0; } + /* Test showed that getting report may make the keyboard go nuts. + Moreover since we're reattaching keyboard it usually sends + an initial message on interrupt pipe and so we retrieve + the same keystatus. + */ +#if 0 { grub_uint8_t report[8]; grub_usb_err_t err; grub_memset (report, 0, sizeof (report)); err = grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_IN, - USB_HID_GET_REPORT, 0x0000, interfno, + USB_HID_GET_REPORT, 0x0100, interfno, sizeof (report), (char *) report); if (err) { @@ -203,6 +209,10 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) data->key = report[2] ? : -1; } } +#else + data->status = 0; + data->key = -1; +#endif grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]); @@ -279,6 +289,8 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term) struct grub_usb_keyboard_data *termdata = term->data; int mods = 0; + grub_usb_keyboard_checkkey (term); + /* Check Shift, Control, and Alt status. */ if (termdata->status & 0x02 || termdata->status & 0x20) mods |= GRUB_TERM_STATUS_SHIFT; From 3ee4474e8dc092c7da7d7cb920d0a86bf1e15bd7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 16:09:43 +0200 Subject: [PATCH 0064/1414] Prepare infrastructure for background USB transfers --- bus/usb/ohci.c | 794 ++++++++++++++++++++++------------------ bus/usb/uhci.c | 205 +++++++---- bus/usb/usb.c | 2 +- bus/usb/usbtrans.c | 40 +- include/grub/usb.h | 14 +- include/grub/usbtrans.h | 2 + 6 files changed, 606 insertions(+), 451 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 7f757485c..ba723996a 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -652,36 +652,32 @@ grub_ohci_transaction (grub_ohci_td_t td, td->next_td = 0; } +struct grub_ohci_transfer_controller_data +{ + grub_uint32_t tderr_phys; + grub_uint32_t td_last_phys; + grub_ohci_ed_t ed_virt; + grub_ohci_td_t td_current_virt; + grub_ohci_td_t td_head_virt; + grub_uint64_t bad_OHCI_delay; +}; + static grub_usb_err_t -grub_ohci_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, int timeout, - grub_size_t *actual) +grub_ohci_setup_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) { struct grub_ohci *o = (struct grub_ohci *) dev->data; - grub_ohci_ed_t ed_virt; int bulk = 0; - grub_ohci_td_t td_head_virt; - grub_ohci_td_t td_current_virt; grub_ohci_td_t td_next_virt; - grub_ohci_td_t tderr_virt = NULL; grub_uint32_t target; grub_uint32_t td_head_phys; grub_uint32_t td_tail_phys; - grub_uint32_t td_last_phys; - grub_uint32_t tderr_phys = 0; - grub_uint32_t status; - grub_uint32_t control; - grub_uint8_t errcode = 0; - grub_usb_err_t err = GRUB_USB_ERR_NONE; int i; - grub_uint64_t maxtime; - grub_uint64_t bad_OHCI_delay = 0; - int err_halt = 0; - int err_timeout = 0; - int err_unrec = 0; - grub_uint32_t intstatus; + struct grub_ohci_transfer_controller_data *cdata; - *actual = 0; + cdata = grub_zalloc (sizeof (*cdata)); + if (!cdata) + return GRUB_USB_ERR_INTERNAL; /* Pre-set target for ED - we need it to find proper ED */ /* Set the device address. */ @@ -703,21 +699,23 @@ grub_ohci_transfer (grub_usb_controller_t dev, case GRUB_USB_TRANSACTION_TYPE_CONTROL: break; - default : + default: + grub_free (cdata); return GRUB_USB_ERR_INTERNAL; } /* Find proper ED or add new ED */ - ed_virt = grub_ohci_find_ed (o, bulk, target); - if (!ed_virt) + cdata->ed_virt = grub_ohci_find_ed (o, bulk, target); + if (!cdata->ed_virt) { grub_dprintf ("ohci","Fatal: No free ED !\n"); + grub_free (cdata); return GRUB_USB_ERR_INTERNAL; } /* Take pointer to first TD from ED */ - td_head_phys = grub_le_to_cpu32 (ed_virt->td_head) & ~0xf; - td_tail_phys = grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf; + td_head_phys = grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf; + td_tail_phys = grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf; /* Sanity check - td_head should be equal to td_tail */ if (td_head_phys != td_tail_phys) /* Should never happen ! */ @@ -726,6 +724,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_dprintf ("ohci", "HEAD = 0x%02x, TAIL = 0x%02x\n", td_head_phys, td_tail_phys); /* XXX: Fix: What to do ? */ + grub_free (cdata); return GRUB_USB_ERR_INTERNAL; } @@ -733,65 +732,64 @@ grub_ohci_transfer (grub_usb_controller_t dev, * we must allocate the first TD. */ if (!td_head_phys) { - td_head_virt = grub_ohci_alloc_td (o); - if (!td_head_virt) + cdata->td_head_virt = grub_ohci_alloc_td (o); + if (!cdata->td_head_virt) return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */ /* We can set td_head only when ED is not active, i.e. * when it is newly allocated. */ - ed_virt->td_head = grub_cpu_to_le32 ( grub_ohci_td_virt2phys (o, - td_head_virt) ); - ed_virt->td_tail = ed_virt->td_head; + cdata->ed_virt->td_head + = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_head_virt)); + cdata->ed_virt->td_tail = cdata->ed_virt->td_head; } else - td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys ); + cdata->td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys ); /* Set TDs */ - td_last_phys = td_head_phys; /* initial value to make compiler happy... */ - for (i = 0, td_current_virt = td_head_virt; + cdata->td_last_phys = td_head_phys; /* initial value to make compiler happy... */ + for (i = 0, cdata->td_current_virt = cdata->td_head_virt; i < transfer->transcnt; i++) { grub_usb_transaction_t tr = &transfer->transactions[i]; - grub_ohci_transaction (td_current_virt, tr->pid, tr->toggle, + grub_ohci_transaction (cdata->td_current_virt, tr->pid, tr->toggle, tr->size, tr->data); /* Set index of TD in transfer */ - td_current_virt->tr_index = (grub_uint32_t) i; + cdata->td_current_virt->tr_index = (grub_uint32_t) i; /* No IRQ request in TD if bad_OHCI set */ if (o->bad_OHCI) - td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21); + cdata->td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21); /* Remember last used (processed) TD phys. addr. */ - td_last_phys = grub_ohci_td_virt2phys (o, td_current_virt); + cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt); /* Allocate next TD */ td_next_virt = grub_ohci_alloc_td (o); if (!td_next_virt) /* No free TD, cancel transfer and free TDs except head TD */ { if (i) /* if i==0 we have nothing to free... */ - grub_ohci_free_tds (o, - grub_ohci_td_phys2virt(o, - grub_le_to_cpu32 (td_head_virt->next_td) ) ); + grub_ohci_free_tds (o, grub_ohci_td_phys2virt(o, + grub_le_to_cpu32 (cdata->td_head_virt->next_td))); /* Reset head TD */ - grub_memset ( (void*)td_head_virt, 0, + grub_memset ( (void*)cdata->td_head_virt, 0, sizeof(struct grub_ohci_td) ); grub_dprintf ("ohci", "Fatal: No free TD !"); + grub_free (cdata); return GRUB_USB_ERR_INTERNAL; } /* Chain TDs */ - td_current_virt->link_td = (grub_uint32_t) td_next_virt; - td_current_virt->next_td = grub_cpu_to_le32 ( - grub_ohci_td_virt2phys (o, - td_next_virt) ); - td_next_virt->prev_td_phys = grub_ohci_td_virt2phys (o, - td_current_virt); - td_current_virt = td_next_virt; + cdata->td_current_virt->link_td = (grub_uint32_t) td_next_virt; + cdata->td_current_virt->next_td + = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, td_next_virt)); + td_next_virt->prev_td_phys + = grub_ohci_td_virt2phys (o, cdata->td_current_virt); + cdata->td_current_virt = td_next_virt; } grub_dprintf ("ohci", "Tail TD (not processed) = %p\n", - td_current_virt); + cdata->td_current_virt); /* Setup the Endpoint Descriptor for transfer. */ /* First set necessary fields in TARGET but keep (or set) skip bit */ @@ -799,12 +797,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, * size never change after first allocation of ED. * But unfortunately max. packet size may change during initial * setup sequence and we must handle it. */ - ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); + cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); /* Set td_tail */ - ed_virt->td_tail - = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, td_current_virt)); + cdata->ed_virt->td_tail + = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_current_virt)); /* Now reset skip bit */ - ed_virt->target = grub_cpu_to_le32 (target); + cdata->ed_virt->target = grub_cpu_to_le32 (target); /* ed_virt->td_head = grub_cpu_to_le32 (td_head); Must not be changed, it is maintained by OHCI */ /* ed_virt->next_ed = grub_cpu_to_le32 (0); Handled by grub_ohci_find_ed, do not change ! */ @@ -834,93 +832,19 @@ grub_ohci_transfer (grub_usb_controller_t dev, } } - /* Safety measure to avoid a hang. */ - maxtime = grub_get_time_ms () + timeout; - - /* Wait until the transfer is completed or STALLs. */ - do - { - /* Check transfer status */ - intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - if (!o->bad_OHCI && (intstatus & 0x2) != 0) - { - /* Remember last successful TD */ - tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; - /* Reset DoneHead */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - /* if TD is last, finish */ - if (tderr_phys == td_last_phys) - { - if (grub_le_to_cpu32 (ed_virt->td_head) & 1) - err_halt = 1; - break; - } - continue; - } + return GRUB_USB_ERR_NONE; +} - if ((intstatus & 0x10) != 0) - { /* Unrecoverable error - only reset can help...! */ - err_unrec = 1; - break; - } - - /* Detected a HALT. */ - if (err_halt || (grub_le_to_cpu32 (ed_virt->td_head) & 1)) - { - err_halt = 1; - /* ED is halted, but donehead event can happened in the meantime */ - intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - if (!o->bad_OHCI && (intstatus & 0x2) != 0) - /* Don't break loop now, first do donehead action(s) */ - continue; - break; - } - - /* bad OHCI handling */ - if ( (grub_le_to_cpu32 (ed_virt->td_head) & ~0xf) == - (grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf) ) /* Empty ED */ - { - if (o->bad_OHCI) /* Bad OHCI detected previously */ - { - /* Try get last successful TD. */ - tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; - if (tderr_phys)/* Reset DoneHead if we were successful */ - { - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - } - /* Check the HALT bit */ - if (grub_le_to_cpu32 (ed_virt->td_head) & 1) - err_halt = 1; - break; - } - else /* Detection of bad OHCI */ - /* We should wait short time (~2ms) before we say that - * it is bad OHCI to prevent some hazard - - * donehead can react in the meantime. This waiting is done - * only once per OHCI driver "live cycle". */ - if (!bad_OHCI_delay) /* Set delay time */ - bad_OHCI_delay = grub_get_time_ms () + 2; - else if (grub_get_time_ms () >= bad_OHCI_delay) - o->bad_OHCI = 1; - continue; - } - - /* Timeout ? */ - if (grub_get_time_ms () > maxtime) - { - err_timeout = 1; - break; - } - - grub_cpu_idle (); - } - while (1); +static void +pre_finish_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) +{ + struct grub_ohci *o = dev->data; + struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; + grub_uint32_t target; + grub_uint32_t status; + grub_uint32_t control; + grub_uint32_t intstatus; /* There are many ways how the loop above can finish: * - normally without any error via INTSTATUS WDH bit @@ -952,8 +876,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Remember target for debug and set skip flag in ED */ /* It should be normaly not necessary but we need it at least * in case of timeout */ - target = grub_le_to_cpu32 ( ed_virt->target ); - ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); + target = grub_le_to_cpu32 ( cdata->ed_virt->target ); + cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); /* Read registers for debug - they should be read now because * debug prints case unwanted delays, so something can happen * in the meantime... */ @@ -964,224 +888,23 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n", control, status); grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n", - intstatus, tderr_phys, td_last_phys); - grub_dprintf ("ohci", "err_unrec=%d, err_timeout=%d \n\t\t err_halt=%d, bad_OHCI=%d\n", - err_unrec, err_timeout, err_halt, o->bad_OHCI); + intstatus, cdata->tderr_phys, cdata->td_last_phys); grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n", target, - grub_le_to_cpu32 (ed_virt->td_head), - grub_le_to_cpu32 (ed_virt->td_tail) ); + grub_le_to_cpu32 (cdata->ed_virt->td_head), + grub_le_to_cpu32 (cdata->ed_virt->td_tail) ); - if (!err_halt && !err_unrec && !err_timeout) /* normal finish */ - { - /* Simple workaround if donehead is not working */ - if (o->bad_OHCI && - ( !tderr_phys || (tderr_phys != td_last_phys) ) ) - { - grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n"); - tderr_phys = td_last_phys; - /* I hope we can do it as transfer (most probably) finished OK */ - } - /* Prepare pointer to last processed TD */ - tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys); - /* Set index of last processed TD */ - if (tderr_virt) - transfer->last_trans = tderr_virt->tr_index; - else - transfer->last_trans = -1; - *actual = transfer->size + 1; - } +} - else if (err_halt) /* error, ED is halted by OHCI, i.e. can be modified */ - { - /* First we must get proper tderr_phys value */ - if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */ - { - if ( tderr_phys ) /* check if tderr_phys points to TD with error */ - errcode = grub_le_to_cpu32 ( grub_ohci_td_phys2virt (o, - tderr_phys)->token ) - >> 28; - if ( !tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */ - { /* Retired TD with error should be previous TD to ED->td_head */ - tderr_phys = grub_ohci_td_phys2virt (o, - grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf ) - ->prev_td_phys; - } - } - - /* Even if we have "good" OHCI, in some cases - * tderr_phys can be zero, check it */ - else if ( !tderr_phys ) - { /* Retired TD with error should be previous TD to ED->td_head */ - tderr_phys = grub_ohci_td_phys2virt (o, - grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf ) - ->prev_td_phys; - } - - /* Prepare pointer to last processed TD and get error code */ - tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys); - /* Set index of last processed TD */ - if (tderr_virt) - { - errcode = grub_le_to_cpu32 ( tderr_virt->token ) >> 28; - transfer->last_trans = tderr_virt->tr_index; - } - else - transfer->last_trans = -1; - - /* Evaluation of error code */ - grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n", - tderr_phys, errcode); - switch (errcode) - { - case 0: - /* XXX: Should not happen! */ - grub_error (GRUB_ERR_IO, "OHCI failed without reporting the reason"); - err = GRUB_USB_ERR_INTERNAL; - break; - - case 1: - /* XXX: CRC error. */ - err = GRUB_USB_ERR_TIMEOUT; - break; - - case 2: - err = GRUB_USB_ERR_BITSTUFF; - break; - - case 3: - /* XXX: Data Toggle error. */ - err = GRUB_USB_ERR_DATA; - break; - - case 4: - err = GRUB_USB_ERR_STALL; - break; - - case 5: - /* XXX: Not responding. */ - err = GRUB_USB_ERR_TIMEOUT; - break; - - case 6: - /* XXX: PID Check bits failed. */ - err = GRUB_USB_ERR_BABBLE; - break; - - case 7: - /* XXX: PID unexpected failed. */ - err = GRUB_USB_ERR_BABBLE; - break; - - case 8: - /* XXX: Data overrun error. */ - err = GRUB_USB_ERR_DATA; - grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", - tderr_virt, tderr_virt->tr_index); - break; - - case 9: - /* XXX: Data underrun error. */ - grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", - tderr_virt, tderr_virt->tr_index); - if (transfer->last_trans == -1) - break; - *actual = transfer->transactions[transfer->last_trans].size - - (grub_le_to_cpu32 (tderr_virt->buffer_end) - - grub_le_to_cpu32 (tderr_virt->buffer)) - + transfer->transactions[transfer->last_trans].preceding; - break; - - case 10: - /* XXX: Reserved. */ - err = GRUB_USB_ERR_NAK; - break; - - case 11: - /* XXX: Reserved. */ - err = GRUB_USB_ERR_NAK; - break; - - case 12: - /* XXX: Buffer overrun. */ - err = GRUB_USB_ERR_DATA; - break; - - case 13: - /* XXX: Buffer underrun. */ - err = GRUB_USB_ERR_DATA; - break; - - default: - err = GRUB_USB_ERR_NAK; - break; - } - - } - - else if (err_unrec) - { - /* Don't try to get error code and last processed TD for proper - * toggle bit value - anything can be invalid */ - err = GRUB_USB_ERR_UNRECOVERABLE; - grub_dprintf("ohci", "Unrecoverable error!"); - - /* Do OHCI reset in case of unrecoverable error - maybe we will need - * do more - re-enumerate bus etc. (?) */ - - /* Suspend the OHCI by issuing a reset. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - grub_millisleep (1); - grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); - - /* Misc. resets. */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - - /* Enable the OHCI. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - (2 << 6) - | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE - | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); - } - - else if (err_timeout) - { - /* In case of timeout do not detect error from TD */ - err = GRUB_ERR_TIMEOUT; - grub_dprintf("ohci", "Timeout !\n"); - - /* We should wait for next SOF to be sure that ED is unaccessed - * by OHCI */ - /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); - /* Wait for new SOF */ - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); - - /* Now we must find last processed TD if bad_OHCI == TRUE */ - if (o->bad_OHCI) - { /* Retired TD with error should be previous TD to ED->td_head */ - tderr_phys = grub_ohci_td_phys2virt (o, - grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf) - ->prev_td_phys; - } - tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys); - if (tderr_virt) - transfer->last_trans = tderr_virt->tr_index; - else - transfer->last_trans = -1; - } +static void +finish_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) +{ + struct grub_ohci *o = dev->data; + struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ - ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf); + cdata->ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf); /* At this point always should be: * ED has skip bit set and halted or empty or after next SOF, @@ -1195,23 +918,368 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); /* Un-chainig of last TD */ - if (td_current_virt->prev_td_phys) + if (cdata->td_current_virt->prev_td_phys) { grub_ohci_td_t td_prev_virt - = grub_ohci_td_phys2virt (o, td_current_virt->prev_td_phys); - - td_next_virt = (grub_ohci_td_t) td_prev_virt->link_td; - if (td_current_virt == td_next_virt) + = grub_ohci_td_phys2virt (o, cdata->td_current_virt->prev_td_phys); + + if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td) td_prev_virt->link_td = 0; } - grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x, errcode=0x%02x\n", - err, errcode); - grub_ohci_free_tds (o, td_head_virt); + grub_dprintf ("ohci", "OHCI finished, freeing\n"); + grub_ohci_free_tds (o, cdata->td_head_virt); +} + +static grub_usb_err_t +parse_halt (grub_usb_controller_t dev, + grub_usb_transfer_t transfer, + grub_size_t *actual) +{ + struct grub_ohci *o = dev->data; + struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; + grub_uint8_t errcode = 0; + grub_usb_err_t err = GRUB_USB_ERR_NAK; + grub_ohci_td_t tderr_virt = NULL; + + *actual = 0; + + pre_finish_transfer (dev, transfer); + + /* First we must get proper tderr_phys value */ + if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */ + { + if (cdata->tderr_phys) /* check if tderr_phys points to TD with error */ + errcode = grub_le_to_cpu32 (grub_ohci_td_phys2virt (o, + cdata->tderr_phys)->token) + >> 28; + if ( !cdata->tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */ + { /* Retired TD with error should be previous TD to ED->td_head */ + cdata->tderr_phys = grub_ohci_td_phys2virt (o, + grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf ) + ->prev_td_phys; + } + } + /* Even if we have "good" OHCI, in some cases + * tderr_phys can be zero, check it */ + else if (!cdata->tderr_phys) + /* Retired TD with error should be previous TD to ED->td_head */ + cdata->tderr_phys + = grub_ohci_td_phys2virt (o, + grub_le_to_cpu32 (cdata->ed_virt->td_head) + & ~0xf)->prev_td_phys; + + + /* Prepare pointer to last processed TD and get error code */ + tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys); + /* Set index of last processed TD */ + if (tderr_virt) + { + errcode = grub_le_to_cpu32 (tderr_virt->token) >> 28; + transfer->last_trans = tderr_virt->tr_index; + } + else + transfer->last_trans = -1; + + /* Evaluation of error code */ + grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n", + cdata->tderr_phys, errcode); + switch (errcode) + { + case 0: + /* XXX: Should not happen! */ + grub_error (GRUB_ERR_IO, "OHCI failed without reporting the reason"); + err = GRUB_USB_ERR_INTERNAL; + break; + + case 1: + /* XXX: CRC error. */ + err = GRUB_USB_ERR_TIMEOUT; + break; + + case 2: + err = GRUB_USB_ERR_BITSTUFF; + break; + + case 3: + /* XXX: Data Toggle error. */ + err = GRUB_USB_ERR_DATA; + break; + + case 4: + err = GRUB_USB_ERR_STALL; + break; + + case 5: + /* XXX: Not responding. */ + err = GRUB_USB_ERR_TIMEOUT; + break; + + case 6: + /* XXX: PID Check bits failed. */ + err = GRUB_USB_ERR_BABBLE; + break; + + case 7: + /* XXX: PID unexpected failed. */ + err = GRUB_USB_ERR_BABBLE; + break; + + case 8: + /* XXX: Data overrun error. */ + err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", + tderr_virt, tderr_virt->tr_index); + break; + + case 9: + /* XXX: Data underrun error. */ + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", + tderr_virt, tderr_virt->tr_index); + if (transfer->last_trans == -1) + break; + *actual = transfer->transactions[transfer->last_trans].size + - (grub_le_to_cpu32 (tderr_virt->buffer_end) + - grub_le_to_cpu32 (tderr_virt->buffer)) + + transfer->transactions[transfer->last_trans].preceding; + err = GRUB_USB_ERR_NONE; + break; + + case 10: + /* XXX: Reserved. */ + err = GRUB_USB_ERR_NAK; + break; + + case 11: + /* XXX: Reserved. */ + err = GRUB_USB_ERR_NAK; + break; + + case 12: + /* XXX: Buffer overrun. */ + err = GRUB_USB_ERR_DATA; + break; + + case 13: + /* XXX: Buffer underrun. */ + err = GRUB_USB_ERR_DATA; + break; + + default: + err = GRUB_USB_ERR_NAK; + break; + } + + finish_transfer (dev, transfer); return err; } +static grub_usb_err_t +parse_success (grub_usb_controller_t dev, + grub_usb_transfer_t transfer, + grub_size_t *actual) +{ + struct grub_ohci *o = dev->data; + struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; + grub_ohci_td_t tderr_virt = NULL; + + pre_finish_transfer (dev, transfer); + + /* Simple workaround if donehead is not working */ + if (o->bad_OHCI && + (!cdata->tderr_phys || (cdata->tderr_phys != cdata->td_last_phys))) + { + grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n"); + cdata->tderr_phys = cdata->td_last_phys; + /* I hope we can do it as transfer (most probably) finished OK */ + } + /* Prepare pointer to last processed TD */ + tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys); + /* Set index of last processed TD */ + if (tderr_virt) + transfer->last_trans = tderr_virt->tr_index; + else + transfer->last_trans = -1; + *actual = transfer->size + 1; + + finish_transfer (dev, transfer); + + return GRUB_USB_ERR_NONE; +} + +static grub_usb_err_t +parse_unrec (grub_usb_controller_t dev, + grub_usb_transfer_t transfer, + grub_size_t *actual) +{ + struct grub_ohci *o = dev->data; + + *actual = 0; + + pre_finish_transfer (dev, transfer); + + /* Don't try to get error code and last processed TD for proper + * toggle bit value - anything can be invalid */ + grub_dprintf("ohci", "Unrecoverable error!"); + + /* Do OHCI reset in case of unrecoverable error - maybe we will need + * do more - re-enumerate bus etc. (?) */ + + /* Suspend the OHCI by issuing a reset. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + grub_millisleep (1); + grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); + + /* Misc. resets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + (2 << 6) + | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE + | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); + finish_transfer (dev, transfer); + + return GRUB_USB_ERR_UNRECOVERABLE; +} + +static grub_usb_err_t +grub_ohci_check_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer, + grub_size_t *actual) +{ + struct grub_ohci *o = dev->data; + struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; + grub_uint32_t intstatus; + + /* Check transfer status */ + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + if (!o->bad_OHCI && (intstatus & 0x2) != 0) + { + /* Remember last successful TD */ + cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + /* Reset DoneHead */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + /* if TD is last, finish */ + if (cdata->tderr_phys == cdata->td_last_phys) + { + if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1) + return parse_halt (dev, transfer, actual); + else + return parse_success (dev, transfer, actual); + } + return GRUB_USB_ERR_WAIT; + } + + if ((intstatus & 0x10) != 0) + /* Unrecoverable error - only reset can help...! */ + return parse_unrec (dev, transfer, actual); + + /* Detected a HALT. */ + if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)) + { + /* ED is halted, but donehead event can happened in the meantime */ + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + if (!o->bad_OHCI && (intstatus & 0x2) != 0) + { + /* Remember last successful TD */ + cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + /* Reset DoneHead */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + /* if TD is last, finish */ + } + return parse_halt (dev, transfer, actual); + } + + /* bad OHCI handling */ + if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) == + (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */ + { + if (o->bad_OHCI) /* Bad OHCI detected previously */ + { + /* Try get last successful TD. */ + cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + if (cdata->tderr_phys)/* Reset DoneHead if we were successful */ + { + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* Read back of register should ensure it is really written */ + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + } + /* Check the HALT bit */ + if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1) + return parse_halt (dev, transfer, actual); + else + return parse_success (dev, transfer, actual); + } + else /* Detection of bad OHCI */ + /* We should wait short time (~2ms) before we say that + * it is bad OHCI to prevent some hazard - + * donehead can react in the meantime. This waiting is done + * only once per OHCI driver "live cycle". */ + if (!cdata->bad_OHCI_delay) /* Set delay time */ + cdata->bad_OHCI_delay = grub_get_time_ms () + 2; + else if (grub_get_time_ms () >= cdata->bad_OHCI_delay) + o->bad_OHCI = 1; + return GRUB_USB_ERR_WAIT; + } + + return GRUB_USB_ERR_WAIT; +} + +static grub_usb_err_t +grub_ohci_cancel_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) +{ + struct grub_ohci *o = dev->data; + struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; + grub_ohci_td_t tderr_virt = NULL; + + pre_finish_transfer (dev, transfer); + + grub_dprintf("ohci", "Timeout !\n"); + + /* We should wait for next SOF to be sure that ED is unaccessed + * by OHCI */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + + /* Now we must find last processed TD if bad_OHCI == TRUE */ + if (o->bad_OHCI) + /* Retired TD with error should be previous TD to ED->td_head */ + cdata->tderr_phys + = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head) + & ~0xf)->prev_td_phys; + + tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys); + if (tderr_virt) + transfer->last_trans = tderr_virt->tr_index; + else + transfer->last_trans = -1; + + finish_transfer (dev, transfer); + + return GRUB_USB_ERR_NONE; +} + static grub_err_t grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) @@ -1398,7 +1466,9 @@ static struct grub_usb_controller_dev usb_controller = { .name = "ohci", .iterate = grub_ohci_iterate, - .transfer = grub_ohci_transfer, + .setup_transfer = grub_ohci_setup_transfer, + .check_transfer = grub_ohci_check_transfer, + .cancel_transfer = grub_ohci_cancel_transfer, .hubports = grub_ohci_hubports, .portstatus = grub_ohci_portstatus, .detect_dev = grub_ohci_detect_dev diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index d0416d7e2..4792f961a 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -438,26 +438,35 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, return td; } +struct grub_uhci_transfer_controller_data +{ + grub_uhci_qh_t qh; + grub_uhci_td_t td_first; +}; + static grub_usb_err_t -grub_uhci_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - int timeout, grub_size_t *actual) +grub_uhci_setup_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) { struct grub_uhci *u = (struct grub_uhci *) dev->data; - grub_uhci_qh_t qh; grub_uhci_td_t td; - grub_uhci_td_t td_first = NULL; grub_uhci_td_t td_prev = NULL; - grub_usb_err_t err = GRUB_USB_ERR_NONE; int i; - grub_uint64_t endtime; + struct grub_uhci_transfer_controller_data *cdata; - *actual = 0; + cdata = grub_malloc (sizeof (*cdata)); + if (!cdata) + return GRUB_USB_ERR_INTERNAL; + + cdata->td_first = NULL; /* Allocate a queue head for the transfer queue. */ - qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL); - if (! qh) - return GRUB_USB_ERR_INTERNAL; + cdata->qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL); + if (! cdata->qh) + { + grub_free (cdata); + return GRUB_USB_ERR_INTERNAL; + } grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase); @@ -470,18 +479,20 @@ grub_uhci_transfer (grub_usb_controller_t dev, tr->size, tr->data); if (! td) { + grub_size_t actual = 0; /* Terminate and free. */ td_prev->linkptr2 = 0; td_prev->linkptr = 1; - if (td_first) - grub_free_queue (u, td_first, NULL, actual); + if (cdata->td_first) + grub_free_queue (u, cdata->td_first, NULL, &actual); + grub_free (cdata); return GRUB_USB_ERR_INTERNAL; } - if (! td_first) - td_first = td; + if (! cdata->td_first) + cdata->td_first = td; else { td_prev->linkptr2 = (grub_uint32_t) td; @@ -497,82 +508,112 @@ grub_uhci_transfer (grub_usb_controller_t dev, /* Link it into the queue and terminate. Now the transaction can take place. */ - qh->elinkptr = (grub_uint32_t) td_first; + cdata->qh->elinkptr = (grub_uint32_t) cdata->td_first; grub_dprintf ("uhci", "initiate transaction\n"); - /* Wait until either the transaction completed or an error - occurred. */ - endtime = grub_get_time_ms () + timeout; - for (;;) + transfer->controller_data = cdata; + + return GRUB_USB_ERR_NONE; +} + +static grub_usb_err_t +grub_uhci_check_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer, + grub_size_t *actual) +{ + struct grub_uhci *u = (struct grub_uhci *) dev->data; + grub_uhci_td_t errtd; + struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data; + + *actual = 0; + + errtd = (grub_uhci_td_t) (cdata->qh->elinkptr & ~0x0f); + + grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n", + errtd->ctrl_status, errtd->buffer & (~15), errtd); + + /* Check if the transaction completed. */ + if (cdata->qh->elinkptr & 1) { - grub_uhci_td_t errtd; + grub_dprintf ("uhci", "transaction complete\n"); - errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f); - - grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n", - errtd->ctrl_status, errtd->buffer & (~15), errtd); - - /* Check if the transaction completed. */ - if (qh->elinkptr & 1) - break; - - grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status); - - if (!(errtd->ctrl_status & (1 << 23))) - { - /* Check if the endpoint is stalled. */ - if (errtd->ctrl_status & (1 << 22)) - err = GRUB_USB_ERR_STALL; - - /* Check if an error related to the data buffer occurred. */ - if (errtd->ctrl_status & (1 << 21)) - err = GRUB_USB_ERR_DATA; - - /* Check if a babble error occurred. */ - if (errtd->ctrl_status & (1 << 20)) - err = GRUB_USB_ERR_BABBLE; - - /* Check if a NAK occurred. */ - if (errtd->ctrl_status & (1 << 19)) - err = GRUB_USB_ERR_NAK; - - /* Check if a timeout occurred. */ - if (errtd->ctrl_status & (1 << 18)) - err = GRUB_USB_ERR_TIMEOUT; - - /* Check if a bitstuff error occurred. */ - if (errtd->ctrl_status & (1 << 17)) - err = GRUB_USB_ERR_BITSTUFF; - - if (err) - break; - } - - /* Fall through, no errors occurred, so the QH might be - updated. */ - grub_dprintf ("uhci", "transaction fallthrough\n"); - - if (grub_get_time_ms () > endtime) - { - err = GRUB_USB_ERR_STALL; - grub_dprintf ("uhci", "transaction timed out\n"); - break; - } - grub_cpu_idle (); + /* Place the QH back in the free list and deallocate the associated + TDs. */ + cdata->qh->elinkptr = 1; + grub_free_queue (u, cdata->td_first, transfer, actual); + grub_free (cdata); + return GRUB_USB_ERR_NONE; } - if (err != GRUB_USB_ERR_NONE) - grub_dprintf ("uhci", "transaction failed\n"); - else - grub_dprintf ("uhci", "transaction complete\n"); + grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status); + + if (!(errtd->ctrl_status & (1 << 23))) + { + grub_usb_err_t err = GRUB_USB_ERR_NONE; + + /* Check if the endpoint is stalled. */ + if (errtd->ctrl_status & (1 << 22)) + err = GRUB_USB_ERR_STALL; + + /* Check if an error related to the data buffer occurred. */ + if (errtd->ctrl_status & (1 << 21)) + err = GRUB_USB_ERR_DATA; + + /* Check if a babble error occurred. */ + if (errtd->ctrl_status & (1 << 20)) + err = GRUB_USB_ERR_BABBLE; + + /* Check if a NAK occurred. */ + if (errtd->ctrl_status & (1 << 19)) + err = GRUB_USB_ERR_NAK; + + /* Check if a timeout occurred. */ + if (errtd->ctrl_status & (1 << 18)) + err = GRUB_USB_ERR_TIMEOUT; + + /* Check if a bitstuff error occurred. */ + if (errtd->ctrl_status & (1 << 17)) + err = GRUB_USB_ERR_BITSTUFF; + + if (err) + { + grub_dprintf ("uhci", "transaction failed\n"); + + /* Place the QH back in the free list and deallocate the associated + TDs. */ + cdata->qh->elinkptr = 1; + grub_free_queue (u, cdata->td_first, transfer, actual); + grub_free (cdata); + + return err; + } + } + + /* Fall through, no errors occurred, so the QH might be + updated. */ + grub_dprintf ("uhci", "transaction fallthrough\n"); + + return GRUB_USB_ERR_WAIT; +} + +static grub_usb_err_t +grub_uhci_cancel_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) +{ + struct grub_uhci *u = (struct grub_uhci *) dev->data; + grub_size_t actual; + struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data; + + grub_dprintf ("uhci", "transaction cancel\n"); /* Place the QH back in the free list and deallocate the associated TDs. */ - qh->elinkptr = 1; - grub_free_queue (u, td_first, transfer, actual); + cdata->qh->elinkptr = 1; + grub_free_queue (u, cdata->td_first, transfer, &actual); + grub_free (cdata); - return err; + return GRUB_USB_ERR_NONE; } static int @@ -706,7 +747,9 @@ static struct grub_usb_controller_dev usb_controller = { .name = "uhci", .iterate = grub_uhci_iterate, - .transfer = grub_uhci_transfer, + .setup_transfer = grub_uhci_setup_transfer, + .check_transfer = grub_uhci_check_transfer, + .cancel_transfer = grub_uhci_cancel_transfer, .hubports = grub_uhci_hubports, .portstatus = grub_uhci_portstatus, .detect_dev = grub_uhci_detect_dev diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 2bd805ef2..80d386c8d 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -338,7 +338,7 @@ grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc) GRUB_MOD_INIT(usb) { - grub_term_poll_usb = grub_usb_poll_devices; + // grub_term_poll_usb = grub_usb_poll_devices; } GRUB_MOD_FINI(usb) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 4a2e112bf..27377a3a5 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -23,6 +23,39 @@ #include #include #include +#include + +static grub_usb_err_t +grub_usb_execute_and_wait_transfer (grub_usb_device_t dev, + grub_usb_transfer_t transfer, + int timeout, grub_size_t *actual) +{ + grub_usb_err_t err; + grub_uint64_t endtime; + + endtime = grub_get_time_ms () + timeout; + err = dev->controller.dev->setup_transfer (&dev->controller, transfer); + if (err) + return err; + while (1) + { + err = dev->controller.dev->check_transfer (&dev->controller, transfer, + actual); + if (!err) + return GRUB_USB_ERR_NONE; + if (err != GRUB_USB_ERR_WAIT) + return err; + if (grub_get_time_ms () > endtime) + { + err = dev->controller.dev->cancel_transfer (&dev->controller, + transfer); + if (err) + return err; + return GRUB_USB_ERR_TIMEOUT; + } + grub_cpu_idle (); + } +} grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, @@ -147,8 +180,8 @@ grub_usb_control_msg (grub_usb_device_t dev, transfer->transactions[datablocks + 1].toggle = 1; - err = dev->controller.dev->transfer (&dev->controller, transfer, - 1000, &actual); + err = grub_usb_execute_and_wait_transfer (dev, transfer, 1000, &actual); + grub_dprintf ("usb", "control: err=%d\n", err); grub_free (transfer->transactions); @@ -248,8 +281,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, size -= tr->size; } - err = dev->controller.dev->transfer (&dev->controller, transfer, timeout, - actual); + err = grub_usb_execute_and_wait_transfer (dev, transfer, timeout, actual); /* We must remember proper toggle value even if some transactions * were not processed - correct value should be inversion of last * processed transaction (TD). */ diff --git a/include/grub/usb.h b/include/grub/usb.h index bb3336580..e7d119646 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -30,6 +30,7 @@ typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t; typedef enum { GRUB_USB_ERR_NONE, + GRUB_USB_ERR_WAIT, GRUB_USB_ERR_INTERNAL, GRUB_USB_ERR_STALL, GRUB_USB_ERR_DATA, @@ -97,6 +98,7 @@ grub_usb_err_t grub_usb_root_hub (grub_usb_controller_t controller); + /* XXX: All handled by libusb for now. */ struct grub_usb_controller_dev { @@ -105,9 +107,15 @@ struct grub_usb_controller_dev int (*iterate) (int (*hook) (grub_usb_controller_t dev)); - grub_usb_err_t (*transfer) (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - int timeout, grub_size_t *actual); + grub_usb_err_t (*setup_transfer) (grub_usb_controller_t dev, + grub_usb_transfer_t transfer); + + grub_usb_err_t (*check_transfer) (grub_usb_controller_t dev, + grub_usb_transfer_t transfer, + grub_size_t *actual); + + grub_usb_err_t (*cancel_transfer) (grub_usb_controller_t dev, + grub_usb_transfer_t transfer); int (*hubports) (grub_usb_controller_t dev); diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index a5bb2e8b2..486e83f40 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -62,6 +62,8 @@ struct grub_usb_transfer int last_trans; /* Index of last processed transaction in OHCI/UHCI driver. */ + + void *controller_data; }; typedef struct grub_usb_transfer *grub_usb_transfer_t; From e959937cfd6fca6f85da92c9b5b7f0153b276102 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 17:12:51 +0200 Subject: [PATCH 0065/1414] Use background transfers for usb_keyboard --- bus/usb/usbtrans.c | 97 +++++++++++++++++++++++++++++++++-------- include/grub/usb.h | 5 +++ include/grub/usbtrans.h | 6 +++ term/usb_keyboard.c | 41 ++++++++++++++--- 4 files changed, 127 insertions(+), 22 deletions(-) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 27377a3a5..5d6966ecc 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -195,29 +195,27 @@ grub_usb_control_msg (grub_usb_device_t dev, return err; } -static grub_usb_err_t -grub_usb_bulk_readwrite (grub_usb_device_t dev, - int endpoint, grub_size_t size0, char *data_in, - grub_transfer_type_t type, int timeout, - grub_size_t *actual) +static grub_usb_transfer_t +grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, + int endpoint, grub_size_t size0, char *data_in, + grub_transfer_type_t type) { int i; grub_usb_transfer_t transfer; int datablocks; unsigned int max; - grub_usb_err_t err; - int toggle = dev->toggle[endpoint]; volatile char *data; grub_uint32_t data_addr; struct grub_pci_dma_chunk *data_chunk; grub_size_t size = size0; + int toggle = dev->toggle[endpoint]; grub_dprintf ("usb", "bulk: size=0x%02x type=%d\n", size, type); /* FIXME: avoid allocation any kind of buffer in a first place. */ data_chunk = grub_memalign_dma32 (128, size); if (!data_chunk) - return GRUB_USB_ERR_INTERNAL; + return NULL; data = grub_dma_get_virt (data_chunk); data_addr = grub_dma_get_phys (data_chunk); if (type == GRUB_USB_TRANSFER_TYPE_OUT) @@ -242,7 +240,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, if (! transfer) { grub_dma_free (data_chunk); - return GRUB_USB_ERR_INTERNAL; + return NULL; } datablocks = ((size + max - 1) / max); @@ -251,9 +249,12 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, transfer->endpoint = endpoint & 15; transfer->devaddr = dev->addr; transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; + transfer->dir = type; transfer->max = max; transfer->dev = dev; transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */ + transfer->data_chunk = data_chunk; + transfer->data = data_in; /* Allocate an array of transfer data structures. */ transfer->transactions = grub_malloc (transfer->transcnt @@ -262,7 +263,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, { grub_free (transfer); grub_dma_free (data_chunk); - return GRUB_USB_ERR_INTERNAL; + return NULL; } /* Set up all transfers. */ @@ -280,24 +281,51 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, tr->preceding = i * max; size -= tr->size; } + return transfer; +} + +static void +grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer) +{ + grub_usb_device_t dev = transfer->dev; + int toggle = dev->toggle[transfer->endpoint]; - err = grub_usb_execute_and_wait_transfer (dev, transfer, timeout, actual); /* We must remember proper toggle value even if some transactions * were not processed - correct value should be inversion of last * processed transaction (TD). */ if (transfer->last_trans >= 0) toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1; else - toggle = dev->toggle[endpoint]; /* Nothing done, take original */ - grub_dprintf ("usb", "bulk: err=%d, toggle=%d\n", err, toggle); - dev->toggle[endpoint] = toggle; + toggle = dev->toggle[transfer->endpoint]; /* Nothing done, take original */ + grub_dprintf ("usb", "bulk: toggle=%d\n", toggle); + dev->toggle[transfer->endpoint] = toggle; + + if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN) + grub_memcpy (transfer->data, (void *) + grub_dma_get_virt (transfer->data_chunk), + transfer->size + 1); grub_free (transfer->transactions); grub_free (transfer); - grub_dma_free (data_chunk); + grub_dma_free (transfer->data_chunk); +} - if (type == GRUB_USB_TRANSFER_TYPE_IN) - grub_memcpy (data_in, (char *) data, size0); +static grub_usb_err_t +grub_usb_bulk_readwrite (grub_usb_device_t dev, + int endpoint, grub_size_t size0, char *data_in, + grub_transfer_type_t type, int timeout, + grub_size_t *actual) +{ + grub_usb_err_t err; + grub_usb_transfer_t transfer; + + transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size0, + data_in, type); + if (!transfer) + return GRUB_USB_ERR_INTERNAL; + err = grub_usb_execute_and_wait_transfer (dev, transfer, timeout, actual); + + grub_usb_bulk_finish_readwrite (transfer); return err; } @@ -329,6 +357,41 @@ grub_usb_bulk_read (grub_usb_device_t dev, return err; } +grub_usb_err_t +grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual) +{ + grub_usb_err_t err; + grub_usb_device_t dev = transfer->dev; + + err = dev->controller.dev->check_transfer (&dev->controller, transfer, + actual); + if (err == GRUB_USB_ERR_WAIT) + return err; + + grub_usb_bulk_finish_readwrite (transfer); + + return err; +} + +grub_usb_transfer_t +grub_usb_bulk_read_background (grub_usb_device_t dev, + int endpoint, grub_size_t size, void *data) +{ + grub_usb_err_t err; + grub_usb_transfer_t transfer; + + transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size, + data, GRUB_USB_TRANSFER_TYPE_IN); + if (!transfer) + return NULL; + + err = dev->controller.dev->setup_transfer (&dev->controller, transfer); + if (err) + return NULL; + + return transfer; +} + grub_usb_err_t grub_usb_bulk_read_extended (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data, diff --git a/include/grub/usb.h b/include/grub/usb.h index e7d119646..768ec2f66 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -274,5 +274,10 @@ grub_usb_err_t grub_usb_bulk_read_extended (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data, int timeout, grub_size_t *actual); +grub_usb_transfer_t +grub_usb_bulk_read_background (grub_usb_device_t dev, + int endpoint, grub_size_t size, void *data); +grub_usb_err_t +grub_usb_check_transfer (grub_usb_transfer_t trans, grub_size_t *actual); #endif /* GRUB_USB_H */ diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 486e83f40..a8aca3119 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -56,6 +56,8 @@ struct grub_usb_transfer grub_transaction_type_t type; + grub_transfer_type_t dir; + struct grub_usb_device *dev; struct grub_usb_transaction *transactions; @@ -64,6 +66,10 @@ struct grub_usb_transfer /* Index of last processed transaction in OHCI/UHCI driver. */ void *controller_data; + + /* Used when finishing transfer to copy data back. */ + struct grub_pci_dma_chunk *data_chunk; + void *data; }; typedef struct grub_usb_transfer *grub_usb_transfer_t; diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index adb84fa94..1a486b53d 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -84,6 +84,9 @@ struct grub_usb_keyboard_data grub_uint8_t status; int key; struct grub_usb_desc_endp *endp; + grub_usb_transfer_t transfer; + grub_uint8_t report[8]; + int dead; }; static struct grub_term_input grub_usb_keyboards[16]; @@ -214,8 +217,20 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) data->key = -1; #endif + data->transfer = grub_usb_bulk_read_background (usbdev, + data->endp->endp_addr, + sizeof (data->report), + (char *) data->report); + if (!data->transfer) + { + grub_print_error (); + return 0; + } + grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]); + data->dead = 0; + return 1; } @@ -224,19 +239,35 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) static int grub_usb_keyboard_checkkey (struct grub_term_input *term) { - grub_uint8_t data[8]; grub_usb_err_t err; struct grub_usb_keyboard_data *termdata = term->data; + grub_uint8_t data[sizeof (termdata->report)]; grub_size_t actual; if (termdata->key != -1) return termdata->key; - data[2] = 0; + if (termdata->dead) + return -1; + /* Poll interrupt pipe. */ - err = grub_usb_bulk_read_extended (termdata->usbdev, - termdata->endp->endp_addr, sizeof (data), - (char *) data, 10, &actual); + err = grub_usb_check_transfer (termdata->transfer, &actual); + + if (err == GRUB_USB_ERR_WAIT) + return -1; + + grub_memcpy (data, termdata->report, sizeof (data)); + + termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev, + termdata->endp->endp_addr, + sizeof (termdata->report), + (char *) termdata->report); + if (!termdata->transfer) + { + grub_printf ("%s failed. Stopped\n", term->name); + termdata->dead = 1; + } + if (err || actual < 1) return -1; From 2eb310be7981acf9284ae68857711da29b59ceb7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 18:24:09 +0200 Subject: [PATCH 0066/1414] Enable usb device polling again --- bus/usb/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 80d386c8d..2bd805ef2 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -338,7 +338,7 @@ grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc) GRUB_MOD_INIT(usb) { - // grub_term_poll_usb = grub_usb_poll_devices; + grub_term_poll_usb = grub_usb_poll_devices; } GRUB_MOD_FINI(usb) From 0aaf4938c785b06e611351bb927d9c1689355629 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 19:41:37 +0200 Subject: [PATCH 0067/1414] Fix incorrect toggle calculation --- bus/usb/uhci.c | 2 +- bus/usb/usbtrans.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 4792f961a..addfb41e8 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -474,7 +474,7 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev, { grub_usb_transaction_t tr = &transfer->transactions[i]; - td = grub_uhci_transaction (u, transfer->endpoint, tr->pid, + td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid, transfer->devaddr, tr->toggle, tr->size, tr->data); if (! td) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 5d6966ecc..7e6840083 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -246,7 +246,7 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; transfer->size = size - 1; - transfer->endpoint = endpoint & 15; + transfer->endpoint = endpoint; transfer->devaddr = dev->addr; transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->dir = type; From 5a2823c1913acbb22d06191b1057e7651f5936db Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 19:42:31 +0200 Subject: [PATCH 0068/1414] Give better debug message in usb_keyboard_checkkey --- term/usb_keyboard.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 1a486b53d..e9be331cf 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -258,6 +258,13 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) grub_memcpy (data, termdata->report, sizeof (data)); + grub_dprintf ("usb_keyboard", + "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" + " 0x%02x 0x%02x 0x%02x 0x%02x\n", + err, actual, + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev, termdata->endp->endp_addr, sizeof (termdata->report), @@ -276,12 +283,6 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) if (actual < 3 || !data[2]) return -1; - grub_dprintf ("usb_keyboard", - "report: 0x%02x 0x%02x 0x%02x 0x%02x" - " 0x%02x 0x%02x 0x%02x 0x%02x\n", - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7]); - /* Check if the Control or Shift key was pressed. */ if (data[0] & 0x01 || data[0] & 0x10) termdata->key = keyboard_map[data[2]] - 'a' + 1; From b481fe847a3cc1642085940f541c8fda8a5f878d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 20:54:20 +0200 Subject: [PATCH 0069/1414] really set controller_data in ohci --- bus/usb/ohci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index ba723996a..66b7c0855 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -832,6 +832,8 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, } } + transfer->controller_data = cdata; + return GRUB_USB_ERR_NONE; } From 3593f89bf3cebb02a5881ee71ac09cb61f5195da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 21:39:15 +0200 Subject: [PATCH 0070/1414] clear port status change afte polling it --- bus/usb/ohci.c | 12 ++++++++++-- bus/usb/uhci.c | 24 ++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 66b7c0855..e3cd490ac 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -1349,8 +1349,16 @@ grub_ohci_detect_dev (grub_usb_controller_t dev, int port, int *changed) grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status); - /* Connect Status Change bit - it detects change of connection */ - *changed = ((status & GRUB_OHCI_RESET_CONNECT_CHANGE) != 0); + /* Connect Status Change bit - it detects change of connection */ + if (status & GRUB_OHCI_RESET_CONNECT_CHANGE) + { + *changed = 1; + /* Reset bit Connect Status Change */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_RESET_CONNECT_CHANGE); + } + else + *changed = 0; if (! (status & 1)) return GRUB_USB_SPEED_NONE; diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index addfb41e8..472a7054e 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -39,6 +39,18 @@ typedef enum #define GRUB_UHCI_LINK_TERMINATE 1 #define GRUB_UHCI_LINK_QUEUE_HEAD 2 +enum + { + GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED = 0x0002, + GRUB_UHCI_REG_PORTSC_PORT_ENABLED = 0x0004, + GRUB_UHCI_REG_PORTSC_RESUME = 0x0040, + GRUB_UHCI_REG_PORTSC_RESET = 0x0200, + GRUB_UHCI_REG_PORTSC_SUSPEND = 0x1000, + GRUB_UHCI_REG_PORTSC_RW = GRUB_UHCI_REG_PORTSC_PORT_ENABLED + | GRUB_UHCI_REG_PORTSC_RESUME | GRUB_UHCI_REG_PORTSC_RESET + | GRUB_UHCI_REG_PORTSC_SUSPEND + }; + /* UHCI Queue Head. */ struct grub_uhci_qh @@ -693,7 +705,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, return grub_error (GRUB_ERR_IO, "UHCI Timed out"); /* Reset bit Connect Status Change */ - grub_uhci_writereg16 (u, reg, status | (1 << 1)); + grub_uhci_writereg16 (u, reg, status | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED); /* Read final port status */ status = grub_uhci_readreg16 (u, reg); @@ -725,7 +737,15 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed) grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port); /* Connect Status Change bit - it detects change of connection */ - *changed = ((status & (1 << 1)) != 0); + if (status & (1 << 1)) + { + *changed = 1; + /* Reset bit Connect Status Change */ + grub_uhci_writereg16 (u, reg, (status & GRUB_UHCI_REG_PORTSC_RW) + | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED); + } + else + *changed = 0; if (! (status & 1)) return GRUB_USB_SPEED_NONE; From f609c84a7fc5ae8b4729a39bcad8c90325c1aa85 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 21:55:24 +0200 Subject: [PATCH 0071/1414] MAke an enum out of reqtype --- include/grub/usb.h | 8 -------- include/grub/usbtrans.h | 28 +++++++++++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/grub/usb.h b/include/grub/usb.h index 768ec2f66..315ae9455 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -49,14 +49,6 @@ typedef enum GRUB_USB_SPEED_HIGH } grub_usb_speed_t; -enum - { - GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT = 0x21, - GRUB_USB_REQTYPE_VENDOR_OUT = 0x40, - GRUB_USB_REQTYPE_CLASS_INTERFACE_IN = 0xa1, - GRUB_USB_REQTYPE_VENDOR_IN = 0xc0 - }; - /* Call HOOK with each device, until HOOK returns non-zero. */ int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)); diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index a8aca3119..ae2fd1bc4 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -74,15 +74,25 @@ struct grub_usb_transfer typedef struct grub_usb_transfer *grub_usb_transfer_t; -#define GRUB_USB_REQTYPE_IN (1 << 7) -#define GRUB_USB_REQTYPE_OUT (0 << 7) -#define GRUB_USB_REQTYPE_STANDARD (0 << 5) -#define GRUB_USB_REQTYPE_CLASS (1 << 5) -#define GRUB_USB_REQTYPE_VENDOR (2 << 5) -#define GRUB_USB_REQTYPE_TARGET_DEV (0 << 0) -#define GRUB_USB_REQTYPE_TARGET_INTERF (1 << 0) -#define GRUB_USB_REQTYPE_TARGET_ENDP (2 << 0) -#define GRUB_USB_REQTYPE_TARGET_OTHER (3 << 0) + +enum + { + GRUB_USB_REQTYPE_TARGET_DEV = (0 << 0), + GRUB_USB_REQTYPE_TARGET_INTERF = (1 << 0), + GRUB_USB_REQTYPE_TARGET_ENDP = (2 << 0), + GRUB_USB_REQTYPE_TARGET_OTHER = (3 << 0), + GRUB_USB_REQTYPE_STANDARD = (0 << 5), + GRUB_USB_REQTYPE_CLASS = (1 << 5), + GRUB_USB_REQTYPE_VENDOR = (2 << 5), + GRUB_USB_REQTYPE_OUT = (0 << 7), + GRUB_USB_REQTYPE_IN = (1 << 7), + GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT = GRUB_USB_REQTYPE_TARGET_INTERF + | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_OUT, + GRUB_USB_REQTYPE_VENDOR_OUT = GRUB_USB_REQTYPE_VENDOR | GRUB_USB_REQTYPE_OUT, + GRUB_USB_REQTYPE_CLASS_INTERFACE_IN = GRUB_USB_REQTYPE_TARGET_INTERF + | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_IN, + GRUB_USB_REQTYPE_VENDOR_IN = GRUB_USB_REQTYPE_VENDOR | GRUB_USB_REQTYPE_IN + }; #define GRUB_USB_REQ_GET_STATUS 0x00 #define GRUB_USB_REQ_CLEAR_FEATURE 0x01 From ff62c48f5a8f2b35ab73eca078e5c5aed4755eb6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Aug 2010 23:09:37 +0200 Subject: [PATCH 0072/1414] Use status change pipe for hub hotplug detection --- bus/usb/usbhub.c | 112 +++++++++++++++++++++++++++++++++++----- bus/usb/usbtrans.c | 8 +++ include/grub/usb.h | 10 ++++ include/grub/usbtrans.h | 57 +++++++++++++------- term/usb_keyboard.c | 12 +++++ 5 files changed, 167 insertions(+), 32 deletions(-) diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 7f2c8d24b..111a2495e 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -177,16 +177,16 @@ grub_usb_add_hub (grub_usb_device_t dev) grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status); /* If connected, reset and enable the port. */ - if (status & GRUB_USB_HUB_STATUS_CONNECTED) + if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) { grub_usb_speed_t speed; /* Determine the device speed. */ - if (status & GRUB_USB_HUB_STATUS_LOWSPEED) + if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) speed = GRUB_USB_SPEED_LOW; else { - if (status & GRUB_USB_HUB_STATUS_HIGHSPEED) + if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED) speed = GRUB_USB_SPEED_HIGH; else speed = GRUB_USB_SPEED_FULL; @@ -231,7 +231,7 @@ grub_usb_add_hub (grub_usb_device_t dev) | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_TARGET_OTHER), GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_CONNECTED, + GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0); /* Just ignore the device if the Hub reports some error */ if (err) @@ -252,6 +252,25 @@ grub_usb_add_hub (grub_usb_device_t dev) } } + for (i = 0; i < dev->config[0].interf[0].descif->endpointcnt; + i++) + { + struct grub_usb_desc_endp *endp = NULL; + endp = &dev->config[0].interf[0].descendp[i]; + + if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp) + == GRUB_USB_EP_INTERRUPT) + { + dev->hub_endpoint = endp; + dev->hub_transfer + = grub_usb_bulk_read_background (dev, endp->endp_addr, + grub_min (endp->maxpacket, + sizeof (dev->statuschange)), + (char *) &dev->statuschange); + break; + } + } + return GRUB_ERR_NONE; } @@ -341,6 +360,9 @@ detach_device (grub_usb_device_t dev) return; if (dev->descdev.class == GRUB_USB_CLASS_HUB) { + if (dev->hub_transfer) + grub_usb_cancel_transfer (dev->hub_transfer); + for (i = 0; i < dev->nports; i++) detach_device (dev->children[i]); grub_free (dev->children); @@ -364,41 +386,105 @@ poll_nonroot_hub (grub_usb_device_t dev) grub_uint64_t timeout; grub_usb_device_t next_dev; grub_usb_device_t *attached_devices = dev->children; - + grub_uint8_t changed; + grub_size_t actual; + + if (!dev->hub_transfer) + return; + + err = grub_usb_check_transfer (dev->hub_transfer, &actual); + + if (err == GRUB_USB_ERR_WAIT) + return; + + changed = dev->statuschange; + + dev->hub_transfer + = grub_usb_bulk_read_background (dev, dev->hub_endpoint->endp_addr, + grub_min (dev->hub_endpoint->maxpacket, + sizeof (dev->statuschange)), + (char *) &dev->statuschange); + + if (err || actual == 0 || changed == 0) + return; + + grub_dprintf ("usb", "statuschanged = %02x, err = %d, actual = %d\n", + changed, err, actual); + /* Iterate over the Hub ports. */ for (i = 1; i <= dev->nports; i++) { grub_uint32_t status; + if (!(changed & (1 << i))) + continue; + /* Get the port status. */ err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_TARGET_OTHER), GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); - /* Just ignore the device if the Hub does not report the - status. */ + if (err) continue; - if (status & GRUB_USB_HUB_STATUS_C_CONNECTED) + /* FIXME: properly handle these conditions. */ + if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET) + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0); + + if (status & GRUB_USB_HUB_STATUS_C_PORT_ENABLED) + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_ENABLED, i, 0, 0); + + if (status & GRUB_USB_HUB_STATUS_C_PORT_SUSPEND) + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_SUSPEND, i, 0, 0); + + if (status & GRUB_USB_HUB_STATUS_C_PORT_OVERCURRENT) + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0); + + if (!(status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)) + continue; + + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0); + + if (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED) { detach_device (attached_devices[i-1]); attached_devices[i - 1] = NULL; } /* Connected and status of connection changed ? */ - if ((status & GRUB_USB_HUB_STATUS_CONNECTED) - && (status & GRUB_USB_HUB_STATUS_C_CONNECTED)) + if ((status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) + && (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)) { grub_usb_speed_t speed; /* Determine the device speed. */ - if (status & GRUB_USB_HUB_STATUS_LOWSPEED) + if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) speed = GRUB_USB_SPEED_LOW; else { - if (status & GRUB_USB_HUB_STATUS_HIGHSPEED) + if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED) speed = GRUB_USB_SPEED_HIGH; else speed = GRUB_USB_SPEED_FULL; @@ -442,7 +528,7 @@ poll_nonroot_hub (grub_usb_device_t dev) | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_TARGET_OTHER), GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_CONNECTED, + GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0); /* Just ignore the device if the Hub reports some error */ if (err) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 7e6840083..fe55114c7 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -392,6 +392,14 @@ grub_usb_bulk_read_background (grub_usb_device_t dev, return transfer; } +void +grub_usb_cancel_transfer (grub_usb_transfer_t transfer) +{ + grub_usb_device_t dev = transfer->dev; + dev->controller.dev->cancel_transfer (&dev->controller, transfer); + grub_errno = GRUB_ERR_NONE; +} + grub_usb_err_t grub_usb_bulk_read_extended (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data, diff --git a/include/grub/usb.h b/include/grub/usb.h index 315ae9455..f9cdb2765 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -181,11 +181,19 @@ struct grub_usb_device /* Used by libusb wrapper. Schedulded for removal. */ void *data; + /* Hub information. */ + /* Array of children for a hub. */ grub_usb_device_t *children; /* Number of hub ports. */ unsigned nports; + + grub_usb_transfer_t hub_transfer; + + grub_uint32_t statuschange; + + struct grub_usb_desc_endp *hub_endpoint; }; @@ -271,5 +279,7 @@ grub_usb_bulk_read_background (grub_usb_device_t dev, int endpoint, grub_size_t size, void *data); grub_usb_err_t grub_usb_check_transfer (grub_usb_transfer_t trans, grub_size_t *actual); +void +grub_usb_cancel_transfer (grub_usb_transfer_t trans); #endif /* GRUB_USB_H */ diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index ae2fd1bc4..9e9d75e5d 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -94,31 +94,50 @@ enum GRUB_USB_REQTYPE_VENDOR_IN = GRUB_USB_REQTYPE_VENDOR | GRUB_USB_REQTYPE_IN }; -#define GRUB_USB_REQ_GET_STATUS 0x00 -#define GRUB_USB_REQ_CLEAR_FEATURE 0x01 -#define GRUB_USB_REQ_SET_FEATURE 0x03 -#define GRUB_USB_REQ_SET_ADDRESS 0x05 -#define GRUB_USB_REQ_GET_DESCRIPTOR 0x06 -#define GRUB_USB_REQ_SET_DESCRIPTOR 0x07 -#define GRUB_USB_REQ_GET_CONFIGURATION 0x08 -#define GRUB_USB_REQ_SET_CONFIGURATION 0x09 -#define GRUB_USB_REQ_GET_INTERFACE 0x0A -#define GRUB_USB_REQ_SET_INTERFACE 0x0B -#define GRUB_USB_REQ_SYNC_FRAME 0x0C +enum + { + GRUB_USB_REQ_GET_STATUS = 0x00, + GRUB_USB_REQ_CLEAR_FEATURE = 0x01, + GRUB_USB_REQ_SET_FEATURE = 0x03, + GRUB_USB_REQ_SET_ADDRESS = 0x05, + GRUB_USB_REQ_GET_DESCRIPTOR = 0x06, + GRUB_USB_REQ_SET_DESCRIPTOR = 0x07, + GRUB_USB_REQ_GET_CONFIGURATION = 0x08, + GRUB_USB_REQ_SET_CONFIGURATION = 0x09, + GRUB_USB_REQ_GET_INTERFACE = 0x0A, + GRUB_USB_REQ_SET_INTERFACE = 0x0B, + GRUB_USB_REQ_SYNC_FRAME = 0x0C + }; #define GRUB_USB_FEATURE_ENDP_HALT 0x00 #define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 #define GRUB_USB_FEATURE_TEST_MODE 0x02 -#define GRUB_USB_HUB_FEATURE_PORT_RESET 0x04 -#define GRUB_USB_HUB_FEATURE_PORT_POWER 0x08 -#define GRUB_USB_HUB_FEATURE_C_CONNECTED 0x10 +enum + { + GRUB_USB_HUB_FEATURE_PORT_RESET = 0x04, + GRUB_USB_HUB_FEATURE_PORT_POWER = 0x08, + GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED = 0x10, + GRUB_USB_HUB_FEATURE_C_PORT_ENABLED = 0x11, + GRUB_USB_HUB_FEATURE_C_PORT_SUSPEND = 0x12, + GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT = 0x13, + GRUB_USB_HUB_FEATURE_C_PORT_RESET = 0x14 + }; -#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) -#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) -#define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10) -#define GRUB_USB_HUB_STATUS_C_CONNECTED (1 << 16) -#define GRUB_USB_HUB_STATUS_C_PORT_RESET (1 << 20) +enum + { + GRUB_USB_HUB_STATUS_PORT_CONNECTED = (1 << 0), + GRUB_USB_HUB_STATUS_PORT_ENABLED = (1 << 1), + GRUB_USB_HUB_STATUS_PORT_SUSPEND = (1 << 2), + GRUB_USB_HUB_STATUS_PORT_OVERCURRENT = (1 << 3), + GRUB_USB_HUB_STATUS_PORT_LOWSPEED = (1 << 9), + GRUB_USB_HUB_STATUS_PORT_HIGHSPEED = (1 << 10), + GRUB_USB_HUB_STATUS_C_PORT_CONNECTED = (1 << 16), + GRUB_USB_HUB_STATUS_C_PORT_ENABLED = (1 << 17), + GRUB_USB_HUB_STATUS_C_PORT_SUSPEND = (1 << 18), + GRUB_USB_HUB_STATUS_C_PORT_OVERCURRENT = (1 << 19), + GRUB_USB_HUB_STATUS_C_PORT_RESET = (1 << 20) + }; struct grub_usb_packet_setup { diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index e9be331cf..ea13418e0 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -107,6 +107,9 @@ grub_usb_keyboard_detach (grub_usb_device_t usbdev, if (data->usbdev != usbdev) continue; + if (data->transfer) + grub_usb_cancel_transfer (data->transfer); + grub_term_unregister_input (&grub_usb_keyboards[i]); grub_free ((char *) grub_usb_keyboards[i].name); grub_usb_keyboards[i].name = NULL; @@ -351,9 +354,18 @@ GRUB_MOD_FINI(usb_keyboard) for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++) if (grub_usb_keyboards[i].data) { + struct grub_usb_keyboard_data *data = grub_usb_keyboards[i].data; + + if (!data) + continue; + + if (data->transfer) + grub_usb_cancel_transfer (data->transfer); + grub_term_unregister_input (&grub_usb_keyboards[i]); grub_free ((char *) grub_usb_keyboards[i].name); grub_usb_keyboards[i].name = NULL; + grub_free (grub_usb_keyboards[i].data); grub_usb_keyboards[i].data = 0; } grub_usb_unregister_attach_hook_class (&attach_hook); From ab247a453f02a2eb0f02d35b6950d26cf6eb327b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 00:01:21 +0200 Subject: [PATCH 0073/1414] Ignore keyboard errors and track numlock status --- term/usb_keyboard.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index fc1435c05..759b3eb7d 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -99,8 +99,21 @@ static grub_uint8_t usb_to_at_map[128] = /* 0x7e */ 0x00, 0x00, }; -#define CAPS_LOCK 0x39 -#define CAPS_LOCK_LED 0x02 +enum + { + KEY_NO_KEY = 0x00, + KEY_ERR_BUFFER = 0x01, + KEY_ERR_POST = 0x02, + KEY_ERR_UNDEF = 0x03, + KEY_CAPS_LOCK = 0x39, + KEY_NUM_LOCK = 0x53, + }; + +enum + { + LED_NUM_LOCK = 0x01, + LED_CAPS_LOCK = 0x02 + }; /* Valid values for bRequest. See HID definition version 1.11 section 7.2. */ #define USB_HID_GET_REPORT 0x01 @@ -328,7 +341,9 @@ send_leds (struct grub_usb_keyboard_data *termdata) char report[1]; report[0] = 0; if (termdata->mods & GRUB_TERM_STATUS_CAPS) - report[0] |= CAPS_LOCK_LED; + report[0] |= LED_CAPS_LOCK; + if (termdata->mods & GRUB_TERM_STATUS_NUM) + report[0] |= LED_NUM_LOCK; grub_usb_control_msg (termdata->usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, USB_HID_SET_REPORT, 0x0200, termdata->interfno, sizeof (report), (char *) report); @@ -380,18 +395,29 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) termdata->status = data[0]; - if (actual < 3 || !data[2]) + if (actual < 3) return -1; - if (data[2] == CAPS_LOCK) + if (data[2] == KEY_NO_KEY || data[2] == KEY_ERR_BUFFER + || data[2] == KEY_ERR_POST || data[2] == KEY_ERR_UNDEF) + return -1; + + if (data[2] == KEY_CAPS_LOCK) { termdata->mods ^= GRUB_TERM_STATUS_CAPS; send_leds (termdata); return -1; } - if (usb_to_at_map[data[2]] == 0) - grub_printf ("Unknown key 0x%x detected\n", data[2]); + if (data[2] == KEY_NUM_LOCK) + { + termdata->mods ^= GRUB_TERM_STATUS_NUM; + send_leds (termdata); + return -1; + } + + if (data[2] > ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) + grub_printf ("Unknown key 0x%02x detected\n", data[2]); else termdata->key = grub_term_map_key (usb_to_at_map[data[2]], interpret_status (data[0]) From 7e6975d7ea371b0cb6986fb028b21d2da5c93d35 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 00:29:34 +0200 Subject: [PATCH 0074/1414] Support USB key repeat --- include/grub/term.h | 3 +++ term/usb_keyboard.c | 24 ++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index 009258f6e..9956398da 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -490,6 +490,9 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) extern void (*EXPORT_VAR (grub_term_poll_usb)) (void); +#define GRUB_TERM_REPEAT_PRE_INTERVAL 100 +#define GRUB_TERM_REPEAT_INTERVAL 50 + #endif /* ! ASM_FILE */ #endif /* ! GRUB_TERM_HEADER */ diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 759b3eb7d..c3af1694b 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -144,6 +144,8 @@ struct grub_usb_keyboard_data grub_usb_transfer_t transfer; grub_uint8_t report[8]; int dead; + int last_key; + grub_uint64_t repeat_time; }; static struct grub_term_input grub_usb_keyboards[16]; @@ -368,7 +370,16 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) err = grub_usb_check_transfer (termdata->transfer, &actual); if (err == GRUB_USB_ERR_WAIT) - return -1; + { + if (termdata->last_key != -1 + && grub_get_time_ms () > termdata->repeat_time) + { + termdata->key = termdata->last_key; + termdata->repeat_time = grub_get_time_ms () + + GRUB_TERM_REPEAT_INTERVAL; + } + return termdata->key; + } grub_memcpy (data, termdata->report, sizeof (data)); @@ -382,6 +393,7 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) termdata->dead = 1; } + termdata->last_key = -1; grub_dprintf ("usb_keyboard", "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" @@ -419,9 +431,13 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) if (data[2] > ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) grub_printf ("Unknown key 0x%02x detected\n", data[2]); else - termdata->key = grub_term_map_key (usb_to_at_map[data[2]], - interpret_status (data[0]) - | termdata->mods); + { + termdata->last_key = termdata->key + = grub_term_map_key (usb_to_at_map[data[2]], + interpret_status (data[0]) | termdata->mods); + termdata->repeat_time = grub_get_time_ms () + + GRUB_TERM_REPEAT_PRE_INTERVAL; + } grub_errno = GRUB_ERR_NONE; From 7209c54e91d35c69789e774bc29b597cdd37f93e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 00:31:43 +0200 Subject: [PATCH 0075/1414] Set last_key to -1 at init time --- term/usb_keyboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index c3af1694b..3dfe5331b 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -326,12 +326,12 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) return 0; } + data->last_key = -1; data->mods = 0; + data->dead = 0; grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]); - data->dead = 0; - return 1; } From c2994de1349f7135118853b2250fccd9a867b9bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 00:57:04 +0200 Subject: [PATCH 0076/1414] Add back accidently removed mov --- kern/i386/pc/startup.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index ef5904bb2..f78fb5baa 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1214,7 +1214,6 @@ FUNCTION(grub_console_getkey) shrl $8, %eax orl $GRUB_TERM_EXTENDED, %eax 2: - popl %ebp ret @@ -1248,12 +1247,15 @@ FUNCTION(grub_console_checkkey) DATA32 jmp pending notpending: + xorl %edx, %edx decl %edx pending: DATA32 call real_to_prot .code32 + movl %edx, %eax + popl %ebp ret From 96157c5378112658d062a1b654fd008d7edce9ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 01:01:31 +0200 Subject: [PATCH 0077/1414] Increase pre-repeat usb keyboad interval --- include/grub/term.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grub/term.h b/include/grub/term.h index 9956398da..bfe1c8f9b 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -490,7 +490,7 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) extern void (*EXPORT_VAR (grub_term_poll_usb)) (void); -#define GRUB_TERM_REPEAT_PRE_INTERVAL 100 +#define GRUB_TERM_REPEAT_PRE_INTERVAL 400 #define GRUB_TERM_REPEAT_INTERVAL 50 #endif /* ! ASM_FILE */ From 49c822bc42eb215d168ee87cc1644a8a625b173a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 02:17:14 +0200 Subject: [PATCH 0078/1414] Support numpad --- commands/keylayouts.c | 52 +++++++++++++++++++++++++++++++++++++++++-- term/at_keyboard.c | 8 +++++-- term/usb_keyboard.c | 30 ++++++++++++------------- 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index d2cb0e1e7..3442d42e7 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -106,13 +106,61 @@ map_key_core (int code, int status, int *alt_gr_consumed) return grub_current_layout->keyboard_map[code]; } +static int +map_high_key (int code, int status) +{ + int ret = 0; + if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)) + ret |= GRUB_TERM_SHIFT; + + if (code == 0xb5) + return '/'; + + if (code == 0xb7) + return '*'; + + if (code == 0x9c) + return '\n'; + + if (code < 0xc7 || code > 0xd3 || code == 0xca || code == 0xce + || code == 0xcc) + return ret; + /* GRUB keyboard codes are conveniently similar to AT codes. */ + return ret | GRUB_TERM_EXTENDED | (code & ~0x80); +} + +static int +map_num_key (int code, int state) +{ + const int map_arrows[] + = { GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE, + '-', GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, '+', + GRUB_TERM_KEY_END, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE, + GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC }; + const int map_nums[] + = { '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.'}; + + if (((state & GRUB_TERM_STATUS_NUM) + && !(state & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT))) + || ((state & GRUB_TERM_STATUS_NUM) + && !(state & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)))) + return map_nums [code - 0x47]; + else + return map_arrows [code - 0x47]; +} + unsigned grub_term_map_key (int code, int status) { - int alt_gr_consumed; + int alt_gr_consumed = 0; int key; - key = map_key_core (code, status, &alt_gr_consumed); + if (code >= 0x47 && code <= 0x53) + key = map_num_key (code, status); + else if (code & 0x80) + key = map_high_key (code, status); + else + key = map_key_core (code, status, &alt_gr_consumed); if (key == 0 || key == GRUB_TERM_SHIFT) grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 054dc9805..c98fc8255 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -110,7 +110,6 @@ grub_keyboard_isr (grub_uint8_t key) at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; break; } - extended_pending = (key == 0xe0); } /* If there is a raw key pending, return it; otherwise return -1. */ @@ -118,13 +117,18 @@ static int grub_keyboard_getkey (void) { grub_uint8_t key; + grub_uint8_t ret; if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) return -1; key = grub_inb (KEYBOARD_REG_DATA); /* FIXME */ grub_keyboard_isr (key); + ret = KEYBOARD_SCANCODE (key); + if (extended_pending) + ret |= 0x80; + extended_pending = (key == 0xe0); if (! KEYBOARD_ISMAKE (key)) return -1; - return (KEYBOARD_SCANCODE (key)); + return ret; } diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 3dfe5331b..1082e62d0 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -69,20 +69,20 @@ static grub_uint8_t usb_to_at_map[128] = /* 0x42 */ 0x43 /* F9 */, 0x44 /* F10 */, /* 0x44 */ 0x57 /* F11 */, 0x58 /* F12 */, /* 0x46 */ 0x00, 0x00, - /* 0x48 */ 0x00, 0x52 /* Insert */, - /* 0x4a */ 0x47 /* HOME */, 0x51 /* PPAGE */, - /* 0x4c */ 0x53 /* DC */, 0x4f /* END */, - /* 0x4e */ 0x49 /* NPAGE */, 0x4d /* RIGHT */, - /* 0x50 */ 0x4b /* LEFT */, 0x50 /* DOWN */, - /* 0x52 */ 0x48 /* UP */, 0x00, - /* 0x54 */ 0x00, 0x00, - /* 0x56 */ 0x00, 0x00, - /* 0x58 */ 0x00, 0x00, - /* 0x5a */ 0x00, 0x00, - /* 0x5c */ 0x00, 0x00, - /* 0x5e */ 0x00, 0x00, - /* 0x60 */ 0x00, 0x00, - /* 0x62 */ 0x00, 0x00, + /* 0x48 */ 0x00, 0xd2 /* Insert */, + /* 0x4a */ 0xc7 /* HOME */, 0xd1 /* PPAGE */, + /* 0x4c */ 0xd3 /* DC */, 0xcf /* END */, + /* 0x4e */ 0xc9 /* NPAGE */, 0xcd /* RIGHT */, + /* 0x50 */ 0xcb /* LEFT */, 0xd0 /* DOWN */, + /* 0x52 */ 0xc8 /* UP */, 0x00, + /* 0x54 */ 0xb5 /* Num / */, 0xb7 /* Num * */, + /* 0x56 */ 0x4a /* Num - */, 0x4e /* Num + */, + /* 0x58 */ 0x9c /* Num \n */, 0x4f /* Num 1 */, + /* 0x5a */ 0x50 /* Num 2 */, 0x51 /* Num 3 */, + /* 0x5c */ 0x4b /* Num 4 */, 0x4c /* Num 5 */, + /* 0x5e */ 0x4d /* Num 6 */, 0x47 /* Num 7 */, + /* 0x60 */ 0x48 /* Num 8 */, 0x49 /* Num 9 */, + /* 0x62 */ 0x52 /* Num 0 */, 0x53 /* Num . */, /* 0x64 */ 0x56 /* 102nd key. */, 0x00, /* 0x66 */ 0x00, 0x00, /* 0x68 */ 0x00, 0x00, @@ -428,7 +428,7 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) return -1; } - if (data[2] > ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) + if (data[2] >= ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) grub_printf ("Unknown key 0x%02x detected\n", data[2]); else { From c32f26bce85ec1ba5bc3a2c01ced4b2f10f00705 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 16:06:09 +0200 Subject: [PATCH 0079/1414] Make USB the main keylayout for simplicity --- commands/keylayouts.c | 194 ++++++++++++++++---------------- include/grub/at_keyboard.h | 12 -- include/grub/atkeymap.h | 111 ++++++++++++++++++ include/grub/keyboard_layouts.h | 2 +- term/at_keyboard.c | 6 +- term/usb_keyboard.c | 83 +------------- util/grub-mklayout.c | 152 ++++++++++++++++--------- 7 files changed, 321 insertions(+), 239 deletions(-) create mode 100644 include/grub/atkeymap.h diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 3442d42e7..c68919aef 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -30,39 +30,96 @@ static struct grub_keyboard_layout layout_us = { .keyboard_map = { - /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', - /* 0x08 */ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, - /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', - /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', - /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, - /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, - /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, - /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, - /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, - /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, - /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, - /* 0x4e */ '+', GRUB_TERM_KEY_END, - /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, - /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, - /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, - /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', - /* 0x60 */ '\0', '\0', '\0', '\0', - /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, - /* 0x68 */ GRUB_TERM_KEY_RIGHT + /* Keyboard errors. Handled by driver. */ + /* 0x00 */ 0, 0, 0, 0, + + /* 0x04 */ 'a', 'b', 'c', 'd', + /* 0x08 */ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + /* 0x10 */ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + /* 0x18 */ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', + /* 0x20 */ '3', '4', '5', '6', '7', '8', '9', '0', + /* 0x28 */ '\n', '\e', '\b', '\t', ' ', '-', '=', '[', + /* According to usage table 0x31 should be mapped to '/' + but testing with real keyboard shows that 0x32 is remapped to '/'. + Map 0x31 to 0. + */ + /* 0x30 */ ']', 0, '\\', ';', '\'', '`', ',', '.', + /* 0x39 is CapsLock. Handled by driver. */ + /* 0x38 */ '/', 0, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, + /* 0x3c */ GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, + /* 0x3e */ GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, + /* 0x40 */ GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, + /* 0x42 */ GRUB_TERM_KEY_F9, GRUB_TERM_KEY_F10, + /* 0x44 */ GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, + /* PrtScr and ScrollLock. Not handled yet. */ + /* 0x46 */ 0, 0, + /* 0x48 is Pause. Not handled yet. */ + /* 0x48 */ 0, GRUB_TERM_KEY_INSERT, + /* 0x4a */ GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, + /* 0x4c */ GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, + /* 0x4e */ GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, + /* 0x50 */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, + /* 0x53 is NumLock. Handled by driver. */ + /* 0x52 */ GRUB_TERM_KEY_UP, 0, + /* 0x54 */ '/', '*', + /* 0x56 */ '-', '+', + /* 0x58 */ '\n', GRUB_TERM_KEY_END, + /* 0x5a */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE, + /* 0x5c */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER, + /* 0x5e */ GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_HOME, + /* 0x60 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE, + /* 0x62 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, + /* 0x64 */ '\\' }, .keyboard_map_shift = { - '\0', '\0', '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\0', '\0', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', - [0x56] = '|' + /* Keyboard errors. Handled by driver. */ + /* 0x00 */ 0, 0, 0, 0, + + /* 0x04 */ 'A', 'B', 'C', 'D', + /* 0x08 */ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + /* 0x10 */ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + /* 0x18 */ 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', + /* 0x20 */ '#', '$', '%', '^', '&', '*', '(', ')', + /* 0x28 */ '\n' | GRUB_TERM_SHIFT, '\e' | GRUB_TERM_SHIFT, + /* 0x2a */ '\b' | GRUB_TERM_SHIFT, '\t' | GRUB_TERM_SHIFT, + /* 0x2c */ ' ' | GRUB_TERM_SHIFT, '_', '+', '{', + /* According to usage table 0x31 should be mapped to '/' + but testing with real keyboard shows that 0x32 is remapped to '/'. + Map 0x31 to 0. + */ + /* 0x30 */ '}', 0, '|', ':', '"', '~', '<', '>', + /* 0x39 is CapsLock. Handled by driver. */ + /* 0x38 */ '?', 0, + /* 0x3a */ GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT, + /* 0x3b */ GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT, + /* 0x3c */ GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT, + /* 0x3d */ GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT, + /* 0x3e */ GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT, + /* 0x3f */ GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT, + /* 0x40 */ GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT, + /* 0x41 */ GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT, + /* 0x42 */ GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT, + /* 0x43 */ GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT, + /* 0x44 */ GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT, + /* 0x45 */ GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT, + /* PrtScr and ScrollLock. Not handled yet. */ + /* 0x46 */ 0, 0, + /* 0x48 is Pause. Not handled yet. */ + /* 0x48 */ 0, GRUB_TERM_KEY_INSERT | GRUB_TERM_SHIFT, + /* 0x4a */ GRUB_TERM_KEY_HOME | GRUB_TERM_SHIFT, + /* 0x4b */ GRUB_TERM_KEY_PPAGE | GRUB_TERM_SHIFT, + /* 0x4c */ GRUB_TERM_KEY_DC | GRUB_TERM_SHIFT, + /* 0x4d */ GRUB_TERM_KEY_END | GRUB_TERM_SHIFT, + /* 0x4e */ GRUB_TERM_KEY_NPAGE | GRUB_TERM_SHIFT, + /* 0x4f */ GRUB_TERM_KEY_RIGHT | GRUB_TERM_SHIFT, + /* 0x50 */ GRUB_TERM_KEY_LEFT | GRUB_TERM_SHIFT, + /* 0x51 */ GRUB_TERM_KEY_DOWN | GRUB_TERM_SHIFT, + /* 0x53 is NumLock. Handled by driver. */ + /* 0x52 */ GRUB_TERM_KEY_UP | GRUB_TERM_SHIFT, 0, + /* 0x54 */ '/', '*', + /* 0x56 */ '-', '+', + /* 0x58 */ '\n' | GRUB_TERM_SHIFT, '1', '2', '3', '4', '5','6', '7', + /* 0x60 */ '8', '9', '0', '.', '|' } }; @@ -82,88 +139,37 @@ map_key_core (int code, int status, int *alt_gr_consumed) *alt_gr_consumed = 1; return grub_current_layout->keyboard_map_shift_l3[code]; } - else if (grub_current_layout->keyboard_map_shift[code]) - { - *alt_gr_consumed = 1; - return grub_current_layout->keyboard_map_l3[code] - | GRUB_TERM_SHIFT; - } } - else if (grub_current_layout->keyboard_map_shift[code]) + else if (grub_current_layout->keyboard_map_l3[code]) { *alt_gr_consumed = 1; return grub_current_layout->keyboard_map_l3[code]; } } if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) - { - if (grub_current_layout->keyboard_map_shift[code]) - return grub_current_layout->keyboard_map_shift[code]; - else - return grub_current_layout->keyboard_map[code] | GRUB_TERM_SHIFT; - } + return grub_current_layout->keyboard_map_shift[code]; else return grub_current_layout->keyboard_map[code]; } -static int -map_high_key (int code, int status) -{ - int ret = 0; - if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)) - ret |= GRUB_TERM_SHIFT; - - if (code == 0xb5) - return '/'; - - if (code == 0xb7) - return '*'; - - if (code == 0x9c) - return '\n'; - - if (code < 0xc7 || code > 0xd3 || code == 0xca || code == 0xce - || code == 0xcc) - return ret; - /* GRUB keyboard codes are conveniently similar to AT codes. */ - return ret | GRUB_TERM_EXTENDED | (code & ~0x80); -} - -static int -map_num_key (int code, int state) -{ - const int map_arrows[] - = { GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE, - '-', GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, '+', - GRUB_TERM_KEY_END, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE, - GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC }; - const int map_nums[] - = { '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.'}; - - if (((state & GRUB_TERM_STATUS_NUM) - && !(state & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT))) - || ((state & GRUB_TERM_STATUS_NUM) - && !(state & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)))) - return map_nums [code - 0x47]; - else - return map_arrows [code - 0x47]; -} - unsigned grub_term_map_key (int code, int status) { int alt_gr_consumed = 0; int key; - if (code >= 0x47 && code <= 0x53) - key = map_num_key (code, status); - else if (code & 0x80) - key = map_high_key (code, status); - else - key = map_key_core (code, status, &alt_gr_consumed); + if (code >= 0x59 && code <= 0x63 && (status & GRUB_TERM_STATUS_NUM)) + { + if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)) + status &= ~(GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT); + else + status |= GRUB_TERM_STATUS_RSHIFT; + } + + key = map_key_core (code, status, &alt_gr_consumed); if (key == 0 || key == GRUB_TERM_SHIFT) - grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); + grub_printf ("Unknown key 0x%x detected\n", code); if (status & GRUB_TERM_STATUS_CAPS) { diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 10421540a..350ce3bf9 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -39,16 +39,4 @@ #define KEYBOARD_ISREADY(x) ((x) & 0x01) #define KEYBOARD_SCANCODE(x) ((x) & 0x7f) -#ifdef GRUB_MACHINE_IEEE1275 -#define OLPC_UP GRUB_TERM_UP -#define OLPC_DOWN GRUB_TERM_DOWN -#define OLPC_LEFT GRUB_TERM_LEFT -#define OLPC_RIGHT GRUB_TERM_RIGHT -#else -#define OLPC_UP '\0' -#define OLPC_DOWN '\0' -#define OLPC_LEFT '\0' -#define OLPC_RIGHT '\0' -#endif - #endif diff --git a/include/grub/atkeymap.h b/include/grub/atkeymap.h new file mode 100644 index 000000000..a8b9140ff --- /dev/null +++ b/include/grub/atkeymap.h @@ -0,0 +1,111 @@ +/* + * 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_AT_KEYMAP_HEADER +#define GRUB_AT_KEYMAP_HEADER 1 + +static inline int +grub_at_map_to_usb (grub_uint8_t keycode) +{ + /* Modifier keys (ctrl, alt, shift, capslock, numlock and scrolllock + are handled by driver and hence here are mapped to 0)*/ + + static const grub_uint8_t at_to_usb_map[] = + { + /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, + /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, + /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, + /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, + /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, + /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, + /* 0x0c */ 0x2d /* - */, 0x2e /* = */, + /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, + /* 0x10 */ 0x14 /* q */, 0x1a /* w */, + /* 0x12 */ 0x08 /* e */, 0x15 /* r */, + /* 0x14 */ 0x17 /* t */, 0x1c /* y */, + /* 0x16 */ 0x18 /* u */, 0x0c /* i */, + /* 0x18 */ 0x12 /* o */, 0x13 /* p */, + /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, + /* 0x1c */ 0x28 /* Enter */, 0x00 /* Left CTRL */, + /* 0x1e */ 0x04 /* a */, 0x16 /* s */, + /* 0x20 */ 0x07 /* d */, 0x09 /* f */, + /* 0x22 */ 0x0a /* g */, 0x0b /* h */, + /* 0x24 */ 0x0d /* j */, 0x0e /* k */, + /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, + /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, + /* 0x2a */ 0x00 /* Left Shift */, 0x32 /* \ */, + /* 0x2c */ 0x1d /* z */, 0x1b /* x */, + /* 0x2e */ 0x06 /* c */, 0x19 /* v */, + /* 0x30 */ 0x05 /* b */, 0x11 /* n */, + /* 0x32 */ 0x10 /* m */, 0x36 /* , */, + /* 0x34 */ 0x37 /* . */, 0x38 /* / */, + /* 0x36 */ 0x00 /* Right Shift */, 0x55 /* Num * */, + /* 0x38 */ 0x00 /* Left ALT */, 0x2c /* Space */, + /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, + /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, + /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, + /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, + /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, + /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, + /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, + /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, + /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, + /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, + /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, + /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, + /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, + /* 0x54 */ 0x00, 0x00, + /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, + /* 0x58 */ 0x45 /* F12 */, 0x00 + }; + + static const struct + { + grub_uint8_t from, to; + } at_to_usb_extended[] = + { + /* OLPC keys. Just mapped to normal keys. */ + {0x65, 0x52 /* Up */ }, + {0x66, 0x51 /* Down */ }, + {0x67, 0x50 /* Left */ }, + {0x68, 0x4f /* Right */ }, + + {0x9c, 0x58 /* Num \n */}, + {0xb5, 0x54 /* Num / */ }, + {0xc7, 0x4a /* Home */ }, + {0xc8, 0x52 /* Up */ }, + {0xc9, 0x4e /* NPage */ }, + {0xcb, 0x50 /* Left */ }, + {0xcd, 0x4f /* Right */ }, + {0xcf, 0x4d /* End */ }, + {0xd0, 0x51 /* Down */ }, + {0xd1, 0x4b /* PPage */ }, + {0xd2, 0x49 /* Insert */}, + {0xd3, 0x4c /* DC */ }, + }; + if (keycode >= ARRAY_SIZE (at_to_usb_map)) + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (at_to_usb_extended); i++) + if (at_to_usb_extended[i].from == keycode) + return at_to_usb_extended[i].to; + return 0; + } + return at_to_usb_map[keycode]; +} +#endif diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index f1d2fb282..b562d671e 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,7 +21,7 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 6 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 7 #define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 diff --git a/term/at_keyboard.c b/term/at_keyboard.c index c98fc8255..f8595a41a 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -23,6 +23,7 @@ #include #include #include +#include static short at_keyboard_status = 0; static int extended_pending = 0; @@ -123,6 +124,8 @@ grub_keyboard_getkey (void) key = grub_inb (KEYBOARD_REG_DATA); /* FIXME */ grub_keyboard_isr (key); ret = KEYBOARD_SCANCODE (key); + if (ret == SHIFT_L || ret == SHIFT_R || ret == ALT || ret == CTRL) + return -1; if (extended_pending) ret |= 0x80; extended_pending = (key == 0xe0); @@ -175,7 +178,8 @@ grub_at_keyboard_getkey_noblock (void) keyboard_controller_led (led_status); return -1; default: - return grub_term_map_key (code, at_keyboard_status); + return grub_term_map_key (grub_at_map_to_usb (code), + at_keyboard_status); } } diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 1082e62d0..b57b171f8 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -29,76 +29,6 @@ -static grub_uint8_t usb_to_at_map[128] = -{ - /* 0x00 */ 0x00, 0x00, - /* 0x02 */ 0x00, 0x00, - /* 0x04 */ 0x1e /* a */, 0x30 /* b */, - /* 0x06 */ 0x2e /* c */, 0x20 /* d */, - /* 0x08 */ 0x12 /* e */, 0x21 /* f */, - /* 0x0a */ 0x22 /* g */, 0x23 /* h */, - /* 0x0c */ 0x17 /* i */, 0x24 /* j */, - /* 0x0e */ 0x25 /* k */, 0x26 /* l */, - /* 0x10 */ 0x32 /* m */, 0x31 /* n */, - /* 0x12 */ 0x18 /* o */, 0x19 /* p */, - /* 0x14 */ 0x10 /* q */, 0x13 /* r */, - /* 0x16 */ 0x1f /* s */, 0x14 /* t */, - /* 0x18 */ 0x16 /* u */, 0x2f /* v */, - /* 0x1a */ 0x11 /* w */, 0x2d /* x */, - /* 0x1c */ 0x15 /* y */, 0x2c /* z */, - /* 0x1e */ 0x02 /* 1 */, 0x03 /* 2 */, - /* 0x20 */ 0x04 /* 3 */, 0x05 /* 4 */, - /* 0x22 */ 0x06 /* 5 */, 0x07 /* 6 */, - /* 0x24 */ 0x08 /* 7 */, 0x09 /* 8 */, - /* 0x26 */ 0x0a /* 9 */, 0x0b /* 0 */, - /* 0x28 */ 0x1c /* Enter */, 0x01 /* Escape */, - /* 0x2a */ 0x0e /* \b */, 0x0f /* \t */, - /* 0x2c */ 0x39 /* Space */, 0x0c /* - */, - /* 0x2e */ 0x0d /* = */, 0x1a /* [ */, - /* According to usage table 0x31 should be remapped to 0x2b - but testing with real keyboard shows that 0x32 is remapped to 0x2b. */ - /* 0x30 */ 0x1b /* ] */, 0x00, - /* 0x32 */ 0x2b /* \ */, 0x27 /* ; */, - /* 0x34 */ 0x28 /* " */, 0x29 /* ` */, - /* 0x36 */ 0x33 /* , */, 0x34 /* . */, - /* 0x38 */ 0x35 /* / */, 0x00, - /* 0x3a */ 0x3b /* F1 */, 0x3c /* F2 */, - /* 0x3c */ 0x3d /* F3 */, 0x3e /* F4 */, - /* 0x3e */ 0x3f /* F5 */, 0x40 /* F6 */, - /* 0x40 */ 0x41 /* F7 */, 0x42 /* F8 */, - /* 0x42 */ 0x43 /* F9 */, 0x44 /* F10 */, - /* 0x44 */ 0x57 /* F11 */, 0x58 /* F12 */, - /* 0x46 */ 0x00, 0x00, - /* 0x48 */ 0x00, 0xd2 /* Insert */, - /* 0x4a */ 0xc7 /* HOME */, 0xd1 /* PPAGE */, - /* 0x4c */ 0xd3 /* DC */, 0xcf /* END */, - /* 0x4e */ 0xc9 /* NPAGE */, 0xcd /* RIGHT */, - /* 0x50 */ 0xcb /* LEFT */, 0xd0 /* DOWN */, - /* 0x52 */ 0xc8 /* UP */, 0x00, - /* 0x54 */ 0xb5 /* Num / */, 0xb7 /* Num * */, - /* 0x56 */ 0x4a /* Num - */, 0x4e /* Num + */, - /* 0x58 */ 0x9c /* Num \n */, 0x4f /* Num 1 */, - /* 0x5a */ 0x50 /* Num 2 */, 0x51 /* Num 3 */, - /* 0x5c */ 0x4b /* Num 4 */, 0x4c /* Num 5 */, - /* 0x5e */ 0x4d /* Num 6 */, 0x47 /* Num 7 */, - /* 0x60 */ 0x48 /* Num 8 */, 0x49 /* Num 9 */, - /* 0x62 */ 0x52 /* Num 0 */, 0x53 /* Num . */, - /* 0x64 */ 0x56 /* 102nd key. */, 0x00, - /* 0x66 */ 0x00, 0x00, - /* 0x68 */ 0x00, 0x00, - /* 0x6a */ 0x00, 0x00, - /* 0x6c */ 0x00, 0x00, - /* 0x6e */ 0x00, 0x00, - /* 0x70 */ 0x00, 0x00, - /* 0x72 */ 0x00, 0x00, - /* 0x74 */ 0x00, 0x00, - /* 0x76 */ 0x00, 0x00, - /* 0x78 */ 0x00, 0x00, - /* 0x7a */ 0x00, 0x00, - /* 0x7c */ 0x00, 0x00, - /* 0x7e */ 0x00, 0x00, -}; - enum { KEY_NO_KEY = 0x00, @@ -428,16 +358,9 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) return -1; } - if (data[2] >= ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) - grub_printf ("Unknown key 0x%02x detected\n", data[2]); - else - { - termdata->last_key = termdata->key - = grub_term_map_key (usb_to_at_map[data[2]], - interpret_status (data[0]) | termdata->mods); - termdata->repeat_time = grub_get_time_ms () - + GRUB_TERM_REPEAT_PRE_INTERVAL; - } + termdata->last_key = termdata->key + = grub_term_map_key (data[2], interpret_status (data[0]) | termdata->mods); + termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL; grub_errno = GRUB_ERR_NONE; diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 91dea87a6..3aafd8837 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -47,19 +47,47 @@ struct console_grub_equivalence grub_uint32_t grub; }; -static struct console_grub_equivalence console_grub_equivalences[] = { +static struct console_grub_equivalence console_grub_equivalences_shift[] = { + {"KP_0", '0'}, + {"KP_1", '1'}, + {"KP_2", '2'}, + {"KP_3", '3'}, + {"KP_4", '4'}, + {"KP_5", '5'}, + {"KP_6", '6'}, + {"KP_7", '7'}, + {"KP_8", '8'}, + {"KP_9", '9'}, + {"KP_Period", '.'}, +}; + +static struct console_grub_equivalence console_grub_equivalences_unshift[] = { + {"KP_0", GRUB_TERM_KEY_INSERT}, + {"KP_1", GRUB_TERM_KEY_END}, + {"KP_2", GRUB_TERM_KEY_DOWN}, + {"KP_3", GRUB_TERM_KEY_NPAGE}, + {"KP_4", GRUB_TERM_KEY_LEFT}, + {"KP_5", GRUB_TERM_KEY_CENTER}, + {"KP_6", GRUB_TERM_KEY_RIGHT}, + {"KP_7", GRUB_TERM_KEY_HOME}, + {"KP_8", GRUB_TERM_KEY_UP}, + {"KP_9", GRUB_TERM_KEY_PPAGE}, + {"KP_Period", GRUB_TERM_KEY_DC}, +}; + +static struct console_grub_equivalence console_grub_equivalences_common[] = { {"Escape", GRUB_TERM_ESC}, {"Tab", GRUB_TERM_TAB}, {"Delete", GRUB_TERM_BACKSPACE}, + {"KP_Enter", '\n'}, + {"Return", '\n'}, + {"KP_Multiply", '*'}, {"KP_Subtract", '-'}, {"KP_Add", '+'}, {"KP_Divide", '/'}, - {"KP_Enter", '\n'}, - {"Return", '\n'}, - {"F1", GRUB_TERM_KEY_F1}, {"F2", GRUB_TERM_KEY_F2}, {"F3", GRUB_TERM_KEY_F3}, @@ -116,6 +144,9 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"End", GRUB_TERM_KEY_END}, {"Right", GRUB_TERM_KEY_RIGHT}, {"Left", GRUB_TERM_KEY_LEFT}, + {"Next", GRUB_TERM_KEY_NPAGE}, + {"Prior", GRUB_TERM_KEY_PPAGE}, + {"Remove", GRUB_TERM_KEY_DC}, {"VoidSymbol", 0}, /* "Undead" keys since no dead key support in GRUB. */ @@ -132,24 +163,8 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"dead_breve", 0}, {"dead_doubleacute", 0}, - /* NumLock not supported yet. */ - {"KP_0", GRUB_TERM_KEY_INSERT}, - {"KP_1", GRUB_TERM_KEY_END}, - {"KP_2", GRUB_TERM_KEY_DOWN}, - {"KP_3", GRUB_TERM_KEY_NPAGE}, - {"KP_4", GRUB_TERM_KEY_LEFT}, - {"KP_5", 0}, - {"KP_6", GRUB_TERM_KEY_RIGHT}, - {"KP_7", GRUB_TERM_KEY_HOME}, - {"KP_8", GRUB_TERM_KEY_UP}, - {"KP_9", GRUB_TERM_KEY_PPAGE}, - {"KP_Period", GRUB_TERM_KEY_DC}, - /* Unused in GRUB. */ {"Pause", 0}, - {"Remove", 0}, - {"Next", 0}, - {"Prior", 0}, {"Scroll_Forward", 0}, {"Scroll_Backward", 0}, {"Hex_0", 0}, @@ -174,16 +189,6 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"Control_backslash", 0}, {"Compose", 0}, - /* Keys currently not remappable. */ - {"CtrlL_Lock", 0}, - {"Caps_Lock", 0}, - {"ShiftL", 0}, - {"Num_Lock", 0}, - {"Alt", 0}, - {"AltGr", 0}, - {"Control", 0}, - {"Shift", 0}, - {NULL, '\0'} }; @@ -205,24 +210,30 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); exit (status); } -void +static void add_special_keys (struct grub_keyboard_layout *layout) { - /* OLPC keys. */ - layout->keyboard_map[101] = GRUB_TERM_KEY_UP; - layout->keyboard_map[102] = GRUB_TERM_KEY_DOWN; - layout->keyboard_map[103] = GRUB_TERM_KEY_LEFT; - layout->keyboard_map[104] = GRUB_TERM_KEY_RIGHT; + (void) layout; } static unsigned -lookup (char *code) +lookup (char *code, int shift) { int i; + struct console_grub_equivalence *pr; - for (i = 0; console_grub_equivalences[i].layout != NULL; i++) - if (strcmp (code, console_grub_equivalences[i].layout) == 0) - return console_grub_equivalences[i].grub; + if (shift) + pr = console_grub_equivalences_shift; + else + pr = console_grub_equivalences_unshift; + + for (i = 0; pr[i].layout != NULL; i++) + if (strcmp (code, pr[i].layout) == 0) + return pr[i].grub; + + for (i = 0; console_grub_equivalences_common[i].layout != NULL; i++) + if (strcmp (code, console_grub_equivalences_common[i].layout) == 0) + return console_grub_equivalences_common[i].grub; fprintf (stderr, "Unknown key %s\n", code); @@ -230,7 +241,7 @@ lookup (char *code) } static unsigned int -get_grub_code (char *layout_code) +get_grub_code (char *layout_code, int shift) { unsigned int code; @@ -239,7 +250,7 @@ get_grub_code (char *layout_code) else if (strncmp (layout_code, "+U+", sizeof ("+U+") - 1) == 0) sscanf (layout_code, "+U+%x", &code); else - code = lookup (layout_code); + code = lookup (layout_code, shift); return code; } @@ -287,21 +298,60 @@ write_keymaps (FILE *in, FILE *out) { if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0) { - unsigned keycode; + unsigned keycode_at, orig; + unsigned keycode_usb; char normal[64]; char shift[64]; char normalalt[64]; char shiftalt[64]; + static grub_uint8_t e0_remap[] = { + 0x9c /* Num \n */, 0x9d /* Right CTRL */, 0xb5 /* Num / */, + 0, 0xb8 /* Right ALT */, 0, + 0xc7 /* Home */, 0xc8 /* Up */, 0xc9 /* NPage*/, 0xcb /* Left */, + 0xcd /* Right */, 0xcf /* End */, 0xd0 /* Down */, 0xd1 /* PPage */, + 0xd2 /* Insert */, 0xd3 /* Delete */ + }; - sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode, + sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode_at, normal, shift, normalalt, shiftalt); - if (keycode < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) + orig = keycode_at; + + /* Not used. */ + if (keycode_at == 0x77 /* Pause */ + /* Some obscure keys */ + || keycode_at == 0x63 || keycode_at == 0x7d || keycode_at == 0x7e) + continue; + + if (keycode_at >= 96 && keycode_at < 96 + ARRAY_SIZE (e0_remap)) + keycode_at = e0_remap[keycode_at - 96]; + + /* Not remappable. */ + if (keycode_at == 0x1d /* Left CTRL */ + || keycode_at == 0x9d /* Right CTRL */ + || keycode_at == 0x2a /* Left Shift. */ + || keycode_at == 0x36 /* Right Shift. */ + || keycode_at == 0x38 /* Left ALT. */ + || keycode_at == 0xb8 /* Right ALT. */ + || keycode_at == 0x3a /* CapsLock. */ + || keycode_at == 0x45 /* NumLock. */ + || keycode_at == 0x46 /* ScrollLock. */) + continue; + + keycode_usb = grub_at_map_to_usb (keycode_at); + if (keycode_usb == 0 + || keycode_usb >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) { - layout.keyboard_map[keycode] = get_grub_code (normal); - layout.keyboard_map_shift[keycode] = get_grub_code (shift); - layout.keyboard_map_l3[keycode] = get_grub_code (normalalt); - layout.keyboard_map_shift_l3[keycode] - = get_grub_code (shiftalt); + fprintf (stderr, "Unknown keycode 0x%02x\n", orig); + continue; + } + if (keycode_usb < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) + { + layout.keyboard_map[keycode_usb] = get_grub_code (normal, 0); + layout.keyboard_map_shift[keycode_usb] = get_grub_code (shift, 1); + layout.keyboard_map_l3[keycode_usb] + = get_grub_code (normalalt, 0); + layout.keyboard_map_shift_l3[keycode_usb] + = get_grub_code (shiftalt, 1); ok = 1; } } From 6e05e7f0f869af96ecb95b6d021b46f7e15c28c9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 17:44:03 +0200 Subject: [PATCH 0080/1414] Properly handle extended_pending --- term/at_keyboard.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 2b7dd9bee..4213b29db 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -122,13 +122,21 @@ grub_keyboard_getkey (void) if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) return -1; key = grub_inb (KEYBOARD_REG_DATA); + if (key == 0xe0) + { + extended_pending = 1; + return -1; + } /* FIXME */ grub_keyboard_isr (key); ret = KEYBOARD_SCANCODE (key); if (ret == SHIFT_L || ret == SHIFT_R || ret == ALT || ret == CTRL) - return -1; + { + extended_pending = 0; + return -1; + } if (extended_pending) ret |= 0x80; - extended_pending = (key == 0xe0); + extended_pending = 0; if (! KEYBOARD_ISMAKE (key)) return -1; return ret; From f582367ecff67c616b5631331812d87ed5e67fdf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 18:15:27 +0200 Subject: [PATCH 0081/1414] Set the leds and drain the input buffer in at_keyboard initialisation --- term/at_keyboard.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 4213b29db..06d545d74 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -223,6 +223,11 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus at_keyboard_status = 0; grub_keyboard_controller_orig = grub_keyboard_controller_read (); grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1); + keyboard_controller_led (led_status); + /* Drain input buffer. */ + while (KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + grub_inb (KEYBOARD_REG_DATA); + return GRUB_ERR_NONE; } From efc3e75f4d7006767be912b82761674f0814b08c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 18:16:16 +0200 Subject: [PATCH 0082/1414] Bump keylayouts version --- include/grub/keyboard_layouts.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index b562d671e..2f352a752 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,7 +21,7 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 7 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 8 #define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 From 5ea70ca5fabac085dc19caa490efd718882878ee Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 22:53:31 +0200 Subject: [PATCH 0083/1414] Support scancode set 2 --- include/grub/at_keyboard.h | 10 +- include/grub/atkeymap.h | 111 --------- include/grub/keyboard_layouts.h | 15 +- term/at_keyboard.c | 386 ++++++++++++++++++++++++++------ util/grub-mklayout.c | 102 ++++++--- 5 files changed, 410 insertions(+), 214 deletions(-) delete mode 100644 include/grub/atkeymap.h diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 350ce3bf9..6e0806bdb 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -19,21 +19,13 @@ #ifndef GRUB_AT_KEYBOARD_HEADER #define GRUB_AT_KEYBOARD_HEADER 1 -#define SHIFT_L 0x2a -#define SHIFT_R 0x36 -#define CTRL 0x1d -#define ALT 0x38 -#define CAPS_LOCK 0x3a -#define NUM_LOCK 0x45 -#define SCROLL_LOCK 0x46 - /* Used for sending commands to the controller. */ #define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) #define KEYBOARD_COMMAND_READ 0x20 #define KEYBOARD_COMMAND_WRITE 0x60 #define KEYBOARD_COMMAND_REBOOT 0xfe -#define KEYBOARD_SCANCODE_SET1 0x40 +#define KEYBOARD_AT_TRANSLATE 0x40 #define KEYBOARD_ISMAKE(x) !((x) & 0x80) #define KEYBOARD_ISREADY(x) ((x) & 0x01) diff --git a/include/grub/atkeymap.h b/include/grub/atkeymap.h deleted file mode 100644 index a8b9140ff..000000000 --- a/include/grub/atkeymap.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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_AT_KEYMAP_HEADER -#define GRUB_AT_KEYMAP_HEADER 1 - -static inline int -grub_at_map_to_usb (grub_uint8_t keycode) -{ - /* Modifier keys (ctrl, alt, shift, capslock, numlock and scrolllock - are handled by driver and hence here are mapped to 0)*/ - - static const grub_uint8_t at_to_usb_map[] = - { - /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, - /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, - /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, - /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, - /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, - /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, - /* 0x0c */ 0x2d /* - */, 0x2e /* = */, - /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, - /* 0x10 */ 0x14 /* q */, 0x1a /* w */, - /* 0x12 */ 0x08 /* e */, 0x15 /* r */, - /* 0x14 */ 0x17 /* t */, 0x1c /* y */, - /* 0x16 */ 0x18 /* u */, 0x0c /* i */, - /* 0x18 */ 0x12 /* o */, 0x13 /* p */, - /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, - /* 0x1c */ 0x28 /* Enter */, 0x00 /* Left CTRL */, - /* 0x1e */ 0x04 /* a */, 0x16 /* s */, - /* 0x20 */ 0x07 /* d */, 0x09 /* f */, - /* 0x22 */ 0x0a /* g */, 0x0b /* h */, - /* 0x24 */ 0x0d /* j */, 0x0e /* k */, - /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, - /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, - /* 0x2a */ 0x00 /* Left Shift */, 0x32 /* \ */, - /* 0x2c */ 0x1d /* z */, 0x1b /* x */, - /* 0x2e */ 0x06 /* c */, 0x19 /* v */, - /* 0x30 */ 0x05 /* b */, 0x11 /* n */, - /* 0x32 */ 0x10 /* m */, 0x36 /* , */, - /* 0x34 */ 0x37 /* . */, 0x38 /* / */, - /* 0x36 */ 0x00 /* Right Shift */, 0x55 /* Num * */, - /* 0x38 */ 0x00 /* Left ALT */, 0x2c /* Space */, - /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, - /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, - /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, - /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, - /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, - /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, - /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, - /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, - /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, - /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, - /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, - /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, - /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, - /* 0x54 */ 0x00, 0x00, - /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, - /* 0x58 */ 0x45 /* F12 */, 0x00 - }; - - static const struct - { - grub_uint8_t from, to; - } at_to_usb_extended[] = - { - /* OLPC keys. Just mapped to normal keys. */ - {0x65, 0x52 /* Up */ }, - {0x66, 0x51 /* Down */ }, - {0x67, 0x50 /* Left */ }, - {0x68, 0x4f /* Right */ }, - - {0x9c, 0x58 /* Num \n */}, - {0xb5, 0x54 /* Num / */ }, - {0xc7, 0x4a /* Home */ }, - {0xc8, 0x52 /* Up */ }, - {0xc9, 0x4e /* NPage */ }, - {0xcb, 0x50 /* Left */ }, - {0xcd, 0x4f /* Right */ }, - {0xcf, 0x4d /* End */ }, - {0xd0, 0x51 /* Down */ }, - {0xd1, 0x4b /* PPage */ }, - {0xd2, 0x49 /* Insert */}, - {0xd3, 0x4c /* DC */ }, - }; - if (keycode >= ARRAY_SIZE (at_to_usb_map)) - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (at_to_usb_extended); i++) - if (at_to_usb_extended[i].from == keycode) - return at_to_usb_extended[i].to; - return 0; - } - return at_to_usb_map[keycode]; -} -#endif diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index 2f352a752..dd6631a51 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -33,6 +33,19 @@ struct grub_keyboard_layout grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; }; -unsigned EXPORT_FUNC(grub_term_map_key) (int code, int status); +typedef enum grub_keyboard_key + { + GRUB_KEYBOARD_KEY_CAPS_LOCK = 0x39, + GRUB_KEYBOARD_KEY_SCROLL_LOCK = 0x47, + GRUB_KEYBOARD_KEY_NUM_LOCK = 0x53, + GRUB_KEYBOARD_KEY_LEFT_CTRL = 0xe0, + GRUB_KEYBOARD_KEY_LEFT_SHIFT = 0xe1, + GRUB_KEYBOARD_KEY_LEFT_ALT = 0xe2, + GRUB_KEYBOARD_KEY_RIGHT_CTRL = 0xe4, + GRUB_KEYBOARD_KEY_RIGHT_SHIFT = 0xe5, + GRUB_KEYBOARD_KEY_RIGHT_ALT = 0xe6, + } grub_keyboard_key_t; + +unsigned EXPORT_FUNC(grub_term_map_key) (grub_keyboard_key_t code, int status); #endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 06d545d74..00c6cef83 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -23,10 +23,10 @@ #include #include #include -#include static short at_keyboard_status = 0; -static int extended_pending = 0; +static int e0_received = 0; +static int f0_received = 0; static int pending_key = -1; static grub_uint8_t led_status; @@ -36,6 +36,145 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_CAPS (1 << 2) static grub_uint8_t grub_keyboard_controller_orig; +static grub_uint8_t grub_keyboard_orig_set; +static grub_uint8_t current_set; + +static const grub_uint8_t set1_mapping[128] = + { + /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, + /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, + /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, + /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, + /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, + /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, + /* 0x0c */ 0x2d /* - */, 0x2e /* = */, + /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, + /* 0x10 */ 0x14 /* q */, 0x1a /* w */, + /* 0x12 */ 0x08 /* e */, 0x15 /* r */, + /* 0x14 */ 0x17 /* t */, 0x1c /* y */, + /* 0x16 */ 0x18 /* u */, 0x0c /* i */, + /* 0x18 */ 0x12 /* o */, 0x13 /* p */, + /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, + /* 0x1c */ 0x28 /* Enter */, 0xe0 /* Left CTRL */, + /* 0x1e */ 0x04 /* a */, 0x16 /* s */, + /* 0x20 */ 0x07 /* d */, 0x09 /* f */, + /* 0x22 */ 0x0a /* g */, 0x0b /* h */, + /* 0x24 */ 0x0d /* j */, 0x0e /* k */, + /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, + /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, + /* 0x2a */ 0xe1 /* Left Shift */, 0x32 /* \ */, + /* 0x2c */ 0x1d /* z */, 0x1b /* x */, + /* 0x2e */ 0x06 /* c */, 0x19 /* v */, + /* 0x30 */ 0x05 /* b */, 0x11 /* n */, + /* 0x32 */ 0x10 /* m */, 0x36 /* , */, + /* 0x34 */ 0x37 /* . */, 0x38 /* / */, + /* 0x36 */ 0xe5 /* Right Shift */, 0x55 /* Num * */, + /* 0x38 */ 0xe2 /* Left ALT */, 0x2c /* Space */, + /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, + /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, + /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, + /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, + /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, + /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, + /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, + /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, + /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, + /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, + /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, + /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, + /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, + /* 0x54 */ 0x00, 0x00, + /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, + /* 0x58 */ 0x45 /* F12 */, 0x00, + /* 0x5a */ 0x00, 0x00, + /* 0x5c */ 0x00, 0x00, + /* 0x5e */ 0x00, 0x00, + /* 0x60 */ 0x00, 0x00, + /* 0x62 */ 0x00, 0x00, + /* OLPC keys. Just mapped to normal keys. */ + /* 0x64 */ 0x00, 0x52 /* Up */, + /* 0x66 */ 0x51 /* Down */, 0x50 /* Left */, + /* 0x68 */ 0x4f /* Right */ + }; + +static const struct +{ + grub_uint8_t from, to; +} set1_e0_mapping[] = + { + {0x1c, 0x58 /* Num \n */}, + {0x1d, 0xe4 /* Right CTRL */}, + {0x35, 0x54 /* Num / */ }, + {0x38, 0xe6 /* Right ALT */}, + {0x47, 0x4a /* Home */ }, + {0x48, 0x52 /* Up */ }, + {0x49, 0x4e /* NPage */ }, + {0x4b, 0x50 /* Left */ }, + {0x4d, 0x4f /* Right */ }, + {0x4f, 0x4d /* End */ }, + {0x50, 0x51 /* Down */ }, + {0x51, 0x4b /* PPage */ }, + {0x52, 0x49 /* Insert */}, + {0x53, 0x4c /* DC */ }, + }; + +static const grub_uint8_t set2_mapping[256] = + { + /* 0x00 */ 0x00, 0x42 /* F9 */, 0x00, 0x3e /* F5 */, + /* 0x04 */ 0x3c /* F3 */, 0x3a /* F1 */, 0x3b /* F2 */, 0x45 /* F12 */, + /* 0x08 */ 0x00, 0x43 /* F10 */, 0x41 /* F8 */, 0x3f /* F6 */, + /* 0x0c */ 0x3d /* F4 */, 0x2b /* \t */, 0x35 /* ` */, 0x00, + /* 0x10 */ 0x00, GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_LEFT_SHIFT, 0x00, + /* 0x14 */ GRUB_KEYBOARD_KEY_LEFT_CTRL, 0x14 /* q */, 0x1e /* 1 */, 0x00, + /* 0x18 */ 0x00, 0x00, 0x1d /* s */, 0x16 /* s */, + /* 0x1c */ 0x04 /* a */, 0x1a /* w */, 0x1f /* 2 */, 0x00, + /* 0x20 */ 0x00, 0x06 /* c */, 0x1b /* x */, 0x07 /* d */, + /* 0x24 */ 0x08 /* e */, 0x21 /* 4 */, 0x20 /* 3 */, 0x00, + /* 0x28 */ 0x00, 0x2c /* Space */, 0x19 /* v */, 0x09 /* f */, + /* 0x2c */ 0x17 /* t */, 0x15 /* r */, 0x22 /* 5 */, 0x00, + /* 0x30 */ 0x00, 0x11 /* n */, 0x05 /* b */, 0x0b /* h */, + /* 0x34 */ 0x0a /* g */, 0x1c /* y */, 0x23 /* 6 */, 0x00, + /* 0x38 */ 0x00, 0x00, 0x10 /* m */, 0x0d /* j */, + /* 0x3c */ 0x18 /* u */, 0x24 /* 7 */, 0x25 /* 8 */, 0x00, + /* 0x40 */ 0x00, 0x37 /* . */, 0x0e /* k */, 0x0c /* i */, + /* 0x44 */ 0x12 /* o */, 0x27 /* 0 */, 0x26 /* 9 */, 0x00, + /* 0x48 */ 0x00, 0x36 /* , */, 0x38 /* / */, 0x0f /* l */, + /* 0x4c */ 0x33 /* ; */, 0x13 /* p */, 0x2d /* - */, 0x00, + /* 0x50 */ 0x00, 0x00, 0x34 /* ' */, 0x00, + /* 0x54 */ 0x2f /* [ */, 0x2e /* = */, 0x00, 0x00, + /* 0x58 */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_RIGHT_SHIFT, 0x28 /* \n */,0x30 /* ] */, + /* 0x5c */ 0x00, 0x32 /* \ */, 0x00, 0x00, + /* 0x60 */ 0x00, 0x64 /* 102nd key. */, 0x00, 0x00, + /* 0x64 */ 0x00, 0x00, 0x2a /* \b */, 0x00, + /* 0x68 */ 0x00, 0x59 /* Num 1 */, 0x00, 0x5c /* Num 4 */, + /* 0x6c */ 0x5f /* Num 7 */, 0x00, 0x00, 0x00, + /* 0x70 */ 0x62 /* Num 0 */, 0x63 /* Num 0 */, 0x5a /* Num 2 */, 0x5d /* Num 5 */, + /* 0x74 */ 0x5e /* Num 6 */, 0x60 /* Num 8 */, 0x29 /* \e */, 0x53 /* NumLock */, + /* 0x78 */ 0x44 /* F11 */, 0x57 /* Num + */, 0x5b /* Num 3 */, 0x56 /* Num - */, + /* 0x7c */ 0x55 /* Num * */, 0x61 /* Num 9 */, 0x47 /* ScrollLock */, 0x00, + /* 0x80 */ 0x00, 0x00, 0x00, 0x40 /* F7 */, + }; + +static const struct +{ + grub_uint8_t from, to; +} set2_e0_mapping[] = + { + {0x11, GRUB_KEYBOARD_KEY_RIGHT_ALT}, + {0x14, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, + {0x4a, 0x54}, /* Num / */ + {0x5a, 0x58}, /* Num enter */ + {0x69, 0x4d}, /* End */ + {0x6b, 0x50}, /* Left */ + {0x6c, 0x4a}, /* Home */ + {0x70, 0x49}, /* Insert */ + {0x71, 0x4c}, /* Delete */ + {0x72, 0x51}, /* Down */ + {0x74, 0x4f}, /* Right */ + {0x75, 0x52}, /* Up */ + {0x7a, 0x4e}, /* PageDown */ + {0x7d, 0x4b}, /* PageUp */ + }; static void keyboard_controller_wait_until_ready (void) @@ -51,6 +190,55 @@ grub_keyboard_controller_write (grub_uint8_t c) grub_outb (c, KEYBOARD_REG_DATA); } +static grub_uint8_t +query_mode (int mode) +{ + keyboard_controller_wait_until_ready (); + grub_outb (0xf0, KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); + grub_inb (KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); + grub_outb (mode, KEYBOARD_REG_DATA); + + keyboard_controller_wait_until_ready (); + + return grub_inb (KEYBOARD_REG_DATA); +} + +/* QEMU translates the set even in no-translate mode. */ +static inline int +recover_mode (grub_uint8_t report) +{ + if (report == 0x43 || report == 1) + return 1; + if (report == 0x41 || report == 2) + return 2; + if (report == 0x3f || report == 3) + return 3; + return -1; +} + +static void +set_scancodes (void) +{ + grub_keyboard_controller_write (grub_keyboard_controller_orig + & ~KEYBOARD_AT_TRANSLATE); + grub_keyboard_orig_set = recover_mode (query_mode (0)); + + query_mode (2); + current_set = query_mode (0); + current_set = recover_mode (current_set); + if (current_set == 2) + return; + + query_mode (1); + current_set = query_mode (0); + current_set = recover_mode (current_set); + if (current_set == 1) + return; + grub_printf ("No supported scancode set found\n"); +} + static grub_uint8_t grub_keyboard_controller_read (void) { @@ -68,48 +256,126 @@ keyboard_controller_led (grub_uint8_t leds) grub_outb (leds & 0x7, KEYBOARD_REG_DATA); } +static int +fetch_key (int *is_break) +{ + int was_ext = 0; + grub_uint8_t at_key; + int ret = 0; + + if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + return -1; + at_key = grub_inb (KEYBOARD_REG_DATA); + if (at_key == 0xe0) + { + e0_received = 1; + return -1; + } + + was_ext = e0_received; + e0_received = 0; + + switch (current_set) + { + case 1: + *is_break = !!(at_key & 0x80); + if (!was_ext) + ret = set1_mapping[at_key & 0x7f]; + else + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) + if (set1_e0_mapping[i].from == (at_key & 0x80)) + { + ret = set1_e0_mapping[i].to; + break; + } + } + break; + case 2: + if (at_key == 0xf0) + { + f0_received = 1; + return -1; + } + *is_break = f0_received; + f0_received = 0; + if (!was_ext) + ret = set2_mapping[at_key]; + else + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) + if (set1_e0_mapping[i].from == (at_key & 0x80)) + { + ret = set1_e0_mapping[i].to; + break; + } + } + break; + default: + return -1; + } + if (!ret) + { + grub_printf ("Unknown key 0x%02x from set %d\n\n", at_key, current_set); + return -1; + } + return ret; +} + /* FIXME: This should become an interrupt service routine. For now it's just used to catch events from control keys. */ -static void -grub_keyboard_isr (grub_uint8_t key) +static int +grub_keyboard_isr (grub_keyboard_key_t key, int is_break) { - if (KEYBOARD_ISMAKE (key)) - switch (KEYBOARD_SCANCODE (key)) + if (!is_break) + switch (key) { - case SHIFT_L: - at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT; - break; - case SHIFT_R: - at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT; - break; - case CTRL: - at_keyboard_status |= GRUB_TERM_STATUS_LCTRL; - break; - case ALT: - if (extended_pending) - at_keyboard_status |= GRUB_TERM_STATUS_RALT; - else - at_keyboard_status |= GRUB_TERM_STATUS_LALT; - break; + case GRUB_KEYBOARD_KEY_LEFT_SHIFT: + at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: + at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_CTRL: + at_keyboard_status |= GRUB_TERM_STATUS_LCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_CTRL: + at_keyboard_status |= GRUB_TERM_STATUS_RCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_ALT: + at_keyboard_status |= GRUB_TERM_STATUS_RALT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_ALT: + at_keyboard_status |= GRUB_TERM_STATUS_LALT; + return 1; + default: + return 0; } else switch (KEYBOARD_SCANCODE (key)) { - case SHIFT_L: - at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; - break; - case SHIFT_R: - at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT; - break; - case CTRL: - at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL; - break; - case ALT: - if (extended_pending) - at_keyboard_status &= ~GRUB_TERM_STATUS_RALT; - else - at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; - break; + case GRUB_KEYBOARD_KEY_LEFT_SHIFT: + at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: + at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_CTRL: + at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_CTRL: + at_keyboard_status &= ~GRUB_TERM_STATUS_RCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_ALT: + at_keyboard_status &= ~GRUB_TERM_STATUS_RALT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_ALT: + at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; + return 1; + default: + return 0; } } @@ -117,31 +383,19 @@ grub_keyboard_isr (grub_uint8_t key) static int grub_keyboard_getkey (void) { - grub_uint8_t key; - grub_uint8_t ret; - if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - return -1; - key = grub_inb (KEYBOARD_REG_DATA); - if (key == 0xe0) - { - extended_pending = 1; - return -1; - } - /* FIXME */ grub_keyboard_isr (key); - ret = KEYBOARD_SCANCODE (key); - if (ret == SHIFT_L || ret == SHIFT_R || ret == ALT || ret == CTRL) - { - extended_pending = 0; - return -1; - } - if (extended_pending) - ret |= 0x80; - extended_pending = 0; - if (! KEYBOARD_ISMAKE (key)) - return -1; - return ret; -} + int key; + int is_break; + key = fetch_key (&is_break); + if (key == -1) + return -1; + + if (grub_keyboard_isr (key, is_break)) + return -1; + if (is_break) + return -1; + return key; +} /* If there is a character pending, return it; otherwise return -1. */ static int @@ -156,7 +410,7 @@ grub_at_keyboard_getkey_noblock (void) #endif switch (code) { - case CAPS_LOCK: + case GRUB_KEYBOARD_KEY_CAPS_LOCK: at_keyboard_status ^= GRUB_TERM_STATUS_CAPS; led_status ^= KEYBOARD_LED_CAPS; keyboard_controller_led (led_status); @@ -165,7 +419,7 @@ grub_at_keyboard_getkey_noblock (void) grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)); #endif return -1; - case NUM_LOCK: + case GRUB_KEYBOARD_KEY_NUM_LOCK: at_keyboard_status ^= GRUB_TERM_STATUS_NUM; led_status ^= KEYBOARD_LED_NUM; keyboard_controller_led (led_status); @@ -174,14 +428,13 @@ grub_at_keyboard_getkey_noblock (void) grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK)); #endif return -1; - case SCROLL_LOCK: + case GRUB_KEYBOARD_KEY_SCROLL_LOCK: at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL; led_status ^= KEYBOARD_LED_SCROLL; keyboard_controller_led (led_status); return -1; default: - return grub_term_map_key (grub_at_map_to_usb (code), - at_keyboard_status); + return grub_term_map_key (code, at_keyboard_status); } } @@ -222,7 +475,7 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus pending_key = -1; at_keyboard_status = 0; grub_keyboard_controller_orig = grub_keyboard_controller_read (); - grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1); + set_scancodes (); keyboard_controller_led (led_status); /* Drain input buffer. */ while (KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) @@ -234,6 +487,7 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus static grub_err_t grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) { + query_mode (grub_keyboard_orig_set); grub_keyboard_controller_write (grub_keyboard_controller_orig); return GRUB_ERR_NONE; } diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 3aafd8837..fc8ffb67a 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -192,6 +191,65 @@ static struct console_grub_equivalence console_grub_equivalences_common[] = { {NULL, '\0'} }; +static grub_uint8_t linux_to_usb_map[128] = { + /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, + /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, + /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, + /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, + /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, + /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, + /* 0x0c */ 0x2d /* - */, 0x2e /* = */, + /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, + /* 0x10 */ 0x14 /* q */, 0x1a /* w */, + /* 0x12 */ 0x08 /* e */, 0x15 /* r */, + /* 0x14 */ 0x17 /* t */, 0x1c /* y */, + /* 0x16 */ 0x18 /* u */, 0x0c /* i */, + /* 0x18 */ 0x12 /* o */, 0x13 /* p */, + /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, + /* 0x1c */ 0x28 /* Enter */, 0x00 /* Left CTRL */, + /* 0x1e */ 0x04 /* a */, 0x16 /* s */, + /* 0x20 */ 0x07 /* d */, 0x09 /* f */, + /* 0x22 */ 0x0a /* g */, 0x0b /* h */, + /* 0x24 */ 0x0d /* j */, 0x0e /* k */, + /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, + /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, + /* 0x2a */ 0x00 /* Left Shift */, 0x32 /* \ */, + /* 0x2c */ 0x1d /* z */, 0x1b /* x */, + /* 0x2e */ 0x06 /* c */, 0x19 /* v */, + /* 0x30 */ 0x05 /* b */, 0x11 /* n */, + /* 0x32 */ 0x10 /* m */, 0x36 /* , */, + /* 0x34 */ 0x37 /* . */, 0x38 /* / */, + /* 0x36 */ 0x00 /* Right Shift */, 0x55 /* Num * */, + /* 0x38 */ 0x00 /* Left ALT */, 0x2c /* Space */, + /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, + /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, + /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, + /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, + /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, + /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, + /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, + /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, + /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, + /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, + /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, + /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, + /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, + /* 0x54 */ 0x00, 0x00, + /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, + /* 0x58 */ 0x45 /* F12 */, 0x00, + /* 0x5a */ 0x00, 0x00, + /* 0x5c */ 0x00, 0x00, + /* 0x5e */ 0x00, 0x00, + /* 0x60 */ 0x58 /* Num \n */, 0x00 /* Right CTRL */, + /* 0x62 */ 0x54 /* Num / */, 0x00, + /* 0x64 */ 0x00 /* Right ALT */, 0x00, + /* 0x66 */ 0x4a /* Home */, 0x52 /* Up */, + /* 0x68 */ 0x4e /* NPage */, 0x50 /* Left */, + /* 0x6a */ 0x4f /* Right */, 0x4d /* End */, + /* 0x6c */ 0x51 /* Down */, 0x4b /* PPage */, + /* 0x6e */ 0x49 /* Insert */, 0x4c /* DC */ +}; + static void usage (int status) { @@ -298,50 +356,40 @@ write_keymaps (FILE *in, FILE *out) { if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0) { - unsigned keycode_at, orig; + unsigned keycode_linux; unsigned keycode_usb; char normal[64]; char shift[64]; char normalalt[64]; char shiftalt[64]; - static grub_uint8_t e0_remap[] = { - 0x9c /* Num \n */, 0x9d /* Right CTRL */, 0xb5 /* Num / */, - 0, 0xb8 /* Right ALT */, 0, - 0xc7 /* Home */, 0xc8 /* Up */, 0xc9 /* NPage*/, 0xcb /* Left */, - 0xcd /* Right */, 0xcf /* End */, 0xd0 /* Down */, 0xd1 /* PPage */, - 0xd2 /* Insert */, 0xd3 /* Delete */ - }; - sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode_at, + sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode_linux, normal, shift, normalalt, shiftalt); - orig = keycode_at; /* Not used. */ - if (keycode_at == 0x77 /* Pause */ + if (keycode_linux == 0x77 /* Pause */ /* Some obscure keys */ - || keycode_at == 0x63 || keycode_at == 0x7d || keycode_at == 0x7e) + || keycode_linux == 0x63 || keycode_linux == 0x7d + || keycode_linux == 0x7e) continue; - if (keycode_at >= 96 && keycode_at < 96 + ARRAY_SIZE (e0_remap)) - keycode_at = e0_remap[keycode_at - 96]; - /* Not remappable. */ - if (keycode_at == 0x1d /* Left CTRL */ - || keycode_at == 0x9d /* Right CTRL */ - || keycode_at == 0x2a /* Left Shift. */ - || keycode_at == 0x36 /* Right Shift. */ - || keycode_at == 0x38 /* Left ALT. */ - || keycode_at == 0xb8 /* Right ALT. */ - || keycode_at == 0x3a /* CapsLock. */ - || keycode_at == 0x45 /* NumLock. */ - || keycode_at == 0x46 /* ScrollLock. */) + if (keycode_linux == 0x1d /* Left CTRL */ + || keycode_linux == 0x9d /* Right CTRL */ + || keycode_linux == 0x2a /* Left Shift. */ + || keycode_linux == 0x36 /* Right Shift. */ + || keycode_linux == 0x38 /* Left ALT. */ + || keycode_linux == 0xb8 /* Right ALT. */ + || keycode_linux == 0x3a /* CapsLock. */ + || keycode_linux == 0x45 /* NumLock. */ + || keycode_linux == 0x46 /* ScrollLock. */) continue; - keycode_usb = grub_at_map_to_usb (keycode_at); + keycode_usb = linux_to_usb_map[keycode_linux]; if (keycode_usb == 0 || keycode_usb >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) { - fprintf (stderr, "Unknown keycode 0x%02x\n", orig); + fprintf (stderr, "Unknown keycode 0x%02x\n", keycode_linux); continue; } if (keycode_usb < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) From 09206dc3d09f29c8dcb2af30b1001ba56e0b9bf4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Aug 2010 23:56:41 +0200 Subject: [PATCH 0084/1414] Macroify key constants --- include/grub/keyboard_layouts.h | 99 +++++++++++- term/at_keyboard.c | 257 ++++++++++++++++++-------------- util/grub-mklayout.c | 112 +++++++------- 3 files changed, 296 insertions(+), 172 deletions(-) diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index dd6631a51..24d4880af 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -35,15 +35,106 @@ struct grub_keyboard_layout typedef enum grub_keyboard_key { + GRUB_KEYBOARD_KEY_A = 0x04, + GRUB_KEYBOARD_KEY_B = 0x05, + GRUB_KEYBOARD_KEY_C = 0x06, + GRUB_KEYBOARD_KEY_D = 0x07, + GRUB_KEYBOARD_KEY_E = 0x08, + GRUB_KEYBOARD_KEY_F = 0x09, + GRUB_KEYBOARD_KEY_G = 0x0a, + GRUB_KEYBOARD_KEY_H = 0x0b, + GRUB_KEYBOARD_KEY_I = 0x0c, + GRUB_KEYBOARD_KEY_J = 0x0d, + GRUB_KEYBOARD_KEY_K = 0x0e, + GRUB_KEYBOARD_KEY_L = 0x0f, + GRUB_KEYBOARD_KEY_M = 0x10, + GRUB_KEYBOARD_KEY_N = 0x11, + GRUB_KEYBOARD_KEY_O = 0x12, + GRUB_KEYBOARD_KEY_P = 0x13, + GRUB_KEYBOARD_KEY_Q = 0x14, + GRUB_KEYBOARD_KEY_R = 0x15, + GRUB_KEYBOARD_KEY_S = 0x16, + GRUB_KEYBOARD_KEY_T = 0x17, + GRUB_KEYBOARD_KEY_U = 0x18, + GRUB_KEYBOARD_KEY_V = 0x19, + GRUB_KEYBOARD_KEY_W = 0x1a, + GRUB_KEYBOARD_KEY_X = 0x1b, + GRUB_KEYBOARD_KEY_Y = 0x1c, + GRUB_KEYBOARD_KEY_Z = 0x1d, + GRUB_KEYBOARD_KEY_1 = 0x1e, + GRUB_KEYBOARD_KEY_2 = 0x1f, + GRUB_KEYBOARD_KEY_3 = 0x20, + GRUB_KEYBOARD_KEY_4 = 0x21, + GRUB_KEYBOARD_KEY_5 = 0x22, + GRUB_KEYBOARD_KEY_6 = 0x23, + GRUB_KEYBOARD_KEY_7 = 0x24, + GRUB_KEYBOARD_KEY_8 = 0x25, + GRUB_KEYBOARD_KEY_9 = 0x26, + GRUB_KEYBOARD_KEY_0 = 0x27, + GRUB_KEYBOARD_KEY_ENTER = 0x28, + GRUB_KEYBOARD_KEY_ESCAPE = 0x29, + GRUB_KEYBOARD_KEY_BACKSPACE = 0x2a, + GRUB_KEYBOARD_KEY_TAB = 0x2b, + GRUB_KEYBOARD_KEY_SPACE = 0x2c, + GRUB_KEYBOARD_KEY_DASH = 0x2d, + GRUB_KEYBOARD_KEY_EQUAL = 0x2e, + GRUB_KEYBOARD_KEY_LBRACKET = 0x2f, + GRUB_KEYBOARD_KEY_RBRACKET = 0x30, + GRUB_KEYBOARD_KEY_BACKSLASH = 0x32, + GRUB_KEYBOARD_KEY_SEMICOLON = 0x33, + GRUB_KEYBOARD_KEY_DQUOTE = 0x34, + GRUB_KEYBOARD_KEY_RQUOTE = 0x35, + GRUB_KEYBOARD_KEY_COMMA = 0x36, + GRUB_KEYBOARD_KEY_DOT = 0x37, + GRUB_KEYBOARD_KEY_SLASH = 0x38, GRUB_KEYBOARD_KEY_CAPS_LOCK = 0x39, + GRUB_KEYBOARD_KEY_F1 = 0x3a, + GRUB_KEYBOARD_KEY_F2 = 0x3b, + GRUB_KEYBOARD_KEY_F3 = 0x3c, + GRUB_KEYBOARD_KEY_F4 = 0x3d, + GRUB_KEYBOARD_KEY_F5 = 0x3e, + GRUB_KEYBOARD_KEY_F6 = 0x3f, + GRUB_KEYBOARD_KEY_F7 = 0x40, + GRUB_KEYBOARD_KEY_F8 = 0x41, + GRUB_KEYBOARD_KEY_F9 = 0x42, + GRUB_KEYBOARD_KEY_F10 = 0x43, + GRUB_KEYBOARD_KEY_F11 = 0x44, + GRUB_KEYBOARD_KEY_F12 = 0x45, GRUB_KEYBOARD_KEY_SCROLL_LOCK = 0x47, - GRUB_KEYBOARD_KEY_NUM_LOCK = 0x53, - GRUB_KEYBOARD_KEY_LEFT_CTRL = 0xe0, + GRUB_KEYBOARD_KEY_INSERT = 0x49, + GRUB_KEYBOARD_KEY_HOME = 0x4a, + GRUB_KEYBOARD_KEY_PPAGE = 0x4b, + GRUB_KEYBOARD_KEY_DELETE = 0x4c, + GRUB_KEYBOARD_KEY_END = 0x4d, + GRUB_KEYBOARD_KEY_NPAGE = 0x4e, + GRUB_KEYBOARD_KEY_RIGHT = 0x4f, + GRUB_KEYBOARD_KEY_LEFT = 0x50, + GRUB_KEYBOARD_KEY_DOWN = 0x51, + GRUB_KEYBOARD_KEY_UP = 0x52, + GRUB_KEYBOARD_KEY_NUM_LOCK = 0x53, + GRUB_KEYBOARD_KEY_NUMSLASH = 0x54, + GRUB_KEYBOARD_KEY_NUMMUL = 0x55, + GRUB_KEYBOARD_KEY_NUMMINUS = 0x56, + GRUB_KEYBOARD_KEY_NUMPLUS = 0x57, + GRUB_KEYBOARD_KEY_NUMENTER = 0x58, + GRUB_KEYBOARD_KEY_NUM1 = 0x59, + GRUB_KEYBOARD_KEY_NUM2 = 0x5a, + GRUB_KEYBOARD_KEY_NUM3 = 0x5b, + GRUB_KEYBOARD_KEY_NUM4 = 0x5c, + GRUB_KEYBOARD_KEY_NUM5 = 0x5d, + GRUB_KEYBOARD_KEY_NUM6 = 0x5e, + GRUB_KEYBOARD_KEY_NUM7 = 0x5f, + GRUB_KEYBOARD_KEY_NUM8 = 0x60, + GRUB_KEYBOARD_KEY_NUM9 = 0x61, + GRUB_KEYBOARD_KEY_NUM0 = 0x62, + GRUB_KEYBOARD_KEY_NUMDOT = 0x63, + GRUB_KEYBOARD_KEY_102ND = 0x64, + GRUB_KEYBOARD_KEY_LEFT_CTRL = 0xe0, GRUB_KEYBOARD_KEY_LEFT_SHIFT = 0xe1, - GRUB_KEYBOARD_KEY_LEFT_ALT = 0xe2, + GRUB_KEYBOARD_KEY_LEFT_ALT = 0xe2, GRUB_KEYBOARD_KEY_RIGHT_CTRL = 0xe4, GRUB_KEYBOARD_KEY_RIGHT_SHIFT = 0xe5, - GRUB_KEYBOARD_KEY_RIGHT_ALT = 0xe6, + GRUB_KEYBOARD_KEY_RIGHT_ALT = 0xe6, } grub_keyboard_key_t; unsigned EXPORT_FUNC(grub_term_map_key) (grub_keyboard_key_t code, int status); diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 00c6cef83..c515a3971 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -41,60 +41,60 @@ static grub_uint8_t current_set; static const grub_uint8_t set1_mapping[128] = { - /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, - /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, - /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, - /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, - /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, - /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, - /* 0x0c */ 0x2d /* - */, 0x2e /* = */, - /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, - /* 0x10 */ 0x14 /* q */, 0x1a /* w */, - /* 0x12 */ 0x08 /* e */, 0x15 /* r */, - /* 0x14 */ 0x17 /* t */, 0x1c /* y */, - /* 0x16 */ 0x18 /* u */, 0x0c /* i */, - /* 0x18 */ 0x12 /* o */, 0x13 /* p */, - /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, - /* 0x1c */ 0x28 /* Enter */, 0xe0 /* Left CTRL */, - /* 0x1e */ 0x04 /* a */, 0x16 /* s */, - /* 0x20 */ 0x07 /* d */, 0x09 /* f */, - /* 0x22 */ 0x0a /* g */, 0x0b /* h */, - /* 0x24 */ 0x0d /* j */, 0x0e /* k */, - /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, - /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, - /* 0x2a */ 0xe1 /* Left Shift */, 0x32 /* \ */, - /* 0x2c */ 0x1d /* z */, 0x1b /* x */, - /* 0x2e */ 0x06 /* c */, 0x19 /* v */, - /* 0x30 */ 0x05 /* b */, 0x11 /* n */, - /* 0x32 */ 0x10 /* m */, 0x36 /* , */, - /* 0x34 */ 0x37 /* . */, 0x38 /* / */, - /* 0x36 */ 0xe5 /* Right Shift */, 0x55 /* Num * */, - /* 0x38 */ 0xe2 /* Left ALT */, 0x2c /* Space */, - /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, - /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, - /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, - /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, - /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, - /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, - /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, - /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, - /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, - /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, - /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, - /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, - /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, - /* 0x54 */ 0x00, 0x00, - /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, - /* 0x58 */ 0x45 /* F12 */, 0x00, - /* 0x5a */ 0x00, 0x00, - /* 0x5c */ 0x00, 0x00, - /* 0x5e */ 0x00, 0x00, - /* 0x60 */ 0x00, 0x00, - /* 0x62 */ 0x00, 0x00, + /* 0x00 */ 0 /* Unused */, GRUB_KEYBOARD_KEY_ESCAPE, + /* 0x02 */ GRUB_KEYBOARD_KEY_1, GRUB_KEYBOARD_KEY_2, + /* 0x04 */ GRUB_KEYBOARD_KEY_3, GRUB_KEYBOARD_KEY_4, + /* 0x06 */ GRUB_KEYBOARD_KEY_5, GRUB_KEYBOARD_KEY_6, + /* 0x08 */ GRUB_KEYBOARD_KEY_7, GRUB_KEYBOARD_KEY_8, + /* 0x0a */ GRUB_KEYBOARD_KEY_9, GRUB_KEYBOARD_KEY_0, + /* 0x0c */ GRUB_KEYBOARD_KEY_DASH, GRUB_KEYBOARD_KEY_EQUAL, + /* 0x0e */ GRUB_KEYBOARD_KEY_BACKSPACE, GRUB_KEYBOARD_KEY_TAB, + /* 0x10 */ GRUB_KEYBOARD_KEY_Q, GRUB_KEYBOARD_KEY_W, + /* 0x12 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_R, + /* 0x14 */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_Y, + /* 0x16 */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_I, + /* 0x18 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_P, + /* 0x1a */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_RBRACKET, + /* 0x1c */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_LEFT_CTRL, + /* 0x1e */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_S, + /* 0x20 */ GRUB_KEYBOARD_KEY_D, GRUB_KEYBOARD_KEY_F, + /* 0x22 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_H, + /* 0x24 */ GRUB_KEYBOARD_KEY_J, GRUB_KEYBOARD_KEY_K, + /* 0x26 */ GRUB_KEYBOARD_KEY_L, GRUB_KEYBOARD_KEY_SEMICOLON, + /* 0x28 */ GRUB_KEYBOARD_KEY_DQUOTE, GRUB_KEYBOARD_KEY_RQUOTE, + /* 0x2a */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, GRUB_KEYBOARD_KEY_BACKSLASH, + /* 0x2c */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_X, + /* 0x2e */ GRUB_KEYBOARD_KEY_C, GRUB_KEYBOARD_KEY_V, + /* 0x30 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_N, + /* 0x32 */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_COMMA, + /* 0x34 */ GRUB_KEYBOARD_KEY_DOT, GRUB_KEYBOARD_KEY_SLASH, + /* 0x36 */ GRUB_KEYBOARD_KEY_RIGHT_SHIFT, GRUB_KEYBOARD_KEY_NUMMUL, + /* 0x38 */ GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_SPACE, + /* 0x3a */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_F1, + /* 0x3c */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F3, + /* 0x3e */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_F5, + /* 0x40 */ GRUB_KEYBOARD_KEY_F6, GRUB_KEYBOARD_KEY_F7, + /* 0x42 */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F9, + /* 0x44 */ GRUB_KEYBOARD_KEY_F10, GRUB_KEYBOARD_KEY_NUM_LOCK, + /* 0x46 */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, GRUB_KEYBOARD_KEY_NUM7, + /* 0x48 */ GRUB_KEYBOARD_KEY_NUM8, GRUB_KEYBOARD_KEY_NUM9, + /* 0x4a */ GRUB_KEYBOARD_KEY_NUMMINUS, GRUB_KEYBOARD_KEY_NUM4, + /* 0x4c */ GRUB_KEYBOARD_KEY_NUM5, GRUB_KEYBOARD_KEY_NUM6, + /* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS, GRUB_KEYBOARD_KEY_NUM1, + /* 0x50 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM3, + /* 0x52 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUMDOT, + /* 0x54 */ 0, 0, + /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, + /* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0, + /* 0x5a */ 0, 0, + /* 0x5c */ 0, 0, + /* 0x5e */ 0, 0, + /* 0x60 */ 0, 0, + /* 0x62 */ 0, 0, /* OLPC keys. Just mapped to normal keys. */ - /* 0x64 */ 0x00, 0x52 /* Up */, - /* 0x66 */ 0x51 /* Down */, 0x50 /* Left */, - /* 0x68 */ 0x4f /* Right */ + /* 0x64 */ 0, GRUB_KEYBOARD_KEY_UP, + /* 0x66 */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_LEFT, + /* 0x68 */ GRUB_KEYBOARD_KEY_RIGHT }; static const struct @@ -102,57 +102,90 @@ static const struct grub_uint8_t from, to; } set1_e0_mapping[] = { - {0x1c, 0x58 /* Num \n */}, - {0x1d, 0xe4 /* Right CTRL */}, - {0x35, 0x54 /* Num / */ }, - {0x38, 0xe6 /* Right ALT */}, - {0x47, 0x4a /* Home */ }, - {0x48, 0x52 /* Up */ }, - {0x49, 0x4e /* NPage */ }, - {0x4b, 0x50 /* Left */ }, - {0x4d, 0x4f /* Right */ }, - {0x4f, 0x4d /* End */ }, - {0x50, 0x51 /* Down */ }, - {0x51, 0x4b /* PPage */ }, - {0x52, 0x49 /* Insert */}, - {0x53, 0x4c /* DC */ }, + {0x1c, GRUB_KEYBOARD_KEY_NUMENTER}, + {0x1d, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, + {0x35, GRUB_KEYBOARD_KEY_NUMSLASH }, + {0x38, GRUB_KEYBOARD_KEY_RIGHT_ALT}, + {0x47, GRUB_KEYBOARD_KEY_HOME}, + {0x48, GRUB_KEYBOARD_KEY_UP}, + {0x49, GRUB_KEYBOARD_KEY_NPAGE}, + {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}, + {0x52, GRUB_KEYBOARD_KEY_INSERT}, + {0x53, GRUB_KEYBOARD_KEY_DELETE}, }; static const grub_uint8_t set2_mapping[256] = { - /* 0x00 */ 0x00, 0x42 /* F9 */, 0x00, 0x3e /* F5 */, - /* 0x04 */ 0x3c /* F3 */, 0x3a /* F1 */, 0x3b /* F2 */, 0x45 /* F12 */, - /* 0x08 */ 0x00, 0x43 /* F10 */, 0x41 /* F8 */, 0x3f /* F6 */, - /* 0x0c */ 0x3d /* F4 */, 0x2b /* \t */, 0x35 /* ` */, 0x00, - /* 0x10 */ 0x00, GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_LEFT_SHIFT, 0x00, - /* 0x14 */ GRUB_KEYBOARD_KEY_LEFT_CTRL, 0x14 /* q */, 0x1e /* 1 */, 0x00, - /* 0x18 */ 0x00, 0x00, 0x1d /* s */, 0x16 /* s */, - /* 0x1c */ 0x04 /* a */, 0x1a /* w */, 0x1f /* 2 */, 0x00, - /* 0x20 */ 0x00, 0x06 /* c */, 0x1b /* x */, 0x07 /* d */, - /* 0x24 */ 0x08 /* e */, 0x21 /* 4 */, 0x20 /* 3 */, 0x00, - /* 0x28 */ 0x00, 0x2c /* Space */, 0x19 /* v */, 0x09 /* f */, - /* 0x2c */ 0x17 /* t */, 0x15 /* r */, 0x22 /* 5 */, 0x00, - /* 0x30 */ 0x00, 0x11 /* n */, 0x05 /* b */, 0x0b /* h */, - /* 0x34 */ 0x0a /* g */, 0x1c /* y */, 0x23 /* 6 */, 0x00, - /* 0x38 */ 0x00, 0x00, 0x10 /* m */, 0x0d /* j */, - /* 0x3c */ 0x18 /* u */, 0x24 /* 7 */, 0x25 /* 8 */, 0x00, - /* 0x40 */ 0x00, 0x37 /* . */, 0x0e /* k */, 0x0c /* i */, - /* 0x44 */ 0x12 /* o */, 0x27 /* 0 */, 0x26 /* 9 */, 0x00, - /* 0x48 */ 0x00, 0x36 /* , */, 0x38 /* / */, 0x0f /* l */, - /* 0x4c */ 0x33 /* ; */, 0x13 /* p */, 0x2d /* - */, 0x00, - /* 0x50 */ 0x00, 0x00, 0x34 /* ' */, 0x00, - /* 0x54 */ 0x2f /* [ */, 0x2e /* = */, 0x00, 0x00, - /* 0x58 */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_RIGHT_SHIFT, 0x28 /* \n */,0x30 /* ] */, - /* 0x5c */ 0x00, 0x32 /* \ */, 0x00, 0x00, - /* 0x60 */ 0x00, 0x64 /* 102nd key. */, 0x00, 0x00, - /* 0x64 */ 0x00, 0x00, 0x2a /* \b */, 0x00, - /* 0x68 */ 0x00, 0x59 /* Num 1 */, 0x00, 0x5c /* Num 4 */, - /* 0x6c */ 0x5f /* Num 7 */, 0x00, 0x00, 0x00, - /* 0x70 */ 0x62 /* Num 0 */, 0x63 /* Num 0 */, 0x5a /* Num 2 */, 0x5d /* Num 5 */, - /* 0x74 */ 0x5e /* Num 6 */, 0x60 /* Num 8 */, 0x29 /* \e */, 0x53 /* NumLock */, - /* 0x78 */ 0x44 /* F11 */, 0x57 /* Num + */, 0x5b /* Num 3 */, 0x56 /* Num - */, - /* 0x7c */ 0x55 /* Num * */, 0x61 /* Num 9 */, 0x47 /* ScrollLock */, 0x00, - /* 0x80 */ 0x00, 0x00, 0x00, 0x40 /* F7 */, + /* 0x00 */ 0, GRUB_KEYBOARD_KEY_F9, + /* 0x02 */ 0, GRUB_KEYBOARD_KEY_F5, + /* 0x04 */ GRUB_KEYBOARD_KEY_F3, GRUB_KEYBOARD_KEY_F1, + /* 0x06 */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F12, + /* 0x08 */ 0, GRUB_KEYBOARD_KEY_F10, + /* 0x0a */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F6, + /* 0x0c */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_TAB, + /* 0x0e */ GRUB_KEYBOARD_KEY_RQUOTE, 0, + /* 0x10 */ 0, GRUB_KEYBOARD_KEY_LEFT_ALT, + /* 0x12 */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, 0, + /* 0x14 */ GRUB_KEYBOARD_KEY_LEFT_CTRL, GRUB_KEYBOARD_KEY_Q, + /* 0x16 */ GRUB_KEYBOARD_KEY_1, 0, + /* 0x18 */ 0, 0, + /* 0x1a */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_S, + /* 0x1c */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_W, + /* 0x1e */ GRUB_KEYBOARD_KEY_2, 0, + /* 0x20 */ 0, GRUB_KEYBOARD_KEY_C, + /* 0x22 */ GRUB_KEYBOARD_KEY_X, GRUB_KEYBOARD_KEY_D, + /* 0x24 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_4, + /* 0x26 */ GRUB_KEYBOARD_KEY_3, 0, + /* 0x28 */ 0, GRUB_KEYBOARD_KEY_SPACE, + /* 0x2a */ GRUB_KEYBOARD_KEY_V, GRUB_KEYBOARD_KEY_F, + /* 0x2c */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_R, + /* 0x2e */ GRUB_KEYBOARD_KEY_5, 0, + /* 0x30 */ 0, GRUB_KEYBOARD_KEY_N, + /* 0x32 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_H, + /* 0x34 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_Y, + /* 0x36 */ GRUB_KEYBOARD_KEY_6, 0, + /* 0x38 */ 0, 0, + /* 0x3a */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_J, + /* 0x3c */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_7, + /* 0x3e */ GRUB_KEYBOARD_KEY_8, 0, + /* 0x40 */ 0, GRUB_KEYBOARD_KEY_DOT, + /* 0x42 */ GRUB_KEYBOARD_KEY_K, GRUB_KEYBOARD_KEY_I, + /* 0x44 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_0, + /* 0x46 */ GRUB_KEYBOARD_KEY_9, 0, + /* 0x48 */ 0, GRUB_KEYBOARD_KEY_COMMA, + /* 0x4a */ GRUB_KEYBOARD_KEY_SLASH, GRUB_KEYBOARD_KEY_L, + /* 0x4c */ GRUB_KEYBOARD_KEY_SEMICOLON, GRUB_KEYBOARD_KEY_P, + /* 0x4e */ GRUB_KEYBOARD_KEY_DASH, 0, + /* 0x50 */ 0, 0, + /* 0x52 */ GRUB_KEYBOARD_KEY_DQUOTE, 0, + /* 0x54 */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_EQUAL, + /* 0x56 */ 0, 0, + /* 0x58 */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_RIGHT_SHIFT, + /* 0x5a */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_RBRACKET, + /* 0x5c */ 0, GRUB_KEYBOARD_KEY_BACKSLASH, + /* 0x5e */ 0, 0, + /* 0x60 */ 0, GRUB_KEYBOARD_KEY_102ND, + /* 0x62 */ 0, 0, + /* 0x64 */ 0, 0, + /* 0x66 */ GRUB_KEYBOARD_KEY_BACKSPACE, 0, + /* 0x68 */ 0, GRUB_KEYBOARD_KEY_NUM1, + /* 0x6a */ 0, GRUB_KEYBOARD_KEY_NUM4, + /* 0x6c */ GRUB_KEYBOARD_KEY_NUM7, 0, + /* 0x6e */ 0, 0, + /* 0x70 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUM0, + /* 0x72 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM5, + /* 0x74 */ GRUB_KEYBOARD_KEY_NUM6, GRUB_KEYBOARD_KEY_NUM8, + /* 0x76 */ GRUB_KEYBOARD_KEY_ESCAPE, GRUB_KEYBOARD_KEY_NUM_LOCK, + /* 0x78 */ GRUB_KEYBOARD_KEY_F11, GRUB_KEYBOARD_KEY_NUMPLUS, + /* 0x7a */ GRUB_KEYBOARD_KEY_NUM3, GRUB_KEYBOARD_KEY_NUMMINUS, + /* 0x7c */ GRUB_KEYBOARD_KEY_NUMMUL, GRUB_KEYBOARD_KEY_NUM9, + /* 0x7e */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, 0, + /* 0x80 */ 0, 0, + /* 0x82 */ 0, GRUB_KEYBOARD_KEY_F7, }; static const struct @@ -162,18 +195,18 @@ static const struct { {0x11, GRUB_KEYBOARD_KEY_RIGHT_ALT}, {0x14, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, - {0x4a, 0x54}, /* Num / */ - {0x5a, 0x58}, /* Num enter */ - {0x69, 0x4d}, /* End */ - {0x6b, 0x50}, /* Left */ - {0x6c, 0x4a}, /* Home */ - {0x70, 0x49}, /* Insert */ - {0x71, 0x4c}, /* Delete */ - {0x72, 0x51}, /* Down */ - {0x74, 0x4f}, /* Right */ - {0x75, 0x52}, /* Up */ - {0x7a, 0x4e}, /* PageDown */ - {0x7d, 0x4b}, /* PageUp */ + {0x4a, GRUB_KEYBOARD_KEY_NUMSLASH}, + {0x5a, GRUB_KEYBOARD_KEY_NUMENTER}, + {0x69, GRUB_KEYBOARD_KEY_END}, + {0x6b, GRUB_KEYBOARD_KEY_LEFT}, + {0x6c, GRUB_KEYBOARD_KEY_HOME}, + {0x70, GRUB_KEYBOARD_KEY_INSERT}, + {0x71, GRUB_KEYBOARD_KEY_DELETE}, + {0x72, GRUB_KEYBOARD_KEY_DOWN}, + {0x74, GRUB_KEYBOARD_KEY_RIGHT}, + {0x75, GRUB_KEYBOARD_KEY_UP}, + {0x7a, GRUB_KEYBOARD_KEY_NPAGE}, + {0x7d, GRUB_KEYBOARD_KEY_PPAGE}, }; static void diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index fc8ffb67a..e22888fc5 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -192,62 +192,62 @@ static struct console_grub_equivalence console_grub_equivalences_common[] = { }; static grub_uint8_t linux_to_usb_map[128] = { - /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, - /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, - /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, - /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, - /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, - /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, - /* 0x0c */ 0x2d /* - */, 0x2e /* = */, - /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, - /* 0x10 */ 0x14 /* q */, 0x1a /* w */, - /* 0x12 */ 0x08 /* e */, 0x15 /* r */, - /* 0x14 */ 0x17 /* t */, 0x1c /* y */, - /* 0x16 */ 0x18 /* u */, 0x0c /* i */, - /* 0x18 */ 0x12 /* o */, 0x13 /* p */, - /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, - /* 0x1c */ 0x28 /* Enter */, 0x00 /* Left CTRL */, - /* 0x1e */ 0x04 /* a */, 0x16 /* s */, - /* 0x20 */ 0x07 /* d */, 0x09 /* f */, - /* 0x22 */ 0x0a /* g */, 0x0b /* h */, - /* 0x24 */ 0x0d /* j */, 0x0e /* k */, - /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, - /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, - /* 0x2a */ 0x00 /* Left Shift */, 0x32 /* \ */, - /* 0x2c */ 0x1d /* z */, 0x1b /* x */, - /* 0x2e */ 0x06 /* c */, 0x19 /* v */, - /* 0x30 */ 0x05 /* b */, 0x11 /* n */, - /* 0x32 */ 0x10 /* m */, 0x36 /* , */, - /* 0x34 */ 0x37 /* . */, 0x38 /* / */, - /* 0x36 */ 0x00 /* Right Shift */, 0x55 /* Num * */, - /* 0x38 */ 0x00 /* Left ALT */, 0x2c /* Space */, - /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, - /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, - /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, - /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, - /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, - /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, - /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, - /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, - /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, - /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, - /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, - /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, - /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, - /* 0x54 */ 0x00, 0x00, - /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, - /* 0x58 */ 0x45 /* F12 */, 0x00, - /* 0x5a */ 0x00, 0x00, - /* 0x5c */ 0x00, 0x00, - /* 0x5e */ 0x00, 0x00, - /* 0x60 */ 0x58 /* Num \n */, 0x00 /* Right CTRL */, - /* 0x62 */ 0x54 /* Num / */, 0x00, - /* 0x64 */ 0x00 /* Right ALT */, 0x00, - /* 0x66 */ 0x4a /* Home */, 0x52 /* Up */, - /* 0x68 */ 0x4e /* NPage */, 0x50 /* Left */, - /* 0x6a */ 0x4f /* Right */, 0x4d /* End */, - /* 0x6c */ 0x51 /* Down */, 0x4b /* PPage */, - /* 0x6e */ 0x49 /* Insert */, 0x4c /* DC */ + /* 0x00 */ 0 /* Unused */, GRUB_KEYBOARD_KEY_ESCAPE, + /* 0x02 */ GRUB_KEYBOARD_KEY_1, GRUB_KEYBOARD_KEY_2, + /* 0x04 */ GRUB_KEYBOARD_KEY_3, GRUB_KEYBOARD_KEY_4, + /* 0x06 */ GRUB_KEYBOARD_KEY_5, GRUB_KEYBOARD_KEY_6, + /* 0x08 */ GRUB_KEYBOARD_KEY_7, GRUB_KEYBOARD_KEY_8, + /* 0x0a */ GRUB_KEYBOARD_KEY_9, GRUB_KEYBOARD_KEY_0, + /* 0x0c */ GRUB_KEYBOARD_KEY_DASH, GRUB_KEYBOARD_KEY_EQUAL, + /* 0x0e */ GRUB_KEYBOARD_KEY_BACKSPACE, GRUB_KEYBOARD_KEY_TAB, + /* 0x10 */ GRUB_KEYBOARD_KEY_Q, GRUB_KEYBOARD_KEY_W, + /* 0x12 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_R, + /* 0x14 */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_Y, + /* 0x16 */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_I, + /* 0x18 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_P, + /* 0x1a */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_RBRACKET, + /* 0x1c */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_LEFT_CTRL, + /* 0x1e */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_S, + /* 0x20 */ GRUB_KEYBOARD_KEY_D, GRUB_KEYBOARD_KEY_F, + /* 0x22 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_H, + /* 0x24 */ GRUB_KEYBOARD_KEY_J, GRUB_KEYBOARD_KEY_K, + /* 0x26 */ GRUB_KEYBOARD_KEY_L, GRUB_KEYBOARD_KEY_SEMICOLON, + /* 0x28 */ GRUB_KEYBOARD_KEY_DQUOTE, GRUB_KEYBOARD_KEY_RQUOTE, + /* 0x2a */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, GRUB_KEYBOARD_KEY_BACKSLASH, + /* 0x2c */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_X, + /* 0x2e */ GRUB_KEYBOARD_KEY_C, GRUB_KEYBOARD_KEY_V, + /* 0x30 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_N, + /* 0x32 */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_COMMA, + /* 0x34 */ GRUB_KEYBOARD_KEY_DOT, GRUB_KEYBOARD_KEY_SLASH, + /* 0x36 */ GRUB_KEYBOARD_KEY_RIGHT_SHIFT, GRUB_KEYBOARD_KEY_NUMMUL, + /* 0x38 */ GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_SPACE, + /* 0x3a */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_F1, + /* 0x3c */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F3, + /* 0x3e */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_F5, + /* 0x40 */ GRUB_KEYBOARD_KEY_F6, GRUB_KEYBOARD_KEY_F7, + /* 0x42 */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F9, + /* 0x44 */ GRUB_KEYBOARD_KEY_F10, GRUB_KEYBOARD_KEY_NUM_LOCK, + /* 0x46 */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, GRUB_KEYBOARD_KEY_NUM7, + /* 0x48 */ GRUB_KEYBOARD_KEY_NUM8, GRUB_KEYBOARD_KEY_NUM9, + /* 0x4a */ GRUB_KEYBOARD_KEY_NUMMINUS, GRUB_KEYBOARD_KEY_NUM4, + /* 0x4c */ GRUB_KEYBOARD_KEY_NUM5, GRUB_KEYBOARD_KEY_NUM6, + /* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS, GRUB_KEYBOARD_KEY_NUM1, + /* 0x50 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM3, + /* 0x52 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUMDOT, + /* 0x54 */ 0, 0, + /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, + /* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0, + /* 0x5a */ 0, 0, + /* 0x5c */ 0, 0, + /* 0x5e */ 0, 0, + /* 0x60 */ GRUB_KEYBOARD_KEY_NUMENTER, GRUB_KEYBOARD_KEY_RIGHT_CTRL, + /* 0x62 */ GRUB_KEYBOARD_KEY_NUMSLASH, 0, + /* 0x64 */ GRUB_KEYBOARD_KEY_RIGHT_ALT, 0, + /* 0x66 */ GRUB_KEYBOARD_KEY_HOME, GRUB_KEYBOARD_KEY_UP, + /* 0x68 */ GRUB_KEYBOARD_KEY_NPAGE, GRUB_KEYBOARD_KEY_LEFT, + /* 0x6a */ GRUB_KEYBOARD_KEY_RIGHT, GRUB_KEYBOARD_KEY_END, + /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_PPAGE, + /* 0x6e */ GRUB_KEYBOARD_KEY_INSERT, GRUB_KEYBOARD_KEY_DELETE }; static void From 9e91bd9d9ae3c89f89b235b2f3976fb2e4cdce2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 01:13:54 +0200 Subject: [PATCH 0085/1414] Fix multiple issues with set 2 --- commands/keylayouts.c | 2 +- term/at_keyboard.c | 113 +++++++++++++++++++++++++++--------------- 2 files changed, 74 insertions(+), 41 deletions(-) diff --git a/commands/keylayouts.c b/commands/keylayouts.c index c68919aef..deb482a85 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -153,7 +153,7 @@ map_key_core (int code, int status, int *alt_gr_consumed) } unsigned -grub_term_map_key (int code, int status) +grub_term_map_key (grub_keyboard_key_t code, int status) { int alt_gr_consumed = 0; int key; diff --git a/term/at_keyboard.c b/term/at_keyboard.c index c515a3971..b8df4cbf3 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -152,11 +152,11 @@ static const grub_uint8_t set2_mapping[256] = /* 0x3a */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_J, /* 0x3c */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_7, /* 0x3e */ GRUB_KEYBOARD_KEY_8, 0, - /* 0x40 */ 0, GRUB_KEYBOARD_KEY_DOT, + /* 0x40 */ 0, GRUB_KEYBOARD_KEY_COMMA, /* 0x42 */ GRUB_KEYBOARD_KEY_K, GRUB_KEYBOARD_KEY_I, /* 0x44 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_0, /* 0x46 */ GRUB_KEYBOARD_KEY_9, 0, - /* 0x48 */ 0, GRUB_KEYBOARD_KEY_COMMA, + /* 0x48 */ 0, GRUB_KEYBOARD_KEY_DOT, /* 0x4a */ GRUB_KEYBOARD_KEY_SLASH, GRUB_KEYBOARD_KEY_L, /* 0x4c */ GRUB_KEYBOARD_KEY_SEMICOLON, GRUB_KEYBOARD_KEY_P, /* 0x4e */ GRUB_KEYBOARD_KEY_DASH, 0, @@ -220,53 +220,75 @@ grub_keyboard_controller_write (grub_uint8_t c) { keyboard_controller_wait_until_ready (); grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS); + keyboard_controller_wait_until_ready (); grub_outb (c, KEYBOARD_REG_DATA); } -static grub_uint8_t -query_mode (int mode) +static int +write_mode (int mode) { + grub_uint8_t ack; keyboard_controller_wait_until_ready (); grub_outb (0xf0, KEYBOARD_REG_DATA); keyboard_controller_wait_until_ready (); - grub_inb (KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); grub_outb (mode, KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); + ack = grub_inb (KEYBOARD_REG_DATA); + if (ack != 0xfa) + return 0; + + return 1; +} + +static int +query_mode (void) +{ + grub_uint8_t ret; + int e; + + e = write_mode (0); + if (!e) + return 0; keyboard_controller_wait_until_ready (); - return grub_inb (KEYBOARD_REG_DATA); + do + ret = grub_inb (KEYBOARD_REG_DATA); + while (ret == 0xfa); + + /* QEMU translates the set even in no-translate mode. */ + if (ret == 0x43 || ret == 1) + return 1; + if (ret == 0x41 || ret == 2) + return 2; + if (ret == 0x3f || ret == 3) + return 3; + return 0; } -/* QEMU translates the set even in no-translate mode. */ -static inline int -recover_mode (grub_uint8_t report) -{ - if (report == 0x43 || report == 1) - return 1; - if (report == 0x41 || report == 2) - return 2; - if (report == 0x3f || report == 3) - return 3; - return -1; -} static void set_scancodes (void) { + grub_keyboard_orig_set = query_mode (); + /* You must have visited computer museum. Keyboard without scancode set + knowledge. Assume XT. */ + if (!grub_keyboard_orig_set) + { + current_set = 1; + return; + } + grub_keyboard_controller_write (grub_keyboard_controller_orig & ~KEYBOARD_AT_TRANSLATE); - grub_keyboard_orig_set = recover_mode (query_mode (0)); - query_mode (2); - current_set = query_mode (0); - current_set = recover_mode (current_set); + write_mode (2); + current_set = query_mode (); if (current_set == 2) return; - query_mode (1); - current_set = query_mode (0); - current_set = recover_mode (current_set); + write_mode (1); + current_set = query_mode (); if (current_set == 1) return; grub_printf ("No supported scancode set found\n"); @@ -305,6 +327,16 @@ fetch_key (int *is_break) return -1; } + if ((current_set == 2 || current_set == 3) && at_key == 0xf0) + { + f0_received = 1; + return -1; + } + + /* Setting LEDs may generate ACKs. */ + if (at_key == 0xfa) + return -1; + was_ext = e0_received; e0_received = 0; @@ -326,11 +358,6 @@ fetch_key (int *is_break) } break; case 2: - if (at_key == 0xf0) - { - f0_received = 1; - return -1; - } *is_break = f0_received; f0_received = 0; if (!was_ext) @@ -338,10 +365,10 @@ fetch_key (int *is_break) else { unsigned i; - for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) - if (set1_e0_mapping[i].from == (at_key & 0x80)) + for (i = 0; i < ARRAY_SIZE (set2_e0_mapping); i++) + if (set2_e0_mapping[i].from == at_key) { - ret = set1_e0_mapping[i].to; + ret = set2_e0_mapping[i].to; break; } } @@ -351,7 +378,12 @@ fetch_key (int *is_break) } if (!ret) { - grub_printf ("Unknown key 0x%02x from set %d\n\n", at_key, current_set); + if (was_ext) + grub_printf ("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); return -1; } return ret; @@ -387,7 +419,7 @@ grub_keyboard_isr (grub_keyboard_key_t key, int is_break) return 0; } else - switch (KEYBOARD_SCANCODE (key)) + switch (key) { case GRUB_KEYBOARD_KEY_LEFT_SHIFT: at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; @@ -507,12 +539,12 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus { pending_key = -1; at_keyboard_status = 0; - grub_keyboard_controller_orig = grub_keyboard_controller_read (); - set_scancodes (); - keyboard_controller_led (led_status); /* Drain input buffer. */ while (KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) grub_inb (KEYBOARD_REG_DATA); + grub_keyboard_controller_orig = grub_keyboard_controller_read (); + set_scancodes (); + keyboard_controller_led (led_status); return GRUB_ERR_NONE; } @@ -520,7 +552,8 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus static grub_err_t grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) { - query_mode (grub_keyboard_orig_set); + if (grub_keyboard_orig_set) + write_mode (grub_keyboard_orig_set); grub_keyboard_controller_write (grub_keyboard_controller_orig); return GRUB_ERR_NONE; } From b88904ca7fab60afec987ed39d95589d33e8bc1f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 01:44:54 +0200 Subject: [PATCH 0086/1414] Fix ignoring of set1 extended sequences --- term/at_keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index b8df4cbf3..ff9f713c6 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -350,7 +350,7 @@ fetch_key (int *is_break) { unsigned i; for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) - if (set1_e0_mapping[i].from == (at_key & 0x80)) + if (set1_e0_mapping[i].from == (at_key & 0x7f)) { ret = set1_e0_mapping[i].to; break; From 7ae3eb623250b80737e227c6efd0ca7740eb01ab Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 11:26:28 +0200 Subject: [PATCH 0087/1414] Wait for ACKs when setting the mode --- include/grub/at_keyboard.h | 2 ++ term/at_keyboard.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 6e0806bdb..3dfa0da80 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -27,6 +27,8 @@ #define KEYBOARD_AT_TRANSLATE 0x40 +#define GRUB_AT_ACK 0xfa + #define KEYBOARD_ISMAKE(x) !((x) & 0x80) #define KEYBOARD_ISREADY(x) ((x) & 0x01) #define KEYBOARD_SCANCODE(x) ((x) & 0x7f) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index ff9f713c6..e9db7834a 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -23,6 +23,7 @@ #include #include #include +#include static short at_keyboard_status = 0; static int e0_received = 0; @@ -225,19 +226,29 @@ grub_keyboard_controller_write (grub_uint8_t c) } static int -write_mode (int mode) +wait_ack (void) { grub_uint8_t ack; + grub_uint64_t endtime = grub_get_time_ms () + 20; + do + { + ack = grub_inb (KEYBOARD_REG_DATA); + } + while (ack != GRUB_AT_ACK && grub_get_time_ms () < endtime); + grub_dprintf ("atkeyb", "Ack 0x%02x\n", ack); + return ack == GRUB_AT_ACK; +} + +static int +write_mode (int mode) +{ keyboard_controller_wait_until_ready (); grub_outb (0xf0, KEYBOARD_REG_DATA); keyboard_controller_wait_until_ready (); grub_outb (mode, KEYBOARD_REG_DATA); keyboard_controller_wait_until_ready (); - ack = grub_inb (KEYBOARD_REG_DATA); - if (ack != 0xfa) - return 0; - return 1; + return wait_ack (); } static int @@ -254,7 +265,7 @@ query_mode (void) do ret = grub_inb (KEYBOARD_REG_DATA); - while (ret == 0xfa); + while (ret == GRUB_AT_ACK); /* QEMU translates the set even in no-translate mode. */ if (ret == 0x43 || ret == 1) @@ -275,6 +286,7 @@ set_scancodes (void) knowledge. Assume XT. */ if (!grub_keyboard_orig_set) { + grub_dprintf ("atkeyb", "No sets support assumed\n"); current_set = 1; return; } @@ -284,11 +296,13 @@ set_scancodes (void) write_mode (2); current_set = query_mode (); + grub_dprintf ("atkeyb", "returned set %d\n", current_set); if (current_set == 2) return; write_mode (1); current_set = query_mode (); + grub_dprintf ("atkeyb", "returned set %d\n", current_set); if (current_set == 1) return; grub_printf ("No supported scancode set found\n"); @@ -334,7 +348,7 @@ fetch_key (int *is_break) } /* Setting LEDs may generate ACKs. */ - if (at_key == 0xfa) + if (at_key == GRUB_AT_ACK) return -1; was_ext = e0_received; @@ -540,8 +554,14 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus pending_key = -1; at_keyboard_status = 0; /* Drain input buffer. */ - while (KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - grub_inb (KEYBOARD_REG_DATA); + while (1) + { + keyboard_controller_wait_until_ready (); + if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + break; + keyboard_controller_wait_until_ready (); + grub_inb (KEYBOARD_REG_DATA); + } grub_keyboard_controller_orig = grub_keyboard_controller_read (); set_scancodes (); keyboard_controller_led (led_status); From df2174ddedad2a1ae8d404476ae90069c3573adb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 12:07:49 +0200 Subject: [PATCH 0088/1414] Remove checkkey on term level --- include/grub/i386/pc/console.h | 1 - include/grub/term.h | 5 +-- include/grub/terminfo.h | 1 - kern/emu/console.c | 40 +++-------------------- kern/i386/pc/startup.S | 58 ++++++++-------------------------- kern/term.c | 21 +++++++++--- term/at_keyboard.c | 36 +-------------------- term/efi/console.c | 48 +++------------------------- term/i386/pc/console.c | 1 - term/ieee1275/ofconsole.c | 1 - term/serial.c | 1 - term/terminfo.c | 43 ++++++++++--------------- term/usb_keyboard.c | 49 +++++----------------------- 13 files changed, 65 insertions(+), 240 deletions(-) diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index fabb13d5c..1631a40ad 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -27,7 +27,6 @@ #include /* These are global to share code between C and asm. */ -int grub_console_checkkey (struct grub_term_input *term); int grub_console_getkey (struct grub_term_input *term); grub_uint16_t grub_console_getxy (struct grub_term_output *term); void grub_console_gotoxy (struct grub_term_output *term, diff --git a/include/grub/term.h b/include/grub/term.h index bfe1c8f9b..428978142 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -158,10 +158,7 @@ struct grub_term_input /* Clean up the terminal. */ grub_err_t (*fini) (struct grub_term_input *term); - /* Check if any input character is available. */ - int (*checkkey) (struct grub_term_input *term); - - /* Get a character. */ + /* Get a character if any input character is available. Otherwise return -1 */ int (*getkey) (struct grub_term_input *term); /* Get keyboard modifier status. */ diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 85ddb5779..1962c71b7 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -64,7 +64,6 @@ void EXPORT_FUNC (grub_terminfo_setcolorstate) (struct grub_term_output *term, const grub_term_color_state state); -int EXPORT_FUNC (grub_terminfo_checkkey) (struct grub_term_input *term); grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term); int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term); void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term, diff --git a/kern/emu/console.c b/kern/emu/console.c index f6b13b19b..0bf1e05f9 100644 --- a/kern/emu/console.c +++ b/kern/emu/console.c @@ -102,49 +102,18 @@ grub_ncurses_setcolorstate (struct grub_term_output *term, } } -static int saved_char = ERR; - -static int -grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused))) -{ - int c; - - /* Check for SAVED_CHAR. This should not be true, because this - means checkkey is called twice continuously. */ - if (saved_char != ERR) - return saved_char; - - wtimeout (stdscr, 100); - c = getch (); - /* If C is not ERR, then put it back in the input queue. */ - if (c != ERR) - { - saved_char = c; - return c; - } - - return -1; -} - static int grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused))) { int c; - /* If checkkey has already got a character, then return it. */ - if (saved_char != ERR) - { - c = saved_char; - saved_char = ERR; - } - else - { - wtimeout (stdscr, -1); - c = getch (); - } + wtimeout (stdscr, 100); + c = getch (); switch (c) { + case ERR: + return -1; case KEY_LEFT: c = GRUB_TERM_LEFT; break; @@ -288,7 +257,6 @@ grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused))) static struct grub_term_input grub_ncurses_term_input = { .name = "console", - .checkkey = grub_ncurses_checkkey, .getkey = grub_ncurses_getkey, }; diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index f78fb5baa..2d7264156 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1154,6 +1154,16 @@ LOCAL(bypass_table_end): /* * int grub_console_getkey (void) + * if there is a character pending, return it; otherwise return -1 + * BIOS call "INT 16H Function 01H" to check whether a character is pending + * Call with %ah = 0x1 + * Return: + * If key waiting to be input: + * %ah = keyboard scan code + * %al = ASCII character + * Zero flag = clear + * else + * Zero flag = set * BIOS call "INT 16H Function 00H" to read character from keyboard * Call with %ah = 0x0 * Return: %ah = keyboard scan code @@ -1173,14 +1183,9 @@ FUNCTION(grub_console_getkey) * INT 16/AH = 1 before calling INT 16/AH = 0. */ -1: movb $1, %ah int $0x16 - jnz 2f - hlt - jmp 1b - -2: + jz notpending movb $0, %ah int $0x16 @@ -1217,47 +1222,12 @@ FUNCTION(grub_console_getkey) popl %ebp ret -/* - * int grub_console_checkkey (void) - * if there is a character pending, return it; otherwise return -1 - * BIOS call "INT 16H Function 01H" to check whether a character is pending - * Call with %ah = 0x1 - * Return: - * If key waiting to be input: - * %ah = keyboard scan code - * %al = ASCII character - * Zero flag = clear - * else - * Zero flag = set - */ -FUNCTION(grub_console_checkkey) - pushl %ebp - xorl %edx, %edx - - call prot_to_real /* enter real mode */ +notpending: .code16 - - movb $0x1, %ah - int $0x16 - - jz notpending - - xorl %edx, %edx - movw %ax, %dx - DATA32 jmp pending - -notpending: - xorl %edx, %edx - decl %edx - -pending: DATA32 call real_to_prot .code32 - - movl %edx, %eax - - popl %ebp - ret + decl %eax + jmp 2b /* diff --git a/kern/term.c b/kern/term.c index 185626d36..a05325346 100644 --- a/kern/term.c +++ b/kern/term.c @@ -78,6 +78,8 @@ grub_xputs_dumb (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_dumb; +static int pending_key = -1; + int grub_getkey (void) { @@ -85,6 +87,12 @@ grub_getkey (void) grub_refresh (); + if (pending_key != -1) + { + pending_key = -1; + return pending_key; + } + while (1) { if (grub_term_poll_usb) @@ -92,9 +100,9 @@ grub_getkey (void) FOR_ACTIVE_TERM_INPUTS(term) { - int key = term->checkkey (term); + int key = term->getkey (term); if (key != -1) - return term->getkey (term); + return key; } grub_cpu_idle (); @@ -106,14 +114,17 @@ grub_checkkey (void) { grub_term_input_t term; + if (pending_key != -1) + return pending_key; + if (grub_term_poll_usb) grub_term_poll_usb (); FOR_ACTIVE_TERM_INPUTS(term) { - int key = term->checkkey (term); - if (key != -1) - return key; + pending_key = term->getkey (term); + if (pending_key != -1) + return pending_key; } return -1; diff --git a/term/at_keyboard.c b/term/at_keyboard.c index e9db7834a..6ea908a2b 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -28,7 +28,6 @@ static short at_keyboard_status = 0; static int e0_received = 0; static int f0_received = 0; -static int pending_key = -1; static grub_uint8_t led_status; @@ -478,7 +477,7 @@ grub_keyboard_getkey (void) /* If there is a character pending, return it; otherwise return -1. */ static int -grub_at_keyboard_getkey_noblock (void) +grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) { int code; code = grub_keyboard_getkey (); @@ -517,41 +516,9 @@ grub_at_keyboard_getkey_noblock (void) } } -static int -grub_at_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused))) -{ - if (pending_key != -1) - return 1; - - pending_key = grub_at_keyboard_getkey_noblock (); - - if (pending_key != -1) - return 1; - - return -1; -} - -static int -grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - int key; - if (pending_key != -1) - { - key = pending_key; - pending_key = -1; - return key; - } - do - { - key = grub_at_keyboard_getkey_noblock (); - } while (key == -1); - return key; -} - static grub_err_t grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unused))) { - pending_key = -1; at_keyboard_status = 0; /* Drain input buffer. */ while (1) @@ -583,7 +550,6 @@ static struct grub_term_input grub_at_keyboard_term = .name = "at_keyboard", .init = grub_keyboard_controller_init, .fini = grub_keyboard_controller_fini, - .checkkey = grub_at_keyboard_checkkey, .getkey = grub_at_keyboard_getkey }; diff --git a/term/efi/console.c b/term/efi/console.c index f47263ee4..97fefd981 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -28,8 +28,6 @@ static const grub_uint8_t grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW, GRUB_EFI_BACKGROUND_BLACK); -static int read_key = -1; - static grub_uint32_t map_char (grub_uint32_t c) { @@ -112,15 +110,12 @@ const unsigned efi_codes[] = static int -grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused))) +grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) { grub_efi_simple_input_interface_t *i; grub_efi_input_key_t key; grub_efi_status_t status; - if (read_key >= 0) - return 1; - i = grub_efi_system_table->con_in; status = efi_call_2 (i->read_key_stroke, i, &key); @@ -128,45 +123,11 @@ grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused))) return -1; if (key.scan_code == 0) - read_key = key.unicode_char; + return key.unicode_char; else if (key.scan_code < ARRAY_SIZE (efi_codes)) - read_key = efi_codes[key.scan_code]; + return efi_codes[key.scan_code]; - return read_key; -} - -static int -grub_console_getkey (struct grub_term_input *term) -{ - grub_efi_simple_input_interface_t *i; - grub_efi_boot_services_t *b; - grub_efi_uintn_t index; - grub_efi_status_t status; - int key; - - if (read_key >= 0) - { - key = read_key; - read_key = -1; - return key; - } - - i = grub_efi_system_table->con_in; - b = grub_efi_system_table->boot_services; - - do - { - status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index); - if (status != GRUB_EFI_SUCCESS) - return -1; - - grub_console_checkkey (term); - } - while (read_key < 0); - - key = read_key; - read_key = -1; - return key; + return -1; } static grub_uint16_t @@ -268,7 +229,6 @@ grub_efi_console_fini (struct grub_term_output *term) static struct grub_term_input grub_console_term_input = { .name = "console", - .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, }; diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 009647c4c..0efeafe4e 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -34,7 +34,6 @@ grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)) static struct grub_term_input grub_console_term_input = { .name = "console", - .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, .getkeystatus = grub_console_getkeystatus }; diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 604906ceb..e6550254f 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -189,7 +189,6 @@ static struct grub_term_input grub_ofconsole_term_input = { .name = "ofconsole", .init = grub_ofconsole_init_input, - .checkkey = grub_terminfo_checkkey, .getkey = grub_terminfo_getkey, .data = &grub_ofconsole_terminfo_input }; diff --git a/term/serial.c b/term/serial.c index 2268788af..f435a7bc5 100644 --- a/term/serial.c +++ b/term/serial.c @@ -99,7 +99,6 @@ static struct grub_term_input grub_serial_term_input = { .name = "serial", .init = grub_terminfo_input_init, - .checkkey = grub_terminfo_checkkey, .getkey = grub_terminfo_getkey, .data = &grub_serial_terminfo_input }; diff --git a/term/terminfo.c b/term/terminfo.c index 5379aac0c..d2d821449 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -467,39 +467,30 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, #undef CONTINUE_READ } -/* The terminfo version of checkkey. */ -int -grub_terminfo_checkkey (struct grub_term_input *termi) -{ - struct grub_terminfo_input_state *data - = (struct grub_terminfo_input_state *) (termi->data); - if (data->npending) - return data->input_buf[0]; - - grub_terminfo_readkey (termi, data->input_buf, - &data->npending, data->readkey); - - if (data->npending) - return data->input_buf[0]; - - return -1; -} - /* The terminfo version of getkey. */ int grub_terminfo_getkey (struct grub_term_input *termi) { struct grub_terminfo_input_state *data = (struct grub_terminfo_input_state *) (termi->data); - int ret; - while (! data->npending) - grub_terminfo_readkey (termi, data->input_buf, &data->npending, - data->readkey); + if (data->npending) + { + data->npending--; + grub_memmove (data->input_buf, data->input_buf + 1, data->npending); + return data->input_buf[0]; + } - ret = data->input_buf[0]; - data->npending--; - grub_memmove (data->input_buf, data->input_buf + 1, data->npending); - return ret; + grub_terminfo_readkey (termi, data->input_buf, + &data->npending, data->readkey); + + if (data->npending) + { + data->npending--; + grub_memmove (data->input_buf, data->input_buf + 1, data->npending); + return data->input_buf[0]; + } + + return -1; } grub_err_t diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index b57b171f8..ca3a81179 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -68,7 +68,6 @@ struct grub_usb_keyboard_data grub_usb_device_t usbdev; grub_uint8_t status; grub_uint16_t mods; - int key; int interfno; struct grub_usb_desc_endp *endp; grub_usb_transfer_t transfer; @@ -78,15 +77,11 @@ struct grub_usb_keyboard_data grub_uint64_t repeat_time; }; -static struct grub_term_input grub_usb_keyboards[16]; - -static int grub_usb_keyboard_checkkey (struct grub_term_input *term); static int grub_usb_keyboard_getkey (struct grub_term_input *term); static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term); static struct grub_term_input grub_usb_keyboard_term = { - .checkkey = grub_usb_keyboard_checkkey, .getkey = grub_usb_keyboard_getkey, .getkeystatus = grub_usb_keyboard_getkeystatus, .next = 0 @@ -231,19 +226,12 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) USB_HID_GET_REPORT, 0x0100, interfno, sizeof (report), (char *) report); if (err) - { - data->status = 0; - data->key = -1; - } + data->status = 0; else - { - data->status = report[0]; - data->key = report[2] ? : -1; - } + data->status = report[0]; } #else data->status = 0; - data->key = -1; #endif data->transfer = grub_usb_bulk_read_background (usbdev, @@ -283,16 +271,13 @@ send_leds (struct grub_usb_keyboard_data *termdata) } static int -grub_usb_keyboard_checkkey (struct grub_term_input *term) +grub_usb_keyboard_getkey (struct grub_term_input *term) { grub_usb_err_t err; struct grub_usb_keyboard_data *termdata = term->data; grub_uint8_t data[sizeof (termdata->report)]; grub_size_t actual; - if (termdata->key != -1) - return termdata->key; - if (termdata->dead) return -1; @@ -304,11 +289,11 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) if (termdata->last_key != -1 && grub_get_time_ms () > termdata->repeat_time) { - termdata->key = termdata->last_key; termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_INTERVAL; + return termdata->last_key; } - return termdata->key; + return -1; } grub_memcpy (data, termdata->report, sizeof (data)); @@ -358,29 +343,13 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) return -1; } - termdata->last_key = termdata->key - = grub_term_map_key (data[2], interpret_status (data[0]) | termdata->mods); + termdata->last_key = grub_term_map_key (data[2], interpret_status (data[0]) + | termdata->mods); termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL; grub_errno = GRUB_ERR_NONE; - return termdata->key; -} - -static int -grub_usb_keyboard_getkey (struct grub_term_input *term) -{ - int ret; - struct grub_usb_keyboard_data *termdata = term->data; - - while (termdata->key == -1) - grub_usb_keyboard_checkkey (term); - - ret = termdata->key; - - termdata->key = -1; - - return ret; + return termdata->last_key; } static int @@ -388,8 +357,6 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term) { struct grub_usb_keyboard_data *termdata = term->data; - grub_usb_keyboard_checkkey (term); - return interpret_status (termdata->status) | termdata->mods; } From 9518e2a12bab434d0ba96df15773487f6adf0608 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 12:53:42 +0200 Subject: [PATCH 0089/1414] Macroify GRUB_TERM_NO_KEY and use grub_checkkey in grub_getkey --- include/grub/term.h | 2 ++ kern/i386/pc/startup.S | 3 +++ kern/term.c | 50 +++++++++++++++--------------------------- term/at_keyboard.c | 11 +++++----- term/efi/console.c | 4 ++-- term/terminfo.c | 2 +- term/usb_keyboard.c | 14 ++++++------ 7 files changed, 39 insertions(+), 47 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index 428978142..81c18365c 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -19,6 +19,8 @@ #ifndef GRUB_TERM_HEADER #define GRUB_TERM_HEADER 1 +#define GRUB_TERM_NO_KEY -1 + /* Internal codes used by GRUB to represent terminal input. */ /* Only for keys otherwise not having shifted modification. */ #define GRUB_TERM_SHIFT 0x01000000 diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 2d7264156..5a6934dee 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1226,6 +1226,9 @@ notpending: .code16 DATA32 call real_to_prot .code32 +#if GRUB_TERM_NO_KEY != -1 +#error Fix this asm code +#endif decl %eax jmp 2b diff --git a/kern/term.c b/kern/term.c index a05325346..9d23b4f91 100644 --- a/kern/term.c +++ b/kern/term.c @@ -78,43 +78,14 @@ grub_xputs_dumb (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_dumb; -static int pending_key = -1; - -int -grub_getkey (void) -{ - grub_term_input_t term; - - grub_refresh (); - - if (pending_key != -1) - { - pending_key = -1; - return pending_key; - } - - while (1) - { - if (grub_term_poll_usb) - grub_term_poll_usb (); - - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->getkey (term); - if (key != -1) - return key; - } - - grub_cpu_idle (); - } -} +static int pending_key = GRUB_TERM_NO_KEY; int grub_checkkey (void) { grub_term_input_t term; - if (pending_key != -1) + if (pending_key != GRUB_TERM_NO_KEY) return pending_key; if (grub_term_poll_usb) @@ -123,13 +94,28 @@ grub_checkkey (void) FOR_ACTIVE_TERM_INPUTS(term) { pending_key = term->getkey (term); - if (pending_key != -1) + if (pending_key != GRUB_TERM_NO_KEY) return pending_key; } return -1; } +int +grub_getkey (void) +{ + grub_refresh (); + + while (pending_key != GRUB_TERM_NO_KEY) + { + grub_cpu_idle (); + grub_checkkey (); + } + pending_key = GRUB_TERM_NO_KEY; + return pending_key; +} + + void grub_refresh (void) { diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 6ea908a2b..681dd3ef9 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -475,14 +475,15 @@ grub_keyboard_getkey (void) return key; } -/* If there is a character pending, return it; otherwise return -1. */ +/* If there is a character pending, return it; + otherwise return GRUB_TERM_NO_KEY. */ static int grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) { int code; code = grub_keyboard_getkey (); if (code == -1) - return -1; + return GRUB_TERM_NO_KEY; #ifdef DEBUG_AT_KEYBOARD grub_dprintf ("atkeyb", "Detected key 0x%x\n", key); #endif @@ -496,7 +497,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) #ifdef DEBUG_AT_KEYBOARD grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)); #endif - return -1; + return GRUB_TERM_NO_KEY; case GRUB_KEYBOARD_KEY_NUM_LOCK: at_keyboard_status ^= GRUB_TERM_STATUS_NUM; led_status ^= KEYBOARD_LED_NUM; @@ -505,12 +506,12 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) #ifdef DEBUG_AT_KEYBOARD grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK)); #endif - return -1; + return GRUB_TERM_NO_KEY; case GRUB_KEYBOARD_KEY_SCROLL_LOCK: at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL; led_status ^= KEYBOARD_LED_SCROLL; keyboard_controller_led (led_status); - return -1; + return GRUB_TERM_NO_KEY; default: return grub_term_map_key (code, at_keyboard_status); } diff --git a/term/efi/console.c b/term/efi/console.c index 97fefd981..1667bcd4f 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -120,14 +120,14 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) status = efi_call_2 (i->read_key_stroke, i, &key); if (status != GRUB_EFI_SUCCESS) - return -1; + return GRUB_TERM_NO_KEY; if (key.scan_code == 0) return key.unicode_char; else if (key.scan_code < ARRAY_SIZE (efi_codes)) return efi_codes[key.scan_code]; - return -1; + return GRUB_TERM_NO_KEY; } static grub_uint16_t diff --git a/term/terminfo.c b/term/terminfo.c index d2d821449..8dea7aea1 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -490,7 +490,7 @@ grub_terminfo_getkey (struct grub_term_input *termi) return data->input_buf[0]; } - return -1; + return GRUB_TERM_NO_KEY; } grub_err_t diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index ca3a81179..6b1485e96 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -279,7 +279,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) grub_size_t actual; if (termdata->dead) - return -1; + return GRUB_TERM_NO_KEY; /* Poll interrupt pipe. */ err = grub_usb_check_transfer (termdata->transfer, &actual); @@ -293,7 +293,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) + GRUB_TERM_REPEAT_INTERVAL; return termdata->last_key; } - return -1; + return GRUB_TERM_NO_KEY; } grub_memcpy (data, termdata->report, sizeof (data)); @@ -318,29 +318,29 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) data[4], data[5], data[6], data[7]); if (err || actual < 1) - return -1; + return GRUB_TERM_NO_KEY; termdata->status = data[0]; if (actual < 3) - return -1; + return GRUB_TERM_NO_KEY; if (data[2] == KEY_NO_KEY || data[2] == KEY_ERR_BUFFER || data[2] == KEY_ERR_POST || data[2] == KEY_ERR_UNDEF) - return -1; + return GRUB_TERM_NO_KEY; if (data[2] == KEY_CAPS_LOCK) { termdata->mods ^= GRUB_TERM_STATUS_CAPS; send_leds (termdata); - return -1; + return GRUB_TERM_NO_KEY; } if (data[2] == KEY_NUM_LOCK) { termdata->mods ^= GRUB_TERM_STATUS_NUM; send_leds (termdata); - return -1; + return GRUB_TERM_NO_KEY; } termdata->last_key = grub_term_map_key (data[2], interpret_status (data[0]) From 071b673a7b50b59754841cf1c1f888c51d0a670e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 13:12:29 +0200 Subject: [PATCH 0090/1414] Fix bugs in grub_getkey introduced in previous commit --- kern/term.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kern/term.c b/kern/term.c index 9d23b4f91..7b3593161 100644 --- a/kern/term.c +++ b/kern/term.c @@ -104,15 +104,19 @@ grub_checkkey (void) int grub_getkey (void) { + int ret; + grub_refresh (); - while (pending_key != GRUB_TERM_NO_KEY) + grub_checkkey (); + while (pending_key == GRUB_TERM_NO_KEY) { grub_cpu_idle (); grub_checkkey (); } + ret = pending_key; pending_key = GRUB_TERM_NO_KEY; - return pending_key; + return ret; } From 9f5a5ad55a2593e89bb2278101fcaea8a35e61c1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 13:21:26 +0200 Subject: [PATCH 0091/1414] Fix RCTRL and RALT linux scancodes --- util/grub-mklayout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index e22888fc5..c07869eae 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -375,11 +375,11 @@ write_keymaps (FILE *in, FILE *out) /* Not remappable. */ if (keycode_linux == 0x1d /* Left CTRL */ - || keycode_linux == 0x9d /* Right CTRL */ + || keycode_linux == 0x61 /* Right CTRL */ || keycode_linux == 0x2a /* Left Shift. */ || keycode_linux == 0x36 /* Right Shift. */ || keycode_linux == 0x38 /* Left ALT. */ - || keycode_linux == 0xb8 /* Right ALT. */ + || keycode_linux == 0x64 /* Right ALT. */ || keycode_linux == 0x3a /* CapsLock. */ || keycode_linux == 0x45 /* NumLock. */ || keycode_linux == 0x46 /* ScrollLock. */) From 3ba3c4567e1edcb0a45e543f86e0683ec5b7057c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 13:21:53 +0200 Subject: [PATCH 0092/1414] Change GRUB_TERM_NO_KEY to 0 --- include/grub/term.h | 2 +- kern/i386/pc/startup.S | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/grub/term.h b/include/grub/term.h index 81c18365c..dbcb2f52c 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -19,7 +19,7 @@ #ifndef GRUB_TERM_HEADER #define GRUB_TERM_HEADER 1 -#define GRUB_TERM_NO_KEY -1 +#define GRUB_TERM_NO_KEY 0 /* Internal codes used by GRUB to represent terminal input. */ /* Only for keys otherwise not having shifted modification. */ diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 5a6934dee..f7a924fa8 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1226,10 +1226,9 @@ notpending: .code16 DATA32 call real_to_prot .code32 -#if GRUB_TERM_NO_KEY != -1 +#if GRUB_TERM_NO_KEY != 0 #error Fix this asm code #endif - decl %eax jmp 2b From 400ef90dba295d1f3ed38c10020d34b3365bbcb1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 20:40:06 +0200 Subject: [PATCH 0093/1414] Fix reversal of NPAGE and PPAGE when handling Linux keymaps --- util/grub-mklayout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index c07869eae..ac59981c7 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -244,9 +244,9 @@ static grub_uint8_t linux_to_usb_map[128] = { /* 0x62 */ GRUB_KEYBOARD_KEY_NUMSLASH, 0, /* 0x64 */ GRUB_KEYBOARD_KEY_RIGHT_ALT, 0, /* 0x66 */ GRUB_KEYBOARD_KEY_HOME, GRUB_KEYBOARD_KEY_UP, - /* 0x68 */ GRUB_KEYBOARD_KEY_NPAGE, GRUB_KEYBOARD_KEY_LEFT, + /* 0x68 */ GRUB_KEYBOARD_KEY_PPAGE, GRUB_KEYBOARD_KEY_LEFT, /* 0x6a */ GRUB_KEYBOARD_KEY_RIGHT, GRUB_KEYBOARD_KEY_END, - /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_PPAGE, + /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_NPAGE, /* 0x6e */ GRUB_KEYBOARD_KEY_INSERT, GRUB_KEYBOARD_KEY_DELETE }; From f0b02c9c86daa78b3580e1de60986d1eea65f9d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 20:43:44 +0200 Subject: [PATCH 0094/1414] Handle ACKs, NACKs and restore state on booting --- include/grub/at_keyboard.h | 2 + term/at_keyboard.c | 115 +++++++++++++++++++++++++++---------- 2 files changed, 88 insertions(+), 29 deletions(-) diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 3dfa0da80..65cf8a2a2 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -28,6 +28,8 @@ #define KEYBOARD_AT_TRANSLATE 0x40 #define GRUB_AT_ACK 0xfa +#define GRUB_AT_NACK 0xfe +#define GRUB_AT_TRIES 5 #define KEYBOARD_ISMAKE(x) !((x) & 0x80) #define KEYBOARD_ISREADY(x) ((x) & 0x01) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 681dd3ef9..1b130bd62 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -24,6 +24,7 @@ #include #include #include +#include static short at_keyboard_status = 0; static int e0_received = 0; @@ -215,39 +216,76 @@ keyboard_controller_wait_until_ready (void) while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); } +static grub_uint8_t +wait_ack (void) +{ + grub_uint64_t endtime; + grub_uint8_t ack; + + endtime = grub_get_time_ms () + 20; + do + ack = grub_inb (KEYBOARD_REG_DATA); + while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK + && grub_get_time_ms () < endtime); + return ack; +} + +static int +at_command (grub_uint8_t data) +{ + unsigned i; + for (i = 0; i < GRUB_AT_TRIES; i++) + { + grub_uint8_t ack; + keyboard_controller_wait_until_ready (); + grub_outb (data, KEYBOARD_REG_STATUS); + ack = wait_ack (); + if (ack == GRUB_AT_NACK) + continue; + if (ack == GRUB_AT_ACK) + break; + return 0; + } + return (i != GRUB_AT_TRIES); +} + static void grub_keyboard_controller_write (grub_uint8_t c) { - keyboard_controller_wait_until_ready (); - grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS); + at_command (KEYBOARD_COMMAND_WRITE); keyboard_controller_wait_until_ready (); grub_outb (c, KEYBOARD_REG_DATA); } -static int -wait_ack (void) +static grub_uint8_t +grub_keyboard_controller_read (void) { - grub_uint8_t ack; - grub_uint64_t endtime = grub_get_time_ms () + 20; - do - { - ack = grub_inb (KEYBOARD_REG_DATA); - } - while (ack != GRUB_AT_ACK && grub_get_time_ms () < endtime); - grub_dprintf ("atkeyb", "Ack 0x%02x\n", ack); - return ack == GRUB_AT_ACK; + at_command (KEYBOARD_COMMAND_READ); + keyboard_controller_wait_until_ready (); + return grub_inb (KEYBOARD_REG_DATA); } static int write_mode (int mode) { - keyboard_controller_wait_until_ready (); - grub_outb (0xf0, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); - grub_outb (mode, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); + unsigned i; + for (i = 0; i < GRUB_AT_TRIES; i++) + { + grub_uint8_t ack; + keyboard_controller_wait_until_ready (); + grub_outb (0xf0, KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); + grub_outb (mode, KEYBOARD_REG_DATA); + keyboard_controller_wait_until_ready (); + ack = wait_ack (); + if (ack == GRUB_AT_NACK) + continue; + if (ack == GRUB_AT_ACK) + break; + return 0; + } - return wait_ack (); + return (i != GRUB_AT_TRIES); } static int @@ -276,11 +314,9 @@ query_mode (void) return 0; } - static void set_scancodes (void) { - grub_keyboard_orig_set = query_mode (); /* You must have visited computer museum. Keyboard without scancode set knowledge. Assume XT. */ if (!grub_keyboard_orig_set) @@ -307,14 +343,6 @@ set_scancodes (void) grub_printf ("No supported scancode set found\n"); } -static grub_uint8_t -grub_keyboard_controller_read (void) -{ - keyboard_controller_wait_until_ready (); - grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS); - return grub_inb (KEYBOARD_REG_DATA); -} - static void keyboard_controller_led (grub_uint8_t leds) { @@ -531,6 +559,7 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus grub_inb (KEYBOARD_REG_DATA); } grub_keyboard_controller_orig = grub_keyboard_controller_read (); + grub_keyboard_orig_set = query_mode (); set_scancodes (); keyboard_controller_led (led_status); @@ -546,6 +575,31 @@ grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unus return GRUB_ERR_NONE; } +static grub_err_t +grub_at_fini_hw (int noreturn __attribute__ ((unused))) +{ + return grub_keyboard_controller_fini (NULL); +} + +static grub_err_t +grub_at_restore_hw (void) +{ + /* Drain input buffer. */ + while (1) + { + keyboard_controller_wait_until_ready (); + if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + break; + keyboard_controller_wait_until_ready (); + grub_inb (KEYBOARD_REG_DATA); + } + set_scancodes (); + keyboard_controller_led (led_status); + + return GRUB_ERR_NONE; +} + + static struct grub_term_input grub_at_keyboard_term = { .name = "at_keyboard", @@ -557,9 +611,12 @@ static struct grub_term_input grub_at_keyboard_term = GRUB_MOD_INIT(at_keyboard) { grub_term_register_input ("at_keyboard", &grub_at_keyboard_term); + grub_loader_register_preboot_hook (grub_at_fini_hw, grub_at_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE); } GRUB_MOD_FINI(at_keyboard) { + grub_keyboard_controller_fini (NULL); grub_term_unregister_input (&grub_at_keyboard_term); } From 7c4425061d365271aee7c90aadbd2356b63cd73a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 23:27:59 +0200 Subject: [PATCH 0095/1414] Don't reuse finished but not reclaimed QH --- bus/usb/uhci.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 472a7054e..b719051d6 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -28,6 +28,8 @@ #define GRUB_UHCI_IOMASK (0x7FF << 5) +#define N_QH 256 + typedef enum { GRUB_UHCI_REG_USBCMD = 0x00, @@ -99,7 +101,7 @@ struct grub_uhci int iobase; grub_uint32_t *framelist; - /* 256 Queue Heads. */ + /* N_QH Queue Heads. */ grub_uhci_qh_t qh; /* 256 Transfer Descriptors. */ @@ -108,6 +110,8 @@ struct grub_uhci /* Free Transfer Descriptors. */ grub_uhci_td_t tdfree; + int qh_busy[N_QH]; + struct grub_uhci *next; }; @@ -260,7 +264,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, (grub_uint32_t) u->framelist); /* Make the Queue Heads point to each other. */ - for (i = 0; i < 256; i++) + for (i = 0; i < N_QH; i++) { /* Point to the next QH. */ u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15); @@ -273,9 +277,8 @@ grub_uhci_pci_iter (grub_pci_device_t dev, u->qh[i].elinkptr = 1; } - /* The last Queue Head should terminate. 256 are too many QHs so - just use 50. */ - u->qh[50 - 1].linkptr = 1; + /* The last Queue Head should terminate. */ + u->qh[N_QH - 1].linkptr = 1; /* Enable UHCI again. */ grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7)); @@ -344,11 +347,13 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td) } static void -grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td, +grub_free_queue (struct grub_uhci *u, grub_uhci_qh_t qh, grub_uhci_td_t td, grub_usb_transfer_t transfer, grub_size_t *actual) { int i; /* Index of TD in transfer */ + u->qh_busy[qh - u->qh] = 0; + *actual = 0; /* Free the TDs in this queue and set last_trans. */ @@ -387,19 +392,21 @@ grub_alloc_qh (struct grub_uhci *u, #endif i = 1; - for (; i < 255; i++) + for (; i < N_QH; i++) { - if (u->qh[i].elinkptr & 1) + if (!u->qh_busy[i]) break; } qh = &u->qh[i]; - if (! (qh->elinkptr & 1)) + if (i == N_QH) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free queue heads available"); return NULL; } + u->qh_busy[qh - u->qh] = 1; + return qh; } @@ -497,7 +504,7 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev, td_prev->linkptr = 1; if (cdata->td_first) - grub_free_queue (u, cdata->td_first, NULL, &actual); + grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual); grub_free (cdata); return GRUB_USB_ERR_INTERNAL; @@ -553,7 +560,7 @@ grub_uhci_check_transfer (grub_usb_controller_t dev, /* Place the QH back in the free list and deallocate the associated TDs. */ cdata->qh->elinkptr = 1; - grub_free_queue (u, cdata->td_first, transfer, actual); + grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual); grub_free (cdata); return GRUB_USB_ERR_NONE; } @@ -595,7 +602,7 @@ grub_uhci_check_transfer (grub_usb_controller_t dev, /* Place the QH back in the free list and deallocate the associated TDs. */ cdata->qh->elinkptr = 1; - grub_free_queue (u, cdata->td_first, transfer, actual); + grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual); grub_free (cdata); return err; @@ -622,7 +629,7 @@ grub_uhci_cancel_transfer (grub_usb_controller_t dev, /* Place the QH back in the free list and deallocate the associated TDs. */ cdata->qh->elinkptr = 1; - grub_free_queue (u, cdata->td_first, transfer, &actual); + grub_free_queue (u, cdata->qh, cdata->td_first, transfer, &actual); grub_free (cdata); return GRUB_USB_ERR_NONE; From a98f88ecfeee316f6cdcb4df1002d66029103886 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Aug 2010 23:28:33 +0200 Subject: [PATCH 0096/1414] Add pot powered flag declaration --- include/grub/usbtrans.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 9e9d75e5d..5ee276d26 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -130,6 +130,7 @@ enum GRUB_USB_HUB_STATUS_PORT_ENABLED = (1 << 1), GRUB_USB_HUB_STATUS_PORT_SUSPEND = (1 << 2), GRUB_USB_HUB_STATUS_PORT_OVERCURRENT = (1 << 3), + GRUB_USB_HUB_STATUS_PORT_POWERED = (1 << 8), GRUB_USB_HUB_STATUS_PORT_LOWSPEED = (1 << 9), GRUB_USB_HUB_STATUS_PORT_HIGHSPEED = (1 << 10), GRUB_USB_HUB_STATUS_C_PORT_CONNECTED = (1 << 16), From ea9ed87faa8d90d112b2e648046c5a2b0cd27a00 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Aug 2010 18:52:17 +0200 Subject: [PATCH 0097/1414] add help descriptions to legacy commands --- commands/legacycfg.c | 168 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 137 insertions(+), 31 deletions(-) diff --git a/commands/legacycfg.c b/commands/legacycfg.c index 8077497f3..10e897226 100644 --- a/commands/legacycfg.c +++ b/commands/legacycfg.c @@ -48,65 +48,166 @@ struct legacy_command enum { FLAG_IGNORE_REST = 1 } flags; + const char *shortdesc; + const char *longdesc; }; struct legacy_command legacy_commands[] = { - {"blocklist", "blocklist '%s'\n", 1, {TYPE_FILE}, 0}, - {"boot", "boot\n", 0, {}, 0}, + {"blocklist", "blocklist '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Print the blocklist notation of the file FILE." + }, + {"boot", "boot\n", 0, {}, 0, 0, + "Boot the OS/chain-loader which has been loaded."}, /* bootp unsupported. */ - {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0}, + {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Print the contents of the file FILE."}, {"chainloader", "chainloader %s '%s'\n", 2, {TYPE_FORCE_OPTION, TYPE_FILE}, - 0}, - {"cmp", "cmp '%s' '%s'\n", 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST}, + 0, "[--force] FILE", + "Load the chain-loader FILE. If --force is specified, then load it" + " forcibly, whether the boot loader signature is present or not."}, + {"cmp", "cmp '%s' '%s'\n", 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, + "FILE1 FILE2", + "Compare the file FILE1 with the FILE2 and inform the different values" + " if any."}, /* FIXME: Implement command. */ {"color", "legacy_color '%s' '%s'\n", 2, {TYPE_VERBATIM, TYPE_VERBATIM}, - FLAG_IGNORE_REST}, - {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0}, + FLAG_IGNORE_REST, "NORMAL [HIGHLIGHT]", + "Change the menu colors. The color NORMAL is used for most" + " lines in the menu, and the color HIGHLIGHT is used to highlight the" + " line where the cursor points. If you omit HIGHLIGHT, then the" + " inverted color of NORMAL is used for the highlighted line." + " The format of a color is \"FG/BG\". FG and BG are symbolic color names." + " A symbolic color name must be one of these: black, blue, green," + " cyan, red, magenta, brown, light-gray, dark-gray, light-blue," + " light-green, light-cyan, light-red, light-magenta, yellow and white." + " But only the first eight names can be used for BG. You can prefix" + " \"blink-\" to FG if you want a blinking foreground color."}, + {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Load FILE as the configuration file."}, {"debug", "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", - 0, {}, 0}, - {"default", "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; set default=\"$saved_entry\"; fi\n", 1, {TYPE_VERBATIM}, 0}, + 0, {}, 0, 0, "Turn on/off the debug mode."}, + {"default", + "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; " + "set default=\"$saved_entry\"; fi\n", 1, {TYPE_VERBATIM}, 0, + "[NUM | `saved']", + "Set the default entry to entry number NUM (if not specified, it is" + " 0, the first entry) or the entry number saved by savedefault."}, /* dhcp unsupported. */ /* displayapm unsupported. */ - {"displaymem", "lsmmap\n", 0, {}, 0}, + {"displaymem", "lsmmap\n", 0, {}, 0, 0, + "Display what GRUB thinks the system address space map of the" + " machine is, including all regions of physical RAM installed."}, /* embed unsupported. */ - {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0}, - {"find", "search -f '%s'\n", 1, {TYPE_FILE}, 0}, + {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0, "NUM...", + "Go into unattended boot mode: if the default boot entry has any" + " errors, instead of waiting for the user to do anything, it" + " immediately starts over using the NUM entry (same numbering as the" + " `default' command). This obviously won't help if the machine" + " was rebooted by a kernel that GRUB loaded."}, + {"find", "search -f '%s'\n", 1, {TYPE_FILE}, 0, "FILENAME", + "Search for the filename FILENAME in all of partitions and print the list of" + " the devices which contain the file."}, /* fstest unsupported. */ /* geometry unsupported. */ - {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0}, + {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", + "Halt your system. If APM is available on it, turn off the power using" + " the APM BIOS, unless you specify the option `--no-apm'."}, /* help unsupported. */ /* NUL_TERMINATE */ /* hiddenmenu unsupported. */ - {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0}, + {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", + "Hide PARTITION by setting the \"hidden\" bit in" + " its partition type code."}, /* ifconfig unsupported. */ /* impsprobe unsupported. */ /* FIXME: Implement command. */ - {"initrd", "legacy_initrd '%s'\n", 1, {TYPE_FILE}, 0}, + {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, + "FILE [ARG ...]", + "Load an initial ramdisk FILE for a Linux format boot image and set the" + " appropriate parameters in the Linux setup area in memory."}, /* install unsupported. */ /* ioprobe unsupported. */ /* FIXME: implement command. */ - {"kernel", "legacy_kernel %s '%s' %s\n", 3, {TYPE_TYPE_OPTION, TYPE_FILE, - TYPE_REST_VERBATIM}, 0}, + {"kernel", "legacy_kernel %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_FILE, + TYPE_REST_VERBATIM}, 0, + "[--no-mem-option] [--type=TYPE] FILE [ARG ...]", + "Attempt to load the primary boot image from FILE. The rest of the" + " line is passed verbatim as the \"kernel command line\". Any modules" + " must be reloaded after using this command. The option --type is used" + " to suggest what type of kernel to be loaded. TYPE must be either of" + " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" + " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" + " Linux's mem option automatically."}, /* lock is handled separately. */ - {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0}, + {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0, 0 + "Set the active partition on the root disk to GRUB's root device." + " This command is limited to _primary_ PC partitions on a hard disk."}, {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, - FLAG_IGNORE_REST}, + FLAG_IGNORE_REST, "TO_DRIVE FROM_DRIVE", + "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" + " when you chain-load some operating systems, such as DOS, if such an" + " OS resides at a non-first drive."}, /* md5crypt unsupported. */ - {"module", "legacy_initrd '%s'\n", 1, {TYPE_FILE}, 0}, + {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, + "FILE [ARG ...]", + "Load a boot module FILE for a Multiboot format boot image (no" + " interpretation of the file contents is made, so users of this" + " command must know what the kernel in question expects). The" + " rest of the line is passed as the \"module command line\", like" + " the `kernel' command."}, /* modulenounzip unsupported. */ - {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0}, + /* FIXME: allow toggle. */ + {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0, "[FLAG]", + "Toggle pager mode with no argument. If FLAG is given and its value" + " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, /* partnew unsupported. */ - {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0}, + {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, + "PART TYPE", "Change the type of the partition PART to TYPE."}, /* password unsupported. */ /* NUL_TERMINATE */ /* pause unsupported. */ /* rarp unsupported. */ - {"read", "read_dword %s\n", 1, {TYPE_INT}, 0}, - {"reboot", "reboot\n", 0, {}, 0}, - {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0}, - {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0}, - {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0}, - {"serial", "serial %s\n", 1, {TYPE_REST_VERBATIM}, 0}, + {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", + "Read a 32-bit value from memory at address ADDR and" + " display it in hex format."}, + {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, + /* FIXME: Support HDBIAS. */ + {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, "[DEVICE [HDBIAS]]", + "Set the current \"root device\" to the device DEVICE, then" + " attempt to mount it to get the partition size (for passing the" + " partition descriptor in `ES:ESI', used by some chain-loaded" + " bootloaders), the BSD drive-type (for booting BSD kernels using" + " their native boot format), and correctly determine " + " the PC partition where a BSD sub-partition is located. The" + " optional HDBIAS parameter is a number to tell a BSD kernel" + " how many BIOS drive numbers are on controllers before the current" + " one. For example, if there is an IDE disk and a SCSI disk, and your" + " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, + {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, + "[DEVICE [HDBIAS]]", + "Similar to `root', but don't attempt to mount the partition. This" + " is useful for when an OS is outside of the area of the disk that" + " GRUB can read, but setting the correct root device is still" + " desired. Note that the items mentioned in `root' which" + " derived from attempting the mount will NOT work correctly."}, + /* FIXME: support arguments. */ + {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0, + "[NUM | `fallback']", + "Save the current entry as the default boot entry if no argument is" + " specified. If a number is specified, this number is saved. If" + " `fallback' is used, next fallback entry is saved."}, + {"serial", "serial %s\n", 1, {TYPE_REST_VERBATIM}, 0, + "[--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] " + "[--parity=PARITY] [--stop=STOP] [--device=DEV]", + "Initialize a serial device. UNIT is a digit that specifies which serial" + " device is used (e.g. 0 == COM1). If you need to specify the port number," + " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length," + " PARITY is the type of parity, which is one of `no', `odd' and `even'." + " STOP is the length of stop bit(s). The option --device can be used only" + " in the grub shell, which specifies the file name of a tty device. The" + " default values are COM1, 9600, 8N1."}, /* setkey unsupported. */ /* NUL_TERMINATE */ /* setup unsupported. */ /* terminal unsupported. */ /* NUL_TERMINATE */ @@ -114,11 +215,16 @@ struct legacy_command legacy_commands[] = /* testload unsupported. */ /* testvbe unsupported. */ /* tftpserver unsupported. */ - {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0}, + {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", + "Set a timeout, in SEC seconds, before automatically booting the" + " default entry (normally the first entry defined)."}, /* title is handled separately. */ - {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0}, + {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0, "PARTITION", + "Unhide PARTITION by clearing the \"hidden\" bit in its" + " partition type code."}, /* uppermem unsupported. */ - {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0}, + {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0, "UUID", + "Find root by UUID"}, /* vbeprobe unsupported. */ }; From fff175c77f6490ace62df776660c7c75ea526775 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Aug 2010 20:04:49 +0200 Subject: [PATCH 0098/1414] Implement grub-menulst2cfg and fix many bugs in legacy_parser --- Makefile.util.def | 9 + grub-core/Makefile.core.def | 3 +- grub-core/commands/legacycfg.c | 470 +------------------------------ grub-core/lib/legacy_parse.c | 496 +++++++++++++++++++++++++++++++++ include/grub/legacy_parse.h | 27 ++ util/grub-menulst2cfg.c | 99 +++++++ 6 files changed, 636 insertions(+), 468 deletions(-) create mode 100644 grub-core/lib/legacy_parse.c create mode 100644 include/grub/legacy_parse.h create mode 100644 util/grub-menulst2cfg.c diff --git a/Makefile.util.def b/Makefile.util.def index fd3428e76..b4f9fc60e 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -508,3 +508,12 @@ program = { ldadd = libgrub.a; ldflags = '$(LIBDEVMAPPER)'; }; + +program = { + name = grub-menulst2cfg; + mansection = 1; + common = util/grub-menulst2cfg.c; + common = grub-core/lib/legacy_parse.c; + ldadd = libgrub.a; + ldflags = '$(LIBDEVMAPPER)'; +}; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 5ddb99fa6..0ca28eb19 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1407,5 +1407,6 @@ module = { module = { name = legacycfg; common = commands/legacycfg.c; + common = lib/legacy_parse.c; enable = i386_pc; -}; \ No newline at end of file +}; diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 772f48c15..4207531ec 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -28,472 +28,7 @@ #include #include #include - -struct legacy_command -{ - const char *name; - const char *map; - unsigned argc; - enum arg_type { - TYPE_VERBATIM, - TYPE_FORCE_OPTION, - TYPE_NOAPM_OPTION, - TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_FILE, - TYPE_PARTITION, - TYPE_BOOL, - TYPE_INT, - TYPE_REST_VERBATIM - } argt[4]; - enum { - FLAG_IGNORE_REST = 1 - } flags; - const char *shortdesc; - const char *longdesc; -}; - -struct legacy_command legacy_commands[] = - { - {"blocklist", "blocklist '%s'\n", 1, {TYPE_FILE}, 0, "FILE", - "Print the blocklist notation of the file FILE." - }, - {"boot", "boot\n", 0, {}, 0, 0, - "Boot the OS/chain-loader which has been loaded."}, - /* bootp unsupported. */ - {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", - "Print the contents of the file FILE."}, - {"chainloader", "chainloader %s '%s'\n", 2, {TYPE_FORCE_OPTION, TYPE_FILE}, - 0, "[--force] FILE", - "Load the chain-loader FILE. If --force is specified, then load it" - " forcibly, whether the boot loader signature is present or not."}, - {"cmp", "cmp '%s' '%s'\n", 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, - "FILE1 FILE2", - "Compare the file FILE1 with the FILE2 and inform the different values" - " if any."}, - /* FIXME: Implement command. */ - {"color", "legacy_color '%s' '%s'\n", 2, {TYPE_VERBATIM, TYPE_VERBATIM}, - FLAG_IGNORE_REST, "NORMAL [HIGHLIGHT]", - "Change the menu colors. The color NORMAL is used for most" - " lines in the menu, and the color HIGHLIGHT is used to highlight the" - " line where the cursor points. If you omit HIGHLIGHT, then the" - " inverted color of NORMAL is used for the highlighted line." - " The format of a color is \"FG/BG\". FG and BG are symbolic color names." - " A symbolic color name must be one of these: black, blue, green," - " cyan, red, magenta, brown, light-gray, dark-gray, light-blue," - " light-green, light-cyan, light-red, light-magenta, yellow and white." - " But only the first eight names can be used for BG. You can prefix" - " \"blink-\" to FG if you want a blinking foreground color."}, - {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0, "FILE", - "Load FILE as the configuration file."}, - {"debug", - "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", - 0, {}, 0, 0, "Turn on/off the debug mode."}, - {"default", - "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; " - "set default=\"$saved_entry\"; fi\n", 1, {TYPE_VERBATIM}, 0, - "[NUM | `saved']", - "Set the default entry to entry number NUM (if not specified, it is" - " 0, the first entry) or the entry number saved by savedefault."}, - /* dhcp unsupported. */ - /* displayapm unsupported. */ - {"displaymem", "lsmmap\n", 0, {}, 0, 0, - "Display what GRUB thinks the system address space map of the" - " machine is, including all regions of physical RAM installed."}, - /* embed unsupported. */ - {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0, "NUM...", - "Go into unattended boot mode: if the default boot entry has any" - " errors, instead of waiting for the user to do anything, it" - " immediately starts over using the NUM entry (same numbering as the" - " `default' command). This obviously won't help if the machine" - " was rebooted by a kernel that GRUB loaded."}, - {"find", "search -f '%s'\n", 1, {TYPE_FILE}, 0, "FILENAME", - "Search for the filename FILENAME in all of partitions and print the list of" - " the devices which contain the file."}, - /* fstest unsupported. */ - /* geometry unsupported. */ - {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", - "Halt your system. If APM is available on it, turn off the power using" - " the APM BIOS, unless you specify the option `--no-apm'."}, - /* help unsupported. */ /* NUL_TERMINATE */ - /* hiddenmenu unsupported. */ - {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", - "Hide PARTITION by setting the \"hidden\" bit in" - " its partition type code."}, - /* ifconfig unsupported. */ - /* impsprobe unsupported. */ - /* FIXME: Implement command. */ - {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, - "FILE [ARG ...]", - "Load an initial ramdisk FILE for a Linux format boot image and set the" - " appropriate parameters in the Linux setup area in memory."}, - /* install unsupported. */ - /* ioprobe unsupported. */ - /* FIXME: implement command. */ - {"kernel", "legacy_kernel %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_FILE, - TYPE_REST_VERBATIM}, 0, - "[--no-mem-option] [--type=TYPE] FILE [ARG ...]", - "Attempt to load the primary boot image from FILE. The rest of the" - " line is passed verbatim as the \"kernel command line\". Any modules" - " must be reloaded after using this command. The option --type is used" - " to suggest what type of kernel to be loaded. TYPE must be either of" - " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" - " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" - " Linux's mem option automatically."}, - /* lock is handled separately. */ - {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0, 0, - "Set the active partition on the root disk to GRUB's root device." - " This command is limited to _primary_ PC partitions on a hard disk."}, - {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, - FLAG_IGNORE_REST, "TO_DRIVE FROM_DRIVE", - "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" - " when you chain-load some operating systems, such as DOS, if such an" - " OS resides at a non-first drive."}, - /* md5crypt unsupported. */ - {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, - "FILE [ARG ...]", - "Load a boot module FILE for a Multiboot format boot image (no" - " interpretation of the file contents is made, so users of this" - " command must know what the kernel in question expects). The" - " rest of the line is passed as the \"module command line\", like" - " the `kernel' command."}, - /* modulenounzip unsupported. */ - /* FIXME: allow toggle. */ - {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0, "[FLAG]", - "Toggle pager mode with no argument. If FLAG is given and its value" - " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, - /* partnew unsupported. */ - {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, - "PART TYPE", "Change the type of the partition PART to TYPE."}, - /* password unsupported. */ /* NUL_TERMINATE */ - /* pause unsupported. */ - /* rarp unsupported. */ - {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", - "Read a 32-bit value from memory at address ADDR and" - " display it in hex format."}, - {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, - /* FIXME: Support HDBIAS. */ - {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, "[DEVICE [HDBIAS]]", - "Set the current \"root device\" to the device DEVICE, then" - " attempt to mount it to get the partition size (for passing the" - " partition descriptor in `ES:ESI', used by some chain-loaded" - " bootloaders), the BSD drive-type (for booting BSD kernels using" - " their native boot format), and correctly determine " - " the PC partition where a BSD sub-partition is located. The" - " optional HDBIAS parameter is a number to tell a BSD kernel" - " how many BIOS drive numbers are on controllers before the current" - " one. For example, if there is an IDE disk and a SCSI disk, and your" - " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, - {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, - "[DEVICE [HDBIAS]]", - "Similar to `root', but don't attempt to mount the partition. This" - " is useful for when an OS is outside of the area of the disk that" - " GRUB can read, but setting the correct root device is still" - " desired. Note that the items mentioned in `root' which" - " derived from attempting the mount will NOT work correctly."}, - /* FIXME: support arguments. */ - {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0, - "[NUM | `fallback']", - "Save the current entry as the default boot entry if no argument is" - " specified. If a number is specified, this number is saved. If" - " `fallback' is used, next fallback entry is saved."}, - {"serial", "serial %s\n", 1, {TYPE_REST_VERBATIM}, 0, - "[--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] " - "[--parity=PARITY] [--stop=STOP] [--device=DEV]", - "Initialize a serial device. UNIT is a digit that specifies which serial" - " device is used (e.g. 0 == COM1). If you need to specify the port number," - " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length," - " PARITY is the type of parity, which is one of `no', `odd' and `even'." - " STOP is the length of stop bit(s). The option --device can be used only" - " in the grub shell, which specifies the file name of a tty device. The" - " default values are COM1, 9600, 8N1."}, - /* setkey unsupported. */ /* NUL_TERMINATE */ - /* setup unsupported. */ - /* terminal unsupported. */ /* NUL_TERMINATE */ - /* terminfo unsupported. */ /* NUL_TERMINATE */ - /* testload unsupported. */ - /* testvbe unsupported. */ - /* tftpserver unsupported. */ - {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", - "Set a timeout, in SEC seconds, before automatically booting the" - " default entry (normally the first entry defined)."}, - /* title is handled separately. */ - {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0, "PARTITION", - "Unhide PARTITION by clearing the \"hidden\" bit in its" - " partition type code."}, - /* uppermem unsupported. */ - {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0, "UUID", - "Find root by UUID"}, - /* vbeprobe unsupported. */ - }; - -static char * -escape (const char *in) -{ - const char *ptr; - char *ret, *outptr; - int overhead = 0; - for (ptr = in; *ptr; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; - ret = grub_malloc (ptr - in + overhead); - if (!ret) - return NULL; - outptr = ret; - for (ptr = in; *ptr; ptr++) - { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; - - *outptr++ = *ptr; - } - *outptr++ = 0; - return ret; -} - -static char * -adjust_file (const char *in) -{ - const char *comma, *ptr, *rest; - char *ret, *outptr; - int overhead = 0; - int part; - if (in[0] != '(') - return escape (in); - for (ptr = in + 1; *ptr && *ptr != ')' && *ptr != ','; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; - comma = ptr; - if (*comma != ',') - return escape (in); - part = grub_strtoull (comma + 1, (char **) &rest, 0); - for (ptr = rest; *ptr; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; - - /* 30 is enough for any number. */ - ret = grub_malloc (ptr - in + overhead + 30); - if (!ret) - return NULL; - - outptr = ret; - for (ptr = in; ptr <= comma; ptr++) - { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; - - *outptr++ = *ptr; - } - grub_snprintf (outptr, 30, "%d", part + 1); - while (*outptr) - outptr++; - for (ptr = rest; ptr <= comma; ptr++) - { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; - - *outptr++ = *ptr; - } - return ret; -} - -static int -is_option (enum arg_type opt, const char *curarg) -{ - switch (opt) - { - case TYPE_NOAPM_OPTION: - return grub_strcmp (curarg, "--no-apm") == 0; - case TYPE_FORCE_OPTION: - return grub_strcmp (curarg, "--force") == 0; - case TYPE_TYPE_OR_NOMEM_OPTION: - return grub_strcmp (curarg, "--type=netbsd") == 0 - || grub_strcmp (curarg, "--type=freebsd") == 0 - || grub_strcmp (curarg, "--type=openbsd") == 0 - || grub_strcmp (curarg, "--type=linux") == 0 - || grub_strcmp (curarg, "--type=biglinux") == 0 - || grub_strcmp (curarg, "--type=multiboot") == 0 - || grub_strcmp (curarg, "--no-mem-option") == 0; - default: - return 0; - } -} - -static char * -legacy_parse (char *buf, char **entryname) -{ - char *ptr; - char *cmdname; - unsigned i, cmdnum; - - for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); - if ((!*ptr || *ptr == '#') && entryname && *entryname) - { - char *ret = grub_xasprintf ("%s\n", buf); - grub_free (buf); - return ret; - } - if (!*ptr || *ptr == '#') - { - grub_free (buf); - return NULL; - } - - cmdname = ptr; - for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); - - if (entryname && grub_strncmp ("title", cmdname, ptr - cmdname) == 0 - && ptr - cmdname == sizeof ("title") - 1) - { - for (; grub_isspace (*ptr) || *ptr == '='; ptr++); - *entryname = grub_strdup (ptr); - grub_free (buf); - return NULL; - } - - if (grub_strncmp ("lock", cmdname, ptr - cmdname) == 0 - && ptr - cmdname == sizeof ("lock") - 1) - { - /* FIXME */ - } - - for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) - if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 - && legacy_commands[cmdnum].name[ptr - cmdname] == 0) - break; - if (cmdnum == ARRAY_SIZE (legacy_commands)) - return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); - - for (; grub_isspace (*ptr) || *ptr == '='; ptr++); - - char *args[ARRAY_SIZE (legacy_commands[0].argt)]; - memset (args, 0, sizeof (args)); - - { - unsigned j = 0; - for (i = 0; i < legacy_commands[cmdnum].argc; i++) - { - char *curarg, *cptr = NULL, c = 0; - for (; grub_isspace (*ptr); ptr++); - curarg = ptr; - for (; !grub_isspace (*ptr); ptr++); - if (i != legacy_commands[cmdnum].argc - 1 - || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) - { - cptr = ptr; - c = *cptr; - *ptr = 0; - } - if (*ptr) - ptr++; - switch (legacy_commands[cmdnum].argt[i]) - { - case TYPE_PARTITION: - case TYPE_FILE: - args[j++] = adjust_file (curarg); - break; - - case TYPE_REST_VERBATIM: - { - char *outptr, *outptr0; - int overhead = 3; - ptr = curarg; - while (*ptr) - { - for (; grub_isspace (*ptr); ptr++); - for (; *ptr && !grub_isspace (*ptr); ptr++) - if (*ptr == '\\' || *ptr == '\'') - overhead++; - if (*ptr) - ptr++; - overhead += 3; - } - outptr0 = args[j++] = grub_malloc (overhead + (ptr - curarg)); - if (!outptr0) - { - grub_free (buf); - return NULL; - } - ptr = curarg; - outptr = outptr0; - while (*ptr) - { - for (; grub_isspace (*ptr); ptr++); - if (outptr != outptr0) - *outptr++ = ' '; - *outptr++ = '\''; - for (; *ptr && !grub_isspace (*ptr); ptr++) - { - if (*ptr == '\\' || *ptr == '\'') - *outptr++ = '\\'; - *outptr++ = *ptr; - } - *outptr++ = '\''; - if (*ptr) - ptr++; - overhead += 3; - } - *outptr++ = 0; - } - break; - - case TYPE_VERBATIM: - args[j++] = escape (curarg); - break; - case TYPE_FORCE_OPTION: - case TYPE_NOAPM_OPTION: - case TYPE_TYPE_OR_NOMEM_OPTION: - if (is_option (legacy_commands[cmdnum].argt[i], curarg)) - { - args[j++] = grub_strdup (curarg); - break; - } - if (cptr) - *cptr = c; - ptr = curarg; - args[j++] = ""; - break; - case TYPE_INT: - { - char *brk; - int base = 10; - brk = curarg; - if (brk[0] == '0' && brk[1] == 'x') - base = 16; - else if (brk[0] == '0') - base = 8; - for (; *brk; brk++) - { - if (base == 8 && (*brk == '8' || *brk == '9')) - break; - if (grub_isdigit (*brk)) - continue; - if (base != 16) - break; - if (!(*brk >= 'a' && *brk <= 'f') - && !(*brk >= 'A' && *brk <= 'F')) - break; - } - if (brk == curarg) - args[j++] = grub_strdup ("0"); - else - args[j++] = grub_strndup (curarg, brk - curarg); - } - break; - case TYPE_BOOL: - if (curarg[0] == 'o' && curarg[1] == 'n' - && (curarg[2] == 0 || grub_isspace (curarg[2]))) - args[j++] = grub_strdup ("1"); - else - args[j++] = grub_strdup ("0"); - break; - } - } - } - grub_free (buf); - return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2]); -} +#include static grub_err_t legacy_file (const char *filename) @@ -534,7 +69,8 @@ legacy_file (const char *filename) char *oldname = NULL; oldname = entryname; - parsed = legacy_parse (buf, &entryname); + parsed = grub_legacy_parse (buf, &entryname); + grub_free (buf); if (oldname != entryname && oldname) { const char **args = grub_malloc (sizeof (args[0])); diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c new file mode 100644 index 000000000..0b30ef3b1 --- /dev/null +++ b/grub-core/lib/legacy_parse.c @@ -0,0 +1,496 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,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 + +struct legacy_command +{ + const char *name; + const char *map; + unsigned argc; + enum arg_type { + TYPE_VERBATIM, + TYPE_FORCE_OPTION, + TYPE_NOAPM_OPTION, + TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_FILE, + TYPE_PARTITION, + TYPE_BOOL, + TYPE_INT, + TYPE_REST_VERBATIM + } argt[4]; + enum { + FLAG_IGNORE_REST = 1 + } flags; + const char *shortdesc; + const char *longdesc; +}; + +struct legacy_command legacy_commands[] = + { + {"blocklist", "blocklist '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Print the blocklist notation of the file FILE."}, + {"boot", "boot\n", 0, {}, 0, 0, + "Boot the OS/chain-loader which has been loaded."}, + /* bootp unsupported. */ + {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Print the contents of the file FILE."}, + {"chainloader", "chainloader %s '%s'\n", 2, {TYPE_FORCE_OPTION, TYPE_FILE}, + 0, "[--force] FILE", + "Load the chain-loader FILE. If --force is specified, then load it" + " forcibly, whether the boot loader signature is present or not."}, + {"cmp", "cmp '%s' '%s'\n", 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, + "FILE1 FILE2", + "Compare the file FILE1 with the FILE2 and inform the different values" + " if any."}, + /* FIXME: Implement command. */ + {"color", "legacy_color '%s' '%s'\n", 2, {TYPE_VERBATIM, TYPE_VERBATIM}, + FLAG_IGNORE_REST, "NORMAL [HIGHLIGHT]", + "Change the menu colors. The color NORMAL is used for most" + " lines in the menu, and the color HIGHLIGHT is used to highlight the" + " line where the cursor points. If you omit HIGHLIGHT, then the" + " inverted color of NORMAL is used for the highlighted line." + " The format of a color is \"FG/BG\". FG and BG are symbolic color names." + " A symbolic color name must be one of these: black, blue, green," + " cyan, red, magenta, brown, light-gray, dark-gray, light-blue," + " light-green, light-cyan, light-red, light-magenta, yellow and white." + " But only the first eight names can be used for BG. You can prefix" + " \"blink-\" to FG if you want a blinking foreground color."}, + {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Load FILE as the configuration file."}, + {"debug", + "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", + 0, {}, 0, 0, "Turn on/off the debug mode."}, + {"default", + "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; " + "set default=\"$saved_entry\"; fi\n", 1, {TYPE_VERBATIM}, 0, + "[NUM | `saved']", + "Set the default entry to entry number NUM (if not specified, it is" + " 0, the first entry) or the entry number saved by savedefault."}, + /* dhcp unsupported. */ + /* displayapm unsupported. */ + {"displaymem", "lsmmap\n", 0, {}, 0, 0, + "Display what GRUB thinks the system address space map of the" + " machine is, including all regions of physical RAM installed."}, + /* embed unsupported. */ + {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0, "NUM...", + "Go into unattended boot mode: if the default boot entry has any" + " errors, instead of waiting for the user to do anything, it" + " immediately starts over using the NUM entry (same numbering as the" + " `default' command). This obviously won't help if the machine" + " was rebooted by a kernel that GRUB loaded."}, + {"find", "search -sf '%s'\n", 1, {TYPE_FILE}, 0, "FILENAME", + "Search for the filename FILENAME in all of partitions and print the list of" + " the devices which contain the file."}, + /* fstest unsupported. */ + /* geometry unsupported. */ + {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", + "Halt your system. If APM is available on it, turn off the power using" + " the APM BIOS, unless you specify the option `--no-apm'."}, + /* help unsupported. */ /* NUL_TERMINATE */ + /* hiddenmenu unsupported. */ + {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", + "Hide PARTITION by setting the \"hidden\" bit in" + " its partition type code."}, + /* ifconfig unsupported. */ + /* impsprobe unsupported. */ + /* FIXME: Implement command. */ + {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, + "FILE [ARG ...]", + "Load an initial ramdisk FILE for a Linux format boot image and set the" + " appropriate parameters in the Linux setup area in memory."}, + /* install unsupported. */ + /* ioprobe unsupported. */ + /* FIXME: implement command. */ + {"kernel", "legacy_kernel %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_FILE, + TYPE_REST_VERBATIM}, 0, + "[--no-mem-option] [--type=TYPE] FILE [ARG ...]", + "Attempt to load the primary boot image from FILE. The rest of the" + " line is passed verbatim as the \"kernel command line\". Any modules" + " must be reloaded after using this command. The option --type is used" + " to suggest what type of kernel to be loaded. TYPE must be either of" + " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" + " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" + " Linux's mem option automatically."}, + /* lock is handled separately. */ + {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0, 0, + "Set the active partition on the root disk to GRUB's root device." + " This command is limited to _primary_ PC partitions on a hard disk."}, + {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, + FLAG_IGNORE_REST, "TO_DRIVE FROM_DRIVE", + "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" + " when you chain-load some operating systems, such as DOS, if such an" + " OS resides at a non-first drive."}, + /* md5crypt unsupported. */ + {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, + "FILE [ARG ...]", + "Load a boot module FILE for a Multiboot format boot image (no" + " interpretation of the file contents is made, so users of this" + " command must know what the kernel in question expects). The" + " rest of the line is passed as the \"module command line\", like" + " the `kernel' command."}, + /* modulenounzip unsupported. */ + /* FIXME: allow toggle. */ + {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0, "[FLAG]", + "Toggle pager mode with no argument. If FLAG is given and its value" + " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, + /* partnew unsupported. */ + {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, + "PART TYPE", "Change the type of the partition PART to TYPE."}, + /* password unsupported. */ /* NUL_TERMINATE */ + /* pause unsupported. */ + /* rarp unsupported. */ + {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", + "Read a 32-bit value from memory at address ADDR and" + " display it in hex format."}, + {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, + /* FIXME: Support HDBIAS. */ + /* FIXME: Support printing. */ + {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, "[DEVICE [HDBIAS]]", + "Set the current \"root device\" to the device DEVICE, then" + " attempt to mount it to get the partition size (for passing the" + " partition descriptor in `ES:ESI', used by some chain-loaded" + " bootloaders), the BSD drive-type (for booting BSD kernels using" + " their native boot format), and correctly determine " + " the PC partition where a BSD sub-partition is located. The" + " optional HDBIAS parameter is a number to tell a BSD kernel" + " how many BIOS drive numbers are on controllers before the current" + " one. For example, if there is an IDE disk and a SCSI disk, and your" + " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, + {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, + "[DEVICE [HDBIAS]]", + "Similar to `root', but don't attempt to mount the partition. This" + " is useful for when an OS is outside of the area of the disk that" + " GRUB can read, but setting the correct root device is still" + " desired. Note that the items mentioned in `root' which" + " derived from attempting the mount will NOT work correctly."}, + /* FIXME: support arguments. */ + {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0, + "[NUM | `fallback']", + "Save the current entry as the default boot entry if no argument is" + " specified. If a number is specified, this number is saved. If" + " `fallback' is used, next fallback entry is saved."}, + {"serial", "serial %s\n", 1, {TYPE_REST_VERBATIM}, 0, + "[--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] " + "[--parity=PARITY] [--stop=STOP] [--device=DEV]", + "Initialize a serial device. UNIT is a digit that specifies which serial" + " device is used (e.g. 0 == COM1). If you need to specify the port number," + " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length," + " PARITY is the type of parity, which is one of `no', `odd' and `even'." + " STOP is the length of stop bit(s). The option --device can be used only" + " in the grub shell, which specifies the file name of a tty device. The" + " default values are COM1, 9600, 8N1."}, + /* setkey unsupported. */ /* NUL_TERMINATE */ + /* setup unsupported. */ + /* terminal unsupported. */ /* NUL_TERMINATE */ + /* terminfo unsupported. */ /* NUL_TERMINATE */ + /* testload unsupported. */ + /* testvbe unsupported. */ + /* tftpserver unsupported. */ + {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", + "Set a timeout, in SEC seconds, before automatically booting the" + " default entry (normally the first entry defined)."}, + /* title is handled separately. */ + {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0, "PARTITION", + "Unhide PARTITION by clearing the \"hidden\" bit in its" + " partition type code."}, + /* uppermem unsupported. */ + {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0, "UUID", + "Find root by UUID"}, + /* vbeprobe unsupported. */ + }; + +char * +grub_legacy_escape (const char *in, grub_size_t len) +{ + const char *ptr; + char *ret, *outptr; + int overhead = 0; + for (ptr = in; ptr < in + len && *ptr; ptr++) + if (*ptr == '\'' || *ptr == '\\') + overhead++; + ret = grub_malloc (ptr - in + overhead); + if (!ret) + return NULL; + outptr = ret; + for (ptr = in; ptr < in + len && *ptr; ptr++) + { + if (*ptr == '\'' || *ptr == '\\') + *outptr++ = '\\'; + + *outptr++ = *ptr; + } + *outptr++ = 0; + return ret; +} + +static char * +adjust_file (const char *in, grub_size_t len) +{ + const char *comma, *ptr, *rest; + char *ret, *outptr; + int overhead = 0; + int part; + if (in[0] != '(') + return grub_legacy_escape (in, len); + for (ptr = in + 1; ptr < in + len && *ptr && *ptr != ')' + && *ptr != ','; ptr++) + if (*ptr == '\'' || *ptr == '\\') + overhead++; + comma = ptr; + if (*comma != ',') + return grub_legacy_escape (in, len); + part = grub_strtoull (comma + 1, (char **) &rest, 0); + for (ptr = rest; ptr < in + len && *ptr; ptr++) + if (*ptr == '\'' || *ptr == '\\') + overhead++; + + /* 30 is enough for any number. */ + ret = grub_malloc (ptr - in + overhead + 30); + if (!ret) + return NULL; + + outptr = ret; + for (ptr = in; ptr < in + len && ptr <= comma; ptr++) + { + if (*ptr == '\'' || *ptr == '\\') + *outptr++ = '\\'; + + *outptr++ = *ptr; + } + grub_snprintf (outptr, 30, "%d", part + 1); + while (*outptr) + outptr++; + for (ptr = rest; ptr < in + len; ptr++) + { + if (*ptr == '\'' || *ptr == '\\') + *outptr++ = '\\'; + + *outptr++ = *ptr; + } + return ret; +} + +static int +check_option (const char *a, char *b, grub_size_t len) +{ + if (grub_strlen (b) != len) + return 0; + return grub_strncmp (a, b, len) == 0; +} + +static int +is_option (enum arg_type opt, const char *curarg, grub_size_t len) +{ + switch (opt) + { + case TYPE_NOAPM_OPTION: + return check_option (curarg, "--no-apm", len); + case TYPE_FORCE_OPTION: + return check_option (curarg, "--force", len); + case TYPE_TYPE_OR_NOMEM_OPTION: + return check_option (curarg, "--type=netbsd", len) + || check_option (curarg, "--type=freebsd", len) + || check_option (curarg, "--type=openbsd", len) + || check_option (curarg, "--type=linux", len) + || check_option (curarg, "--type=biglinux", len) + || check_option (curarg, "--type=multiboot", len) + || check_option (curarg, "--no-mem-option", len); + default: + return 0; + } +} + +char * +grub_legacy_parse (const char *buf, char **entryname) +{ + const char *ptr; + const char *cmdname; + unsigned i, cmdnum; + + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); + if (!*ptr || *ptr == '#') + return grub_strdup (buf); + + cmdname = ptr; + for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); + + if (entryname && grub_strncmp ("title", cmdname, ptr - cmdname) == 0 + && ptr - cmdname == sizeof ("title") - 1) + { + const char *ptr2; + for (; grub_isspace (*ptr) || *ptr == '='; ptr++); + ptr2 = ptr + grub_strlen (ptr); + while (ptr2 > ptr && grub_isspace (*(ptr2 - 1))) + ptr2--; + *entryname = grub_strndup (ptr, ptr2 - ptr); + return NULL; + } + + if (grub_strncmp ("lock", cmdname, ptr - cmdname) == 0 + && ptr - cmdname == sizeof ("lock") - 1) + { + /* FIXME */ + } + + for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) + if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 + && legacy_commands[cmdnum].name[ptr - cmdname] == 0) + break; + if (cmdnum == ARRAY_SIZE (legacy_commands)) + return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); + + for (; grub_isspace (*ptr) || *ptr == '='; ptr++); + + char *args[ARRAY_SIZE (legacy_commands[0].argt)]; + grub_memset (args, 0, sizeof (args)); + + { + unsigned j = 0; + int hold_arg = 0; + for (i = 0; i < legacy_commands[cmdnum].argc; i++) + { + const char *curarg; + grub_size_t curarglen; + if (hold_arg) + { + ptr = curarg; + hold_arg = 0; + } + for (; grub_isspace (*ptr); ptr++); + curarg = ptr; + for (; !grub_isspace (*ptr); ptr++); + if (i != legacy_commands[cmdnum].argc - 1 + || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) + curarglen = ptr - curarg; + else + { + curarglen = grub_strlen (curarg); + while (curarglen > 0 && grub_isspace (curarg[curarglen - 1])) + curarglen--; + } + if (*ptr) + ptr++; + switch (legacy_commands[cmdnum].argt[i]) + { + case TYPE_PARTITION: + case TYPE_FILE: + args[j++] = adjust_file (curarg, curarglen); + break; + + case TYPE_REST_VERBATIM: + { + char *outptr, *outptr0; + int overhead = 3; + ptr = curarg; + while (*ptr) + { + for (; grub_isspace (*ptr); ptr++); + for (; *ptr && !grub_isspace (*ptr); ptr++) + if (*ptr == '\\' || *ptr == '\'') + overhead++; + if (*ptr) + ptr++; + overhead += 3; + } + outptr0 = args[j++] = grub_malloc (overhead + (ptr - curarg)); + if (!outptr0) + return NULL; + ptr = curarg; + outptr = outptr0; + while (*ptr) + { + for (; grub_isspace (*ptr); ptr++); + if (outptr != outptr0) + *outptr++ = ' '; + *outptr++ = '\''; + for (; *ptr && !grub_isspace (*ptr); ptr++) + { + if (*ptr == '\\' || *ptr == '\'') + *outptr++ = '\\'; + *outptr++ = *ptr; + } + *outptr++ = '\''; + if (*ptr) + ptr++; + overhead += 3; + } + *outptr++ = 0; + } + break; + + case TYPE_VERBATIM: + args[j++] = grub_legacy_escape (curarg, curarglen); + break; + case TYPE_FORCE_OPTION: + case TYPE_NOAPM_OPTION: + case TYPE_TYPE_OR_NOMEM_OPTION: + if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen)) + { + args[j++] = grub_strndup (curarg, curarglen); + break; + } + args[j++] = ""; + hold_arg = 1; + break; + case TYPE_INT: + { + const char *brk; + int base = 10; + brk = curarg; + if (curarglen < 1) + args[j++] = grub_strdup ("0"); + if (brk[0] == '0' && brk[1] == 'x') + base = 16; + else if (brk[0] == '0') + base = 8; + for (; *brk && brk < curarg + curarglen; brk++) + { + if (base == 8 && (*brk == '8' || *brk == '9')) + break; + if (grub_isdigit (*brk)) + continue; + if (base != 16) + break; + if (!(*brk >= 'a' && *brk <= 'f') + && !(*brk >= 'A' && *brk <= 'F')) + break; + } + if (brk == curarg) + args[j++] = grub_strdup ("0"); + else + args[j++] = grub_strndup (curarg, brk - curarg); + } + break; + case TYPE_BOOL: + if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n') + args[j++] = grub_strdup ("1"); + else + args[j++] = grub_strdup ("0"); + break; + } + } + } + return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2]); +} diff --git a/include/grub/legacy_parse.h b/include/grub/legacy_parse.h new file mode 100644 index 000000000..fce4e3e40 --- /dev/null +++ b/include/grub/legacy_parse.h @@ -0,0 +1,27 @@ +/* + * 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_LEGACY_PARSE_HEADER +#define GRUB_LEGACY_PARSE_HEADER 1 + +#include + +char *grub_legacy_parse (const char *buf, char **entryname); +char *grub_legacy_escape (const char *in, grub_size_t len); + +#endif diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c new file mode 100644 index 000000000..fdbdda388 --- /dev/null +++ b/util/grub-menulst2cfg.c @@ -0,0 +1,99 @@ +/* + * 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 + +int +main (int argc, char **argv) +{ + FILE *in, *out; + char *entryname = NULL; + char *buf = NULL; + size_t bufsize = 0; + + if (argc >= 2 && argv[1][0] == '-') + { + fprintf (stderr, "Usage: %s [INFILE [OUTFILE]]\n", argv[0]); + return 0; + } + + if (argc >= 2) + { + in = fopen (argv[1], "r"); + if (!in) + { + fprintf (stderr, "Couldn't open %s for reading: %s\n", + argv[1], strerror (errno)); + return 1; + } + } + else + in = stdin; + + if (argc >= 3) + { + out = fopen (argv[2], "w"); + if (!out) + { + if (in != stdin) + fclose (in); + fprintf (stderr, "Couldn't open %s for writing: %s\n", + argv[2], strerror (errno)); + return 1; + } + } + else + out = stdout; + + while (1) + { + char *parsed; + + if (getline (&buf, &bufsize, in) < 0) + break; + + { + char *oldname = NULL; + + oldname = entryname; + parsed = grub_legacy_parse (buf, &entryname); + if (oldname != entryname && oldname) + fprintf (out, "}\n\n"); + if (oldname != entryname) + fprintf (out, "menuentry \'%s\' {\n", + grub_legacy_escape (entryname, grub_strlen (entryname))); + } + + if (parsed) + fprintf (out, "%s%s", entryname ? " " : "", parsed); + } + + if (entryname) + fprintf (out, "}\n\n"); + + + if (in != stdin) + fclose (in); + if (out != stdout) + fclose (out); + + return 0; +} From 661cf422317447e70016ae99d222cc3601bb3e23 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Aug 2010 20:23:39 +0200 Subject: [PATCH 0099/1414] Fix a problem with kernel command --- grub-core/lib/legacy_parse.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 0b30ef3b1..985a53733 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -121,7 +121,7 @@ struct legacy_command legacy_commands[] = /* install unsupported. */ /* ioprobe unsupported. */ /* FIXME: implement command. */ - {"kernel", "legacy_kernel %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, + {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, TYPE_FILE, TYPE_REST_VERBATIM}, 0, @@ -380,7 +380,7 @@ grub_legacy_parse (const char *buf, char **entryname) } for (; grub_isspace (*ptr); ptr++); curarg = ptr; - for (; !grub_isspace (*ptr); ptr++); + for (; *ptr && !grub_isspace (*ptr); ptr++); if (i != legacy_commands[cmdnum].argc - 1 || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) curarglen = ptr - curarg; @@ -406,7 +406,7 @@ grub_legacy_parse (const char *buf, char **entryname) ptr = curarg; while (*ptr) { - for (; grub_isspace (*ptr); ptr++); + for (; *ptr && grub_isspace (*ptr); ptr++); for (; *ptr && !grub_isspace (*ptr); ptr++) if (*ptr == '\\' || *ptr == '\'') overhead++; @@ -421,7 +421,7 @@ grub_legacy_parse (const char *buf, char **entryname) outptr = outptr0; while (*ptr) { - for (; grub_isspace (*ptr); ptr++); + for (; *ptr && grub_isspace (*ptr); ptr++); if (outptr != outptr0) *outptr++ = ' '; *outptr++ = '\''; @@ -434,7 +434,6 @@ grub_legacy_parse (const char *buf, char **entryname) *outptr++ = '\''; if (*ptr) ptr++; - overhead += 3; } *outptr++ = 0; } @@ -492,5 +491,7 @@ grub_legacy_parse (const char *buf, char **entryname) } } } - return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2]); + + return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2], + args[3]); } From 8fc6a271473ede7cdff29cbfab9558e9dbfd5597 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Aug 2010 21:27:26 +0200 Subject: [PATCH 0100/1414] Implement legacy_kernel and legacy_initrd commands --- grub-core/commands/legacycfg.c | 190 ++++++++++++++++++++++++++++++++- grub-core/lib/legacy_parse.c | 8 +- 2 files changed, 194 insertions(+), 4 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 4207531ec..ed02fd4f2 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -167,13 +167,199 @@ grub_cmd_legacy_configfile (struct grub_command *cmd __attribute__ ((unused)), return ret; } -static grub_command_t cmd_source, cmd_configfile; +static enum + { + GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD + } kernel_type; + +static grub_err_t +grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; + int no_mem_option = 0; + struct grub_command *cmd; + for (i = 0; i < 2; i++) + { + /* FIXME: really support this. */ + if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0) + { + no_mem_option = 1; + argc--; + args++; + continue; + } + + /* FIXME: what's the difference? */ + if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0 + || grub_strcmp (args[0], "--type=biglinux") == 0)) + { + kernel_type = LINUX; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0) + { + kernel_type = MULTIBOOT; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0) + { + kernel_type = KFREEBSD; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0) + { + kernel_type = KOPENBSD; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0) + { + kernel_type = KNETBSD; + argc--; + args++; + continue; + } + } + + if (!argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required"); + + do + { + /* First try Linux. */ + if (kernel_type == GUESS_IT || kernel_type == LINUX) + { + cmd = grub_command_find ("linux16"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = LINUX; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + + /* Then multiboot. */ + /* FIXME: dublicate multiboot filename. */ + if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT) + { + cmd = grub_command_find ("multiboot"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = MULTIBOOT; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + + /* k*BSD didn't really work well with grub-legacy. */ + if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) + { + cmd = grub_command_find ("kfreebsd"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = KFREEBSD; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + if (kernel_type == GUESS_IT || kernel_type == KNETBSD) + { + cmd = grub_command_find ("knetbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = KNETBSD; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + if (kernel_type == GUESS_IT || kernel_type == KOPENBSD) + { + cmd = grub_command_find ("kopenbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = KOPENBSD; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + } + while (0); + + return grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s\n", + args[0]); +} + +static grub_err_t +grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_command *cmd; + + if (kernel_type == LINUX) + { + cmd = grub_command_find ("initrd16"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "command initrd16 not found"); + + return cmd->func (cmd, argc, args); + } + if (kernel_type == MULTIBOOT) + { + /* FIXME: dublicate module filename. */ + cmd = grub_command_find ("module"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found"); + + return cmd->func (cmd, argc, args); + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no kernel with module support is loaded in legacy way"); +} + +static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; GRUB_MOD_INIT(legacycfg) { cmd_source = grub_register_command ("legacy_source", grub_cmd_legacy_source, N_("FILE"), N_("Parse legacy config")); + cmd_kernel = grub_register_command ("legacy_kernel", + grub_cmd_legacy_kernel, + N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"), + N_("Simulate grub-legacy kernel command")); + + cmd_initrd = grub_register_command ("legacy_initrd", + grub_cmd_legacy_initrd, + N_("FILE [ARG ...]"), + N_("Simulate grub-legacy initrd command")); cmd_configfile = grub_register_command ("legacy_configfile", grub_cmd_legacy_configfile, N_("FILE"), @@ -184,4 +370,6 @@ GRUB_MOD_FINI(legacycfg) { grub_unregister_command (cmd_source); grub_unregister_command (cmd_configfile); + grub_unregister_command (cmd_kernel); + grub_unregister_command (cmd_initrd); } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 985a53733..61952d35d 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -113,14 +113,16 @@ struct legacy_command legacy_commands[] = " its partition type code."}, /* ifconfig unsupported. */ /* impsprobe unsupported. */ - /* FIXME: Implement command. */ + /* FIXME: dublicate multiboot filename. */ {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "Load an initial ramdisk FILE for a Linux format boot image and set the" " appropriate parameters in the Linux setup area in memory."}, /* install unsupported. */ /* ioprobe unsupported. */ - /* FIXME: implement command. */ + /* FIXME: really support --no-mem-option. */ + /* FIXME: distinguish linux and biglinux. */ + /* FIXME: dublicate multiboot filename. */ {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, TYPE_FILE, @@ -133,7 +135,7 @@ struct legacy_command legacy_commands[] = " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" " Linux's mem option automatically."}, - /* lock is handled separately. */ + /* lock is unsupported. */ {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0, 0, "Set the active partition on the root disk to GRUB's root device." " This command is limited to _primary_ PC partitions on a hard disk."}, From 7ddbecf25fc97603da45d0783e5dec3372aa85b9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Aug 2010 22:09:09 +0200 Subject: [PATCH 0101/1414] implement legacy_color --- grub-core/commands/legacycfg.c | 39 ++++++++++++++++++++++++++++++++++ grub-core/lib/legacy_parse.c | 1 - 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index ed02fd4f2..db53f2c92 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -344,7 +344,41 @@ grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), "no kernel with module support is loaded in legacy way"); } +static grub_err_t +grub_cmd_legacy_color (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "color required"); + grub_env_set ("color_normal", args[0]); + if (argc >= 2) + grub_env_set ("color_highlight", args[1]); + else + { + char *slash = grub_strchr (args[0], '/'); + char *invert; + grub_size_t len; + + len = grub_strlen (args[0]); + if (!slash) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad color specification %s", + args[0]); + invert = grub_malloc (len + 1); + if (!invert) + return grub_errno; + grub_memcpy (invert, slash + 1, len - (slash - args[0]) - 1); + invert[len - (slash - args[0]) - 1] = '/'; + grub_memcpy (invert + len - (slash - args[0]), args[0], slash - args[0]); + invert[len] = 0; + grub_env_set ("color_highlight", invert); + grub_free (invert); + } + + return grub_errno; +} + static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; +static grub_command_t cmd_color; GRUB_MOD_INIT(legacycfg) { @@ -364,6 +398,10 @@ GRUB_MOD_INIT(legacycfg) grub_cmd_legacy_configfile, N_("FILE"), N_("Parse legacy config")); + cmd_color = grub_register_command ("legacy_color", + grub_cmd_legacy_color, + N_("NORMAL [HIGHLIGHT]"), + N_("Simulate grub-legacy color command")); } GRUB_MOD_FINI(legacycfg) @@ -372,4 +410,5 @@ GRUB_MOD_FINI(legacycfg) grub_unregister_command (cmd_configfile); grub_unregister_command (cmd_kernel); grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_color); } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 61952d35d..1c502187d 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -62,7 +62,6 @@ struct legacy_command legacy_commands[] = "FILE1 FILE2", "Compare the file FILE1 with the FILE2 and inform the different values" " if any."}, - /* FIXME: Implement command. */ {"color", "legacy_color '%s' '%s'\n", 2, {TYPE_VERBATIM, TYPE_VERBATIM}, FLAG_IGNORE_REST, "NORMAL [HIGHLIGHT]", "Change the menu colors. The color NORMAL is used for most" From 2a87d7d1b6ebf745cedc9284419dd13b5ae29770 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Aug 2010 22:34:25 +0200 Subject: [PATCH 0102/1414] Remove biglinux FIXME comment. It's a non-issue --- grub-core/commands/legacycfg.c | 2 +- grub-core/lib/legacy_parse.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index db53f2c92..aca6d1e1f 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -190,7 +190,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), continue; } - /* FIXME: what's the difference? */ + /* linux16 handles both zImages and bzImages. */ if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0 || grub_strcmp (args[0], "--type=biglinux") == 0)) { diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 1c502187d..f2d3dec0a 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -120,7 +120,6 @@ struct legacy_command legacy_commands[] = /* install unsupported. */ /* ioprobe unsupported. */ /* FIXME: really support --no-mem-option. */ - /* FIXME: distinguish linux and biglinux. */ /* FIXME: dublicate multiboot filename. */ {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, From a0bf9fc93013292c3e4c378d1d1bfedeca310b58 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 29 Aug 2010 10:38:46 +0530 Subject: [PATCH 0103/1414] remove per module lst files for creating fs.lst, command.lst, etc. --- conf/Makefile.common | 8 +--- gentpl.py | 33 +------------ grub-core/Makefile.am | 91 ++++++++++++++++++++++++------------ grub-core/gencmdlist.sh | 22 --------- grub-core/genfslist.sh | 26 ----------- grub-core/genhandlerlist.sh | 19 -------- grub-core/genpartmaplist.sh | 26 ----------- grub-core/genparttoollist.sh | 19 -------- grub-core/genterminallist.sh | 20 -------- grub-core/genvideolist.sh | 26 ----------- 10 files changed, 63 insertions(+), 227 deletions(-) delete mode 100644 grub-core/gencmdlist.sh delete mode 100644 grub-core/genfslist.sh delete mode 100644 grub-core/genhandlerlist.sh delete mode 100644 grub-core/genpartmaplist.sh delete mode 100644 grub-core/genparttoollist.sh delete mode 100644 grub-core/genterminallist.sh delete mode 100644 grub-core/genvideolist.sh diff --git a/conf/Makefile.common b/conf/Makefile.common index eb70f7f77..528fa418f 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -85,18 +85,12 @@ CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime # Define these variables to calm down automake -FS_FILES = +PP_FILES = DEF_FILES = UND_FILES = IMG_FILES = MOD_FILES = -VIDEO_FILES = MODULE_FILES = -HANDLER_FILES = -PARTMAP_FILES = -COMMAND_FILES = -PARTTOOL_FILES = -TERMINAL_FILES = KERNEL_HEADER_FILES = man_MANS = diff --git a/gentpl.py b/gentpl.py index 17bda02c6..783a425fa 100644 --- a/gentpl.py +++ b/gentpl.py @@ -290,17 +290,7 @@ def module(platform): r += gvar_add("platform_DATA", "[+ name +].mod") r += gvar_add("CLEANFILES", "def-[+ name +].lst und-[+ name +].lst mod-[+ name +].c mod-[+ name +].o [+ name +].mod") - r += gvar_add("COMMAND_FILES", "command-[+ name +].lst") - r += gvar_add("FS_FILES", "fs-[+ name +].lst") - r += gvar_add("VIDEO_FILES", "video-[+ name +].lst") - r += gvar_add("PARTMAP_FILES", "partmap-[+ name +].lst") - r += gvar_add("HANDLER_FILES", "handler-[+ name +].lst") - r += gvar_add("PARTTOOL_FILES", "parttool-[+ name +].lst") - r += gvar_add("TERMINAL_FILES", "terminal-[+ name +].lst") - r += gvar_add("CLEANFILES", "command-[+ name +].lst fs-[+ name +].lst") - r += gvar_add("CLEANFILES", "handler-[+ name +].lst terminal-[+ name +].lst") - r += gvar_add("CLEANFILES", "video-[+ name +].lst partmap-[+ name +].lst parttool-[+ name +].lst") - + r += gvar_add("PP_FILES", "[+ name +].pp") r += gvar_add("CLEANFILES", "[+ name +].pp") r += """ [+ name +].pp: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES) @@ -332,27 +322,6 @@ mod-[+ name +].o: mod-[+ name +].c if test ! -z '$(TARGET_OBJ2ELF)'; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \ $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; \ fi - -command-[+ name +].lst: [+ name +].pp $(srcdir)/gencmdlist.sh - cat $< | sh $(srcdir)/gencmdlist.sh [+ name +] > $@ || (rm -f $@; exit 1) - -fs-[+ name +].lst: [+ name +].pp $(srcdir)/genfslist.sh - cat $< | sh $(srcdir)/genfslist.sh [+ name +] > $@ || (rm -f $@; exit 1) - -video-[+ name +].lst: [+ name +].pp $(srcdir)/genvideolist.sh - cat $< | sh $(srcdir)/genvideolist.sh [+ name +] > $@ || (rm -f $@; exit 1) - -partmap-[+ name +].lst: [+ name +].pp $(srcdir)/genpartmaplist.sh - cat $< | sh $(srcdir)/genpartmaplist.sh [+ name +] > $@ || (rm -f $@; exit 1) - -parttool-[+ name +].lst: [+ name +].pp $(srcdir)/genparttoollist.sh - cat $< | sh $(srcdir)/genparttoollist.sh [+ name +] > $@ || (rm -f $@; exit 1) - -handler-[+ name +].lst: [+ name +].pp $(srcdir)/genhandlerlist.sh - cat $< | sh $(srcdir)/genhandlerlist.sh [+ name +] > $@ || (rm -f $@; exit 1) - -terminal-[+ name +].lst: [+ name +].pp $(srcdir)/genterminallist.sh - cat $< | sh $(srcdir)/genterminallist.sh [+ name +] > $@ || (rm -f $@; exit 1) """ return r diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 773803544..33f5db46e 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -256,56 +256,87 @@ grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MOD_FILES) CLEANFILES += grub_emu_init.c endif -# .lst files -platform_DATA += moddep.lst -platform_DATA += fs.lst -platform_DATA += command.lst -platform_DATA += partmap.lst -platform_DATA += handler.lst -platform_DATA += terminal.lst -platform_DATA += parttool.lst -platform_DATA += video.lst -platform_DATA += crypto.lst -CLEANFILES += moddep.lst -CLEANFILES += handler.lst -CLEANFILES += terminal.lst -CLEANFILES += parttool.lst -CLEANFILES += video.lst -CLEANFILES += crypto.lst +# List files -fs.lst: $(FS_FILES) - cat $^ /dev/null | sort | uniq > $@ +fs.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + if grep -v "^#" $$pp | grep '^ *grub_fs_register' >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += fs.lst CLEANFILES += fs.lst -command.lst: $(COMMAND_FILES) - cat $^ /dev/null | sort | uniq > $@ +command.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + grep -v "^#" $$pp | sed -n \ + -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ + -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}"; \ + done) | sort -u > $@ +platform_DATA += command.lst CLEANFILES += command.lst -partmap.lst: $(PARTMAP_FILES) - cat $^ /dev/null | sort | uniq > $@ +partmap.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + if grep -v "^#" $$pp | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += partmap.lst CLEANFILES += partmap.lst -handler.lst: $(HANDLER_FILES) - cat $^ /dev/null | sort | uniq > $@ +handler.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + grep -v "^#" $$pp | sed -n \ + -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $$b/;p;}"; \ + done) | sort -u > $@ +platform_DATA += handler.lst CLEANFILES += handler.lst -terminal.lst: $(TERMINAL_FILES) - cat $^ /dev/null | sort | uniq > $@ +terminal.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + grep -v "^#" $$pp | sed -n \ + -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}"; \ + done) | sort -u > $@ +platform_DATA += terminal.lst CLEANFILES += terminal.lst -parttool.lst: $(PARTTOOL_FILES) - cat $^ /dev/null | sort | uniq > $@ +parttool.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + grep -v "^#" $$pp | sed -n \ + -e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}"; \ + done) | sort -u > $@ +platform_DATA += parttool.lst CLEANFILES += parttool.lst -video.lst: $(VIDEO_FILES) - cat $^ /dev/null | sort | uniq > $@ +video.lst: $(PP_FILES) + (for pp in $^; do \ + b=`basename $$pp .pp`; \ + if grep -v "^#" $$pp | grep '^ *grub_video_register' >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += video.lst CLEANFILES += video.lst # but, crypto.lst is simply copied crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst cp $^ $@ +platform_DATA += crypto.lst CLEANFILES += crypto.lst +# .lst files +platform_DATA += moddep.lst +CLEANFILES += moddep.lst + # generate global module dependencies list moddep.lst: kernel_syms.lst genmoddep.awk $(DEF_FILES) $(UND_FILES) cat $(DEF_FILES) kernel_syms.lst /dev/null \ diff --git a/grub-core/gencmdlist.sh b/grub-core/gencmdlist.sh deleted file mode 100644 index ed5965f07..000000000 --- a/grub-core/gencmdlist.sh +++ /dev/null @@ -1,22 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2005,2009 Free Software Foundation, Inc. -# -# This gensymlist.sh is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect command names. - -module=$1 - -grep -v "^#" | sed -n \ - -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" \ - -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" \ - -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" - diff --git a/grub-core/genfslist.sh b/grub-core/genfslist.sh deleted file mode 100644 index 6fa7e927d..000000000 --- a/grub-core/genfslist.sh +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2005,2008 Free Software Foundation, Inc. -# -# This gensymlist.sh is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect fs names. - -module=$1 - -# Ignore kernel.mod. -if test $module = kernel; then - exit -fi - -# For now, this emits only a module name, if the module registers a filesystem. -if grep -v "^#" | grep '^ *grub_fs_register' >/dev/null 2>&1; then - echo $module -fi diff --git a/grub-core/genhandlerlist.sh b/grub-core/genhandlerlist.sh deleted file mode 100644 index e4cb0d9de..000000000 --- a/grub-core/genhandlerlist.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2009 Free Software Foundation, Inc. -# -# This script is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect command names. - -module=$1 - -grep -v "^#" | sed -n \ - -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}" diff --git a/grub-core/genpartmaplist.sh b/grub-core/genpartmaplist.sh deleted file mode 100644 index fceb0f869..000000000 --- a/grub-core/genpartmaplist.sh +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2005, 2008 Free Software Foundation, Inc. -# -# This script is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect partmap names. - -module=$1 - -# Ignore kernel.mod. -if test $module = kernel; then - exit -fi - -# For now, this emits only a module name, if the module registers a partition map. -if grep -v "^#" | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then - echo $module -fi diff --git a/grub-core/genparttoollist.sh b/grub-core/genparttoollist.sh deleted file mode 100644 index 48a0efe55..000000000 --- a/grub-core/genparttoollist.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2009 Free Software Foundation, Inc. -# -# This gensymlist.sh is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect parttool names. - -module=$1 - -grep -v "^#" | sed -n \ - -e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" diff --git a/grub-core/genterminallist.sh b/grub-core/genterminallist.sh deleted file mode 100644 index 60f5b9105..000000000 --- a/grub-core/genterminallist.sh +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2009,2010 Free Software Foundation, Inc. -# -# This script is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect command names. - -module=$1 - -grep -v "^#" | sed -n \ - -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \ - -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $module/;p;}" \ diff --git a/grub-core/genvideolist.sh b/grub-core/genvideolist.sh deleted file mode 100644 index b208fa25c..000000000 --- a/grub-core/genvideolist.sh +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2005,2008,2009 Free Software Foundation, Inc. -# -# This script is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Read source code from stdin and detect partmap names. - -module=$1 - -# Ignore video.mod. -if test $module = video; then - exit -fi - -# For now, this emits only a module name, if the module registers a partition map. -if grep -v "^#" | grep '^ *grub_video_register' >/dev/null 2>&1; then - echo $module -fi From 0d4552faca45fa403448fdb671a47adbaeb53d4d Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 29 Aug 2010 11:17:30 +0530 Subject: [PATCH 0104/1414] remove def-* and und-* list files --- conf/Makefile.common | 2 -- gentpl.py | 17 ++--------------- grub-core/Makefile.am | 21 ++++++++++++--------- grub-core/Makefile.core.def | 5 +++++ grub-core/genmoddep.awk | 34 +++++++++++++++++++--------------- grub-core/gensyminfo.sh.in | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 72 insertions(+), 41 deletions(-) create mode 100644 grub-core/gensyminfo.sh.in diff --git a/conf/Makefile.common b/conf/Makefile.common index 528fa418f..1cf5a4b72 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -86,8 +86,6 @@ CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime # Define these variables to calm down automake PP_FILES = -DEF_FILES = -UND_FILES = IMG_FILES = MOD_FILES = MODULE_FILES = diff --git a/gentpl.py b/gentpl.py index 783a425fa..b153452cd 100644 --- a/gentpl.py +++ b/gentpl.py @@ -284,8 +284,6 @@ def module(platform): r += gvar_add("BUILT_SOURCES", "$(nodist_" + cname() + "_SOURCES)") r += gvar_add("CLEANFILES", "$(nodist_" + cname() + "_SOURCES)") - r += gvar_add("DEF_FILES", "def-[+ name +].lst") - r += gvar_add("UND_FILES", "und-[+ name +].lst") r += gvar_add("MOD_FILES", "[+ name +].mod") r += gvar_add("platform_DATA", "[+ name +].mod") r += gvar_add("CLEANFILES", "def-[+ name +].lst und-[+ name +].lst mod-[+ name +].c mod-[+ name +].o [+ name +].mod") @@ -296,16 +294,6 @@ def module(platform): [+ name +].pp: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES) $(TARGET_CPP) -DGRUB_LST_GENERATOR $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@ || (rm -f $@; exit 1) -def-[+ name +].lst: [+ name +].module$(EXEEXT) - if test x$(USE_APPLE_CC_FIXES) = xyes; then \ - $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@; \ - else \ - $(NM) -g --defined-only -P -p $< | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@; \ - fi - -und-[+ name +].lst: [+ name +].module$(EXEEXT) - $(NM) -u -P -p $< | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@ - mod-[+ name +].c: [+ name +].module$(EXEEXT) moddep.lst genmodsrc.sh sh $(srcdir)/genmodsrc.sh [+ name +] moddep.lst > $@ || (rm -f $@; exit 1) @@ -448,9 +436,8 @@ def script(platform): r += "[+ IF mansection +]" + manpage() + "[+ ENDIF +]" r += "[+ ENDIF +]" - r += rule("[+ name +]", "$(top_builddir)/config.status " + platform_sources(platform), """ -$(top_builddir)/config.status --file=-:""" + platform_sources(platform) + """ \ - | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@ + r += rule("[+ name +]", platform_sources(platform) + " $(top_builddir)/config.status", """ +$(top_builddir)/config.status --file=-:$< | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@ chmod a+x [+ name +] """) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 33f5db46e..2f23f03b0 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -235,8 +235,8 @@ kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input if grep "^#define HAVE_ASM_USCORE" $(top_builddir)/config.h; then u="_"; else u=""; fi; \ cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$$u"'\1 kernel/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$$u"'\1 kernel/;p;}' \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined '"$$u"'kernel \1/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined '"$$u"' kernel \1/;p;}' \ | sort -u >$@ rm -f kernel_syms.input CLEANFILES += kernel_syms.lst @@ -333,15 +333,18 @@ crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst platform_DATA += crypto.lst CLEANFILES += crypto.lst -# .lst files -platform_DATA += moddep.lst -CLEANFILES += moddep.lst +syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) + cat kernel_syms.lst > $@.new + for m in $(MODULE_FILES); do \ + sh $< $$m >> $@.new || exit 1; \ + done + mv $@.new $@ # generate global module dependencies list -moddep.lst: kernel_syms.lst genmoddep.awk $(DEF_FILES) $(UND_FILES) - cat $(DEF_FILES) kernel_syms.lst /dev/null \ - | $(AWK) -f $(srcdir)/genmoddep.awk $(UND_FILES) > $@ \ - || (rm -f $@; exit 1) +moddep.lst: syminfo.lst genmoddep.awk + cat $< | sort | awk -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) +platform_DATA += moddep.lst +CLEANFILES += moddep.lst if COND_i386_pc if COND_ENABLE_EFIEMU diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 0257bbac4..5587f0f40 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1403,3 +1403,8 @@ module = { name = datehook; common = hook/datehook.c; }; + +script = { + name = gensyminfo.sh; + common = gensyminfo.sh.in; +}; diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk index 74487eabf..dfc924666 100644 --- a/grub-core/genmoddep.awk +++ b/grub-core/genmoddep.awk @@ -11,23 +11,27 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# Read defined symbols from stdin. +# Read symbols' info from stdin. BEGIN { + error = 0 + lineno = 0; while (getline <"/dev/stdin") { - symtab[$1] = $2 - } -} - -# The rest is undefined symbols. -{ - module = $2 - - if ($1 in symtab) { - modtab[module] = modtab[module] " " symtab[$1]; - } - else if ($1 != "__gnu_local_gp") { - printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; - error++; + lineno++; + if ($1 == "defined") + symtab[$3] = $2; + else if ($1 == "undefined") { + if ($3 in symtab) + modtab[$2] = modtab[$2] " " symtab[$3]; + else if ($3 != "__gnu_local_gp") { + printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr"; + error++; + } + } + else { + printf "error: %u: unrecognized input format\n", lineno; + error++; + break; + } } } diff --git a/grub-core/gensyminfo.sh.in b/grub-core/gensyminfo.sh.in new file mode 100644 index 000000000..4f5184913 --- /dev/null +++ b/grub-core/gensyminfo.sh.in @@ -0,0 +1,34 @@ +#! /bin/sh -e +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Example: +# +# gensyms.sh normal.module +# + +module=$1 +modname=`echo $module | sed -e 's@\.module.*$@@'` + +# Print all symbols defined by module +if test x@TARGET_APPLE_CC@ = x1; then + @NM@ -g -P -p $module | \ + grep -E '^[a-zA-Z0-9_]* [TDS]' | \ + sed "s@^\([^ ]*\).*@defined $modname \1@g" +else + @NM@ -g --defined-only -P -p $module | \ + sed "s@^\([^ ]*\).*@defined $modname \1@g" +fi + +# Print all undefined symbols used by module +@NM@ -u -P -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g" From ea943e89a387bbd0fdccc0cfdcb966e2254d97d2 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 29 Aug 2010 12:35:52 +0530 Subject: [PATCH 0105/1414] distcheck fixes --- conf/Makefile.extra-dist | 11 ++--------- grub-core/Makefile.am | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 3acef7af7..8fe5eed8b 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -15,19 +15,12 @@ EXTRA_DIST += grub-core/Makefile.gcry.def EXTRA_DIST += grub-core/genmoddep.awk EXTRA_DIST += grub-core/genmodsrc.sh -EXTRA_DIST += grub-core/genfslist.sh -EXTRA_DIST += grub-core/gencmdlist.sh +EXTRA_DIST += grub-core/gensyminfo.sh.in EXTRA_DIST += grub-core/gensymlist.sh EXTRA_DIST += grub-core/genemuinit.sh -EXTRA_DIST += grub-core/genvideolist.sh -EXTRA_DIST += grub-core/genhandlerlist.sh -EXTRA_DIST += grub-core/genpartmaplist.sh -EXTRA_DIST += grub-core/genterminallist.sh -EXTRA_DIST += grub-core/genparttoollist.sh EXTRA_DIST += grub-core/genemuinitheader.sh EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') +EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/posix_wrap -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/libgcrypt_wrap -name '*.h') diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 2f23f03b0..d8b7dbc0f 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -344,7 +344,7 @@ syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) moddep.lst: syminfo.lst genmoddep.awk cat $< | sort | awk -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) platform_DATA += moddep.lst -CLEANFILES += moddep.lst +CLEANFILES += config.log syminfo.lst moddep.lst if COND_i386_pc if COND_ENABLE_EFIEMU From 6b5f780f0590e3ce22444360ce68ae8c1ff7f0f0 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 29 Aug 2010 16:43:07 +0530 Subject: [PATCH 0106/1414] use objcopy instead of creating mod-*.c and mod-*.o --- gentpl.py | 20 ---------- grub-core/Makefile.am | 5 +++ grub-core/Makefile.core.def | 5 +++ grub-core/genmod.sh.in | 73 +++++++++++++++++++++++++++++++++++++ grub-core/genmoddep.awk | 5 ++- 5 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 grub-core/genmod.sh.in diff --git a/gentpl.py b/gentpl.py index b153452cd..81b44316b 100644 --- a/gentpl.py +++ b/gentpl.py @@ -285,31 +285,11 @@ def module(platform): r += gvar_add("CLEANFILES", "$(nodist_" + cname() + "_SOURCES)") r += gvar_add("MOD_FILES", "[+ name +].mod") - r += gvar_add("platform_DATA", "[+ name +].mod") - r += gvar_add("CLEANFILES", "def-[+ name +].lst und-[+ name +].lst mod-[+ name +].c mod-[+ name +].o [+ name +].mod") - r += gvar_add("PP_FILES", "[+ name +].pp") r += gvar_add("CLEANFILES", "[+ name +].pp") r += """ [+ name +].pp: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES) $(TARGET_CPP) -DGRUB_LST_GENERATOR $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@ || (rm -f $@; exit 1) - -mod-[+ name +].c: [+ name +].module$(EXEEXT) moddep.lst genmodsrc.sh - sh $(srcdir)/genmodsrc.sh [+ name +] moddep.lst > $@ || (rm -f $@; exit 1) - -mod-[+ name +].o: mod-[+ name +].c - $(TARGET_CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $(""" + cname() + """_CFLAGS) $(CFLAGS) -c -o $@ $< - -[+ name +].mod: [+ name +].module$(EXEEXT) mod-[+ name +].o - if test x$(USE_APPLE_CC_FIXES) = xyes; then \ - $(CCLD) $(""" + cname() + """_LDFLAGS) $(LDFLAGS) -o $@.bin $^; \ - $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@; \ - rm -f $@.bin; \ - else \ - $(CCLD) -o $@ $(""" + cname() + """_LDFLAGS) $(LDFLAGS) $^; \ - if test ! -z '$(TARGET_OBJ2ELF)'; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \ - $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; \ - fi """ return r diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index d8b7dbc0f..c277cd47e 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -346,6 +346,11 @@ moddep.lst: syminfo.lst genmoddep.awk platform_DATA += moddep.lst CLEANFILES += config.log syminfo.lst moddep.lst +$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) + sh $^ $@ +platform_DATA += $(MOD_FILES) +CLEANFILES += $(MOD_FILES) + if COND_i386_pc if COND_ENABLE_EFIEMU efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 5587f0f40..c852c344f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1408,3 +1408,8 @@ script = { name = gensyminfo.sh; common = gensyminfo.sh.in; }; + +script = { + name = genmod.sh; + common = genmod.sh.in; +}; diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in new file mode 100644 index 000000000..a267ca5d7 --- /dev/null +++ b/grub-core/genmod.sh.in @@ -0,0 +1,73 @@ +#! /bin/sh -e +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# Example: +# +# genmod.sh moddep.lst normal.module echo.module +# + +moddep=$1 +infile=$2 +outfile=$3 + +tmpfile=${outfile}.tmp +modname=`echo $infile | sed -e 's@\.module.*$@@'` + +if ! grep ^$modname: $moddep >/dev/null; then + echo "warning: moddep.lst has no dependencies for $modname" >&2 + exit 0 +fi + +deps=`grep ^$modname: $moddep | sed s@^.*:@@` + +# remove old files if any +rm -f $tmpfile $outfile + +# stripout .modname and .moddeps sections from input module +objcopy -R .modname -R .moddeps $infile $tmpfile + +# Attach .modname and .moddeps sections +t1=`mktemp` +printf "$modname\0" >$t1 + +t2=`mktemp` +for dep in $deps; do printf "$dep\0" >> $t2; done + +if test -n "$deps"; then + objcopy --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile +else + objcopy --add-section .modname=$t1 $tmpfile +fi +rm -f $t1 $t2 + +if test x@TARGET_APPLE_CC@ != x1; then + if ! test -z "@TARGET_OBJ2ELF@"; then + ./@TARGET_OBJ2ELF@ $tmpfile || exit 1 + fi + if test x@platform@ != xemu; then + @STRIP@ --strip-unneeded \ + -K grub_mod_init -K grub_mod_fini \ + -K _grub_mod_init -K _grub_mod_fini \ + -R .note -R .comment $tmpfile || exit 1 + fi +else +# XXX Test these Apple CC fixes + cp $tmpfile $tmpfile.bin + @OBJCONV@ -f@TARGET_MODULE_FORMAT@ \ + -nr:_grub_mod_init:grub_mod_init \ + -nr:_grub_mod_fini:grub_mod_fini \ + -wd1106 -ew2030 -ew2050 -nu -nd $tmpfile.bin $tmpfile || exit 1 + rm -f $name.bin +fi +mv $tmpfile $outfile diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk index dfc924666..e412d4370 100644 --- a/grub-core/genmoddep.awk +++ b/grub-core/genmoddep.awk @@ -17,9 +17,10 @@ BEGIN { lineno = 0; while (getline <"/dev/stdin") { lineno++; - if ($1 == "defined") + if ($1 == "defined") { symtab[$3] = $2; - else if ($1 == "undefined") { + modtab[$2] = "" modtab[$2] + } else if ($1 == "undefined") { if ($3 in symtab) modtab[$2] = modtab[$2] " " symtab[$3]; else if ($3 != "__gnu_local_gp") { From 466b9c35677a6768e98efbd2021534c625f3d0ab Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 29 Aug 2010 16:58:43 +0530 Subject: [PATCH 0107/1414] distcheck fixes --- conf/Makefile.extra-dist | 2 +- grub-core/genmodsrc.sh | 47 ---------------------------------------- 2 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 grub-core/genmodsrc.sh diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 8fe5eed8b..9acaadbcc 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -14,7 +14,7 @@ EXTRA_DIST += grub-core/Makefile.core.def EXTRA_DIST += grub-core/Makefile.gcry.def EXTRA_DIST += grub-core/genmoddep.awk -EXTRA_DIST += grub-core/genmodsrc.sh +EXTRA_DIST += grub-core/genmod.sh.in EXTRA_DIST += grub-core/gensyminfo.sh.in EXTRA_DIST += grub-core/gensymlist.sh EXTRA_DIST += grub-core/genemuinit.sh diff --git a/grub-core/genmodsrc.sh b/grub-core/genmodsrc.sh deleted file mode 100644 index 2d420550a..000000000 --- a/grub-core/genmodsrc.sh +++ /dev/null @@ -1,47 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 2002,2007 Free Software Foundation, Inc. -# -# This genmodsrc.sh is free software; the author -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -set -e - -mod_name="$1" -deps="$2" - -cat <. - */ - -#include - -EOF - -echo "GRUB_MOD_NAME(${mod_name});" - -for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do - echo "GRUB_MOD_DEP(${mod});" -done From 6568636e31cd0c8237dbdceeedefd0739388556e Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 29 Aug 2010 21:22:41 +0530 Subject: [PATCH 0108/1414] use preprocessing-marker technique for creating list files --- conf/Makefile.common | 16 +++++++++++- gentpl.py | 9 ++++--- grub-core/Makefile.am | 57 ++++++++++++++++++------------------------- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/conf/Makefile.common b/conf/Makefile.common index 1cf5a4b72..f13cbdc54 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -83,12 +83,26 @@ CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime +# List file macros for recognizing /interesting/ modules +CPPFLAGS_FS_LIST = -Dgrub_fs_register=FS_LIST_MARKER +CPPFLAGS_VIDEO_LIST= -Dgrub_video_register=VIDEO_LIST_MARKER +CPPFLAGS_PARTMAP_LIST = -Dgrub_partition_map_register=PARTMAP_LIST_MARKER +CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER +CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ + $(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \ + $(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST) + # Define these variables to calm down automake -PP_FILES = IMG_FILES = MOD_FILES = MODULE_FILES = +MARKER_FILES = KERNEL_HEADER_FILES = man_MANS = diff --git a/gentpl.py b/gentpl.py index 81b44316b..f520ebf99 100644 --- a/gentpl.py +++ b/gentpl.py @@ -285,11 +285,12 @@ def module(platform): r += gvar_add("CLEANFILES", "$(nodist_" + cname() + "_SOURCES)") r += gvar_add("MOD_FILES", "[+ name +].mod") - r += gvar_add("PP_FILES", "[+ name +].pp") - r += gvar_add("CLEANFILES", "[+ name +].pp") + r += gvar_add("MARKER_FILES", "[+ name +].marker") + r += gvar_add("CLEANFILES", "[+ name +].marker") r += """ -[+ name +].pp: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES) - $(TARGET_CPP) -DGRUB_LST_GENERATOR $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@ || (rm -f $@; exit 1) +[+ name +].marker: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES) + $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) + grep 'MARKER' $@.new > $@; rm -f $@.new """ return r diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index c277cd47e..3ee526ff8 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -258,69 +258,60 @@ endif # List files -fs.lst: $(PP_FILES) +fs.lst: $(MARKER_FILES) (for pp in $^; do \ - b=`basename $$pp .pp`; \ - if grep -v "^#" $$pp | grep '^ *grub_fs_register' >/dev/null 2>&1; then \ + b=`basename $$pp .marker`; \ + if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \ echo $$b; \ fi; \ done) | sort -u > $@ platform_DATA += fs.lst CLEANFILES += fs.lst -command.lst: $(PP_FILES) +command.lst: $(MARKER_FILES) (for pp in $^; do \ - b=`basename $$pp .pp`; \ - grep -v "^#" $$pp | sed -n \ - -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ - -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ - -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}"; \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ + -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" $$pp; \ done) | sort -u > $@ platform_DATA += command.lst CLEANFILES += command.lst -partmap.lst: $(PP_FILES) +partmap.lst: $(MARKER_FILES) (for pp in $^; do \ - b=`basename $$pp .pp`; \ - if grep -v "^#" $$pp | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then \ + b=`basename $$pp .marker`; \ + if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \ echo $$b; \ fi; \ done) | sort -u > $@ platform_DATA += partmap.lst CLEANFILES += partmap.lst -handler.lst: $(PP_FILES) +terminal.lst: $(MARKER_FILES) (for pp in $^; do \ - b=`basename $$pp .pp`; \ - grep -v "^#" $$pp | sed -n \ - -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $$b/;p;}"; \ - done) | sort -u > $@ -platform_DATA += handler.lst -CLEANFILES += handler.lst - -terminal.lst: $(PP_FILES) - (for pp in $^; do \ - b=`basename $$pp .pp`; \ - grep -v "^#" $$pp | sed -n \ - -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ - -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}"; \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ done) | sort -u > $@ platform_DATA += terminal.lst CLEANFILES += terminal.lst -parttool.lst: $(PP_FILES) +parttool.lst: $(MARKER_FILES) (for pp in $^; do \ - b=`basename $$pp .pp`; \ - grep -v "^#" $$pp | sed -n \ - -e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}"; \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ done) | sort -u > $@ platform_DATA += parttool.lst CLEANFILES += parttool.lst -video.lst: $(PP_FILES) +video.lst: $(MARKER_FILES) (for pp in $^; do \ - b=`basename $$pp .pp`; \ - if grep -v "^#" $$pp | grep '^ *grub_video_register' >/dev/null 2>&1; then \ + b=`basename $$pp .marker`; \ + if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \ echo $$b; \ fi; \ done) | sort -u > $@ From 69d6fc56036f18f3a9f69a78f24d6df8a40cfbb9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Aug 2010 01:04:07 +0200 Subject: [PATCH 0109/1414] Use interrupt endpoint for hubs --- bus/usb/usbhub.c | 290 +++++++++++++---------------------------------- 1 file changed, 81 insertions(+), 209 deletions(-) diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c index 111a2495e..0ddba3255 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -28,6 +28,8 @@ /* USB Supports 127 devices, with device 0 as special case. */ static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES]; +static int rescan = 0; + struct grub_usb_hub { struct grub_usb_hub *next; @@ -110,9 +112,6 @@ grub_usb_add_hub (grub_usb_device_t dev) struct grub_usb_usb_hubdesc hubdesc; grub_err_t err; int i; - grub_uint64_t timeout; - grub_usb_device_t next_dev; - grub_usb_device_t *attached_devices; err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN | GRUB_USB_REQTYPE_CLASS @@ -131,11 +130,9 @@ grub_usb_add_hub (grub_usb_device_t dev) grub_dprintf ("usb", "Hub set configuration\n"); grub_usb_set_configuration (dev, 1); - attached_devices = grub_zalloc (hubdesc.portcnt - * sizeof (attached_devices[0])); - if (!attached_devices) + dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0])); + if (!dev->children) return GRUB_USB_ERR_INTERNAL; - dev->children = attached_devices; dev->nports = hubdesc.portcnt; /* Power on all Hub ports. */ @@ -143,115 +140,15 @@ grub_usb_add_hub (grub_usb_device_t dev) { grub_dprintf ("usb", "Power on - port %d\n", i); /* Power on the port and wait for possible device connect */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_SET_FEATURE, - GRUB_USB_HUB_FEATURE_PORT_POWER, - i, 0, NULL); - /* Just ignore the device if some error happened */ - if (err) - continue; - } - /* Wait for port power-on */ - if (hubdesc.pwdgood >= 50) - grub_millisleep (hubdesc.pwdgood * 2); - else - grub_millisleep (100); - - /* Iterate over the Hub ports. */ - for (i = 1; i <= hubdesc.portcnt; i++) - { - grub_uint32_t status; - - /* Get the port status. */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_GET_STATUS, - 0, i, sizeof (status), (char *) &status); - /* Just ignore the device if the Hub does not report the - status. */ - if (err) - continue; - grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status); - - /* If connected, reset and enable the port. */ - if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) - { - grub_usb_speed_t speed; - - /* Determine the device speed. */ - if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) - speed = GRUB_USB_SPEED_LOW; - else - { - if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED) - speed = GRUB_USB_SPEED_HIGH; - else - speed = GRUB_USB_SPEED_FULL; - } - - /* A device is actually connected to this port. - * Now do reset of port. */ - grub_dprintf ("usb", "Reset hub port - port %d\n", i); - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_SET_FEATURE, - GRUB_USB_HUB_FEATURE_PORT_RESET, - i, 0, 0); - /* If the Hub does not cooperate for this port, just skip - the port. */ - if (err) - continue; - - /* Wait for reset procedure done */ - timeout = grub_get_time_ms () + 1000; - do - { - /* Get the port status. */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_GET_STATUS, - 0, i, sizeof (status), (char *) &status); - } - while (!err && - !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) && - (grub_get_time_ms() < timeout) ); - if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) ) - continue; - - /* Wait a recovery time after reset, spec. says 10ms */ - grub_millisleep (10); - - /* Do reset of connection change bit */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, - i, 0, 0); - /* Just ignore the device if the Hub reports some error */ - if (err) - continue; - grub_dprintf ("usb", "Hub port - cleared connection change\n"); - - /* Add the device and assign a device address to it. */ - grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i); - next_dev = grub_usb_hub_add_dev (&dev->controller, speed); - if (! next_dev) - continue; - - attached_devices[i - 1] = next_dev; - - /* If the device is a Hub, scan it for more devices. */ - if (next_dev->descdev.class == 0x09) - grub_usb_add_hub (next_dev); - } + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_POWER, + i, 0, NULL); } + /* Rest will be done on next usb poll. */ for (i = 0; i < dev->config[0].interf[0].descif->endpointcnt; i++) { @@ -271,6 +168,8 @@ grub_usb_add_hub (grub_usb_device_t dev) } } + rescan = 1; + return GRUB_ERR_NONE; } @@ -383,9 +282,6 @@ poll_nonroot_hub (grub_usb_device_t dev) { grub_err_t err; unsigned i; - grub_uint64_t timeout; - grub_usb_device_t next_dev; - grub_usb_device_t *attached_devices = dev->children; grub_uint8_t changed; grub_size_t actual; @@ -408,9 +304,6 @@ poll_nonroot_hub (grub_usb_device_t dev) if (err || actual == 0 || changed == 0) return; - grub_dprintf ("usb", "statuschanged = %02x, err = %d, actual = %d\n", - changed, err, actual); - /* Iterate over the Hub ports. */ for (i = 1; i <= dev->nports; i++) { @@ -426,17 +319,12 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); + grub_printf ("i = %d, status = %08x\n", i, status); + if (err) continue; /* FIXME: properly handle these conditions. */ - if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET) - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0); - if (status & GRUB_USB_HUB_STATUS_C_PORT_ENABLED) grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_CLASS @@ -458,96 +346,72 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_REQ_CLEAR_FEATURE, GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0); - if (!(status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)) - continue; - - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0); - if (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED) { - detach_device (attached_devices[i-1]); - attached_devices[i - 1] = NULL; - } + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0); + + detach_device (dev->children[i - 1]); + dev->children[i - 1] = NULL; - /* Connected and status of connection changed ? */ - if ((status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) - && (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)) - { - grub_usb_speed_t speed; - - /* Determine the device speed. */ - if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) - speed = GRUB_USB_SPEED_LOW; - else + /* Connected and status of connection changed ? */ + if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) { - if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED) - speed = GRUB_USB_SPEED_HIGH; - else - speed = GRUB_USB_SPEED_FULL; + /* A device is actually connected to this port. + * Now do reset of port. */ + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_RESET, + i, 0, 0); + rescan = 1; } + } - /* A device is actually connected to this port. - * Now do reset of port. */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_SET_FEATURE, - GRUB_USB_HUB_FEATURE_PORT_RESET, - i, 0, 0); - /* If the Hub does not cooperate for this port, just skip - the port. */ - if (err) - continue; + if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET) + { + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0); - /* Wait for reset procedure done */ - timeout = grub_get_time_ms () + 1000; - do - { - /* Get the port status. */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_GET_STATUS, - 0, i, sizeof (status), (char *) &status); - } - while (!err && - !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) && - (grub_get_time_ms() < timeout) ); - if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) ) - continue; + if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) + { + grub_usb_speed_t speed; + grub_usb_device_t next_dev; - /* Wait a recovery time after reset, spec. says 10ms */ - grub_millisleep (10); + /* Determine the device speed. */ + if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) + speed = GRUB_USB_SPEED_LOW; + else + { + if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED) + speed = GRUB_USB_SPEED_HIGH; + else + speed = GRUB_USB_SPEED_FULL; + } - /* Do reset of connection change bit */ - err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, - i, 0, 0); - /* Just ignore the device if the Hub reports some error */ - if (err) - continue; + /* Wait a recovery time after reset, spec. says 10ms */ + grub_millisleep (10); - /* Add the device and assign a device address to it. */ - next_dev = grub_usb_hub_add_dev (&dev->controller, speed); - if (! next_dev) - continue; + /* Add the device and assign a device address to it. */ + next_dev = grub_usb_hub_add_dev (&dev->controller, speed); + if (! next_dev) + continue; - attached_devices[i - 1] = next_dev; + dev->children[i - 1] = next_dev; - /* If the device is a Hub, scan it for more devices. */ - if (next_dev->descdev.class == 0x09) - grub_usb_add_hub (next_dev); + /* If the device is a Hub, scan it for more devices. */ + if (next_dev->descdev.class == 0x09) + grub_usb_add_hub (next_dev); + } } } - - return; } void @@ -578,13 +442,21 @@ grub_usb_poll_devices (void) } } - /* We should check changes of non-root hubs too. */ - for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) + while (1) { - grub_usb_device_t dev = grub_usb_devs[i]; - - if (dev && dev->descdev.class == 0x09) - poll_nonroot_hub (dev); + rescan = 0; + + /* We should check changes of non-root hubs too. */ + for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) + { + grub_usb_device_t dev = grub_usb_devs[i]; + + if (dev && dev->descdev.class == 0x09) + poll_nonroot_hub (dev); + } + if (!rescan) + break; + grub_millisleep (50); } } From 8111f933ec1cf6d35488645680edd1d5b4a76730 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Aug 2010 19:30:34 +0200 Subject: [PATCH 0110/1414] remove ieee1275/grub-install and adapt grub-install for ieee1275 --- Makefile.util.def | 4 +- util/grub-install.in | 86 ++++++++++- util/ieee1275/grub-install.in | 273 ---------------------------------- 3 files changed, 80 insertions(+), 283 deletions(-) delete mode 100644 util/ieee1275/grub-install.in diff --git a/Makefile.util.def b/Makefile.util.def index 9565dde65..0beae52ce 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -351,10 +351,10 @@ script = { i386_coreboot = util/grub-install.in; i386_multiboot = util/grub-install.in; sparc64_ieee1275 = util/grub-install.in; + i386_ieee1275 = util/grub-install.in; + powerpc_ieee1275 = util/grub-install.in; x86_efi = util/i386/efi/grub-install.in; - i386_ieee1275 = util/ieee1275/grub-install.in; - powerpc_ieee1275 = util/ieee1275/grub-install.in; enable = noemu; }; diff --git a/util/grub-install.in b/util/grub-install.in index 4a5b5a1c3..2502c7bf0 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -41,6 +41,7 @@ grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` +grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` rootdir= grub_prefix=`echo /boot/grub | sed ${transform}` modules= @@ -52,6 +53,11 @@ recheck=no debug=no debug_image= +update_nvram=yes + +ofpathname=`which ofpathname` +nvsetenv=`which nvsetenv` + if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=biosdisk elif [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then @@ -63,8 +69,16 @@ fi # Usage: usage # Print the usage. usage () { +if test "x$install_device" = x && test "${target_cpu}-${platform}" != "mips-yeeloong" && test "${target_cpu}-${platform}" != "i386-ieee1275" && test "${target_cpu}-${platform}" != "powerpc-ieee1275"; then cat <&2 usage exit 1 @@ -405,19 +433,61 @@ case "${target_cpu}-${platform}" in i386-pc) mkimage_target=i386-pc ;; sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; - *) mkimage_target=i386-coreboot; + i386-coreboot) mkimage_target=i386-coreboot ;; + i386-multiboot) mkimage_target=i386-multiboot ;; + i386-qemu) mkimage_target=i386-multiboot ;; + i386-ieee1275) mkimage_target=i386-ieee1275 ;; + powerpc-ieee1275) mkimage_target=powerpc-ieee1275 ;; + *) echo "Unknown platform"; exit 1 ;; esac -if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then - $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +$grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +# Copy to traditional location for compatibility +if [ "${target_cpu}-${platform}" = "mips-yeeloong" ]; then + cp ${grubdir}/core.img /boot/grub.elf +elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then + cp ${grubdir}/core.img /boot/grub +fi + +if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 -elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O ${mkimage_target} --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 -else - $grub_mkimage -O ${mkimage_target} ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then + if [ x"$update_nvram" = xyes ]; then + set $ofpathname dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi + set $nvsetenv dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi + # Get the Open Firmware device tree path translation. + dev=`echo $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'` + partno=`echo $grub_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'` + ofpath=`$ofpathname $dev` || { + echo "Couldn't find Open Firmware device tree path for $dev." + echo "You will have to set boot-device manually." + exit 1 + } + + # Point boot-device at the new grub install + boot_device="$ofpath:$partno,"`grub-mkrelpath ${grubdir}/core.img | sed 's,/,\\,g'` + "$nvsetenv" boot-device "$boot_device" || { + echo "$nvsetenv failed." + echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" + echo " setenv boot-device $boot_device" + exit 1 + } + fi fi echo "Installation finished. No error reported." diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in deleted file mode 100644 index 98de5f348..000000000 --- a/util/ieee1275/grub-install.in +++ /dev/null @@ -1,273 +0,0 @@ -#! /bin/sh - -# Install GRUB on your drive. -# 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 . - -# This script uses `ofpathname', which is downloadable from -# http://ppc64-utils.ozlabs.org . - -# Initialize some variables. -transform="@program_transform_name@" - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -sbindir=@sbindir@ -bindir=@bindir@ -libdir=@libdir@ -PACKAGE_NAME=@PACKAGE_NAME@ -PACKAGE_TARNAME=@PACKAGE_TARNAME@ -PACKAGE_VERSION=@PACKAGE_VERSION@ -target_cpu=@target_cpu@ -platform=@platform@ -pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` - -self=`basename $0` - -grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` -grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` -grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` -rootdir= -grub_prefix=`echo /boot/grub | sed ${transform}` -modules= - -install_device= -debug=no -update_nvram=yes - -ofpathname=`which ofpathname` -nvsetenv=`which nvsetenv` - -# Usage: usage -# Print the usage. -usage () { - cat <. -EOF -} - -argument () { - opt=$1 - shift - - if test $# -eq 0; then - echo "$0: option requires an argument -- '$opt'" 1>&2 - exit 1 - fi - echo $1 -} - -# Check the arguments. -while test $# -gt 0 -do - option=$1 - shift - - case "$option" in - -h | --help) - usage - exit 0 ;; - -v | --version) - echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" - exit 0 ;; - - --modules) - modules=`argument $option "$@"`; shift ;; - --modules=*) - modules=`echo "$option" | sed 's/--modules=//'` ;; - - --root-directory) - rootdir=`argument $option "$@"`; shift ;; - --root-directory=*) - rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; - - --grub-mkdevicemap) - grub_mkdevicemap=`argument $option "$@"`; shift ;; - --grub-mkdevicemap=*) - grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; - - --grub-mkimage) - grub_mkimage=`argument $option "$@"`; shift ;; - --grub-mkimage=*) - grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; - - --grub-probe) - grub_probe=`argument $option "$@"`; shift ;; - --grub-probe=*) - grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; - - --no-nvram) - update_nvram=no ;; - # 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 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 -grubdir=${bootdir}/`echo grub | sed ${transform}` -device_map=${grubdir}/device.map - -set $grub_mkimage dummy -if test -f "$1"; then - : -else - echo "$1: Not found." 1>&2 - exit 1 -fi - -# Find the partition at the right mount point. -install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${grubdir}` - -if test "x$install_device" = "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}`"; then - echo "$grubdir must be a mount point." - exit 1 -fi -# XXX warn on firmware-unreadable filesystems? - -# Create the GRUB directory if it is not present. -mkdir -p "$grubdir" || exit 1 - -# Create the device map file if it is not present. -if test -f "$device_map"; then - : -else - # Create a safe temporary file. - test -n "$mklog" && log_file=`$mklog` - - $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 -fi - -# Copy the GRUB images to the GRUB directory. -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 - -if ! test -f ${grubdir}/grubenv; then - $grub_editenv ${grubdir}/grubenv create -fi - -# Create the core image. First, auto-detect the filesystem module. -fs_module=`$grub_probe --target=fs --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 - -# Then the partition map module. In order to support partition-less media, -# this command is allowed to fail (--target=fs already grants us that the -# filesystem will be accessible). -partmap_module= -for x in `$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`; do - partmap_module="$partmap_module part_$x"; -done - -# Device abstraction module, if any (lvm, raid). -devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}` - -modules="$modules $fs_module $partmap_module $devabstraction_module" - -# Now perform the installation. -"$grub_mkimage" -O ${target_cpu}-ieee1275 --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 - -if test $update_nvram = yes; then - set $ofpathname dummy - if test -f "$1"; then - : - else - echo "$1: Not found." 1>&2 - exit 1 - fi - - set $nvsetenv dummy - if test -f "$1"; then - : - else - echo "$1: Not found." 1>&2 - exit 1 - fi - - # Get the Open Firmware device tree path translation. - dev=`echo $install_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'` - partno=`echo $install_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'` - ofpath=`$ofpathname $dev` || { - echo "Couldn't find Open Firmware device tree path for $dev." - echo "You will have to set boot-device manually." - exit 1 - } - - # Point boot-device at the new grub install - boot_device="$ofpath:$partno,\\grub" - "$nvsetenv" boot-device "$boot_device" || { - echo "$nvsetenv failed." - echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" - echo " setenv boot-device $boot_device" - exit 1 - } -fi - -# Prompt the user to check if the device map is correct. -echo "Installation finished. No error reported." -echo "This is the contents of the device map $device_map." -echo "Check if this is correct or not. If any of the lines is incorrect," -echo "fix it and re-run the script \`$self'." -echo - -cat $device_map - -# Bye. -exit 0 From 37837d4ecb1526799eb2ff0a733fcd4e22e9dd90 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Aug 2010 19:48:10 +0200 Subject: [PATCH 0111/1414] Remove leftover embedding of font objects. * include/grub/kernel.h (OBJ_TYPE_FONT): Removed. * util/grub-install.in (font): Removed. * util/grub-mkimage.c (generate_image): Remove font support. All users updated. --- ChangeLog | 9 +++++++++ include/grub/kernel.h | 3 +-- util/grub-install.in | 13 ++++--------- util/grub-mkimage.c | 34 +++------------------------------- 4 files changed, 17 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a0085d9a..869bd420b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-08-30 Vladimir Serbinenko + + Remove leftover embedding of font objects. + + * include/grub/kernel.h (OBJ_TYPE_FONT): Removed. + * util/grub-install.in (font): Removed. + * util/grub-mkimage.c (generate_image): Remove font support. All users + updated. + 2010-08-30 Vladimir Serbinenko * docs/grub.texi (Network): Fix reference to pxe_blksize. diff --git a/include/grub/kernel.h b/include/grub/kernel.h index fed875db1..2ecc73df4 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -26,8 +26,7 @@ enum { OBJ_TYPE_ELF, OBJ_TYPE_MEMDISK, - OBJ_TYPE_CONFIG, - OBJ_TYPE_FONT + OBJ_TYPE_CONFIG }; /* The module header. */ diff --git a/util/grub-install.in b/util/grub-install.in index 4a5b5a1c3..e6521f069 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -30,7 +30,6 @@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ platform=@platform@ host_os=@host_os@ -font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` localedir=@datadir@/locale @@ -84,11 +83,6 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then cat <type = grub_host_to_target32 (OBJ_TYPE_FONT); - header->size = grub_host_to_target32 (font_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (font_path, kernel_img + offset); - offset += font_size; - } - if (config_path) { struct grub_module_header *header; @@ -1241,7 +1221,6 @@ Make a bootable image of GRUB.\n\ -d, --directory=DIR use images and modules under DIR [default=%s/@platform@]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ - -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n\ @@ -1330,13 +1309,6 @@ main (int argc, char *argv[]) prefix = xstrdup ("(memdisk)/boot/grub"); break; - case 'f': - if (font) - free (font); - - font = xstrdup (optarg); - break; - case 'c': if (config) free (config); @@ -1401,7 +1373,7 @@ main (int argc, char *argv[]) } generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, - argv + optind, memdisk, font, config, + argv + optind, memdisk, config, image_target, note); fclose (fp); From 6c2111e96cfc3eb7ee09b460e9d62ab4fe86aa41 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Aug 2010 20:27:59 +0200 Subject: [PATCH 0112/1414] Adapt common grub-install for efi and use it --- Makefile.util.def | 12 +- util/grub-install.in | 33 +++-- util/i386/efi/grub-install.in | 261 ---------------------------------- 3 files changed, 20 insertions(+), 286 deletions(-) delete mode 100644 util/i386/efi/grub-install.in diff --git a/Makefile.util.def b/Makefile.util.def index 0beae52ce..532ff65b7 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -345,17 +345,7 @@ script = { installdir = sbin; name = grub-install; - mips = util/grub-install.in; - i386_pc = util/grub-install.in; - i386_qemu = util/grub-install.in; - i386_coreboot = util/grub-install.in; - i386_multiboot = util/grub-install.in; - sparc64_ieee1275 = util/grub-install.in; - i386_ieee1275 = util/grub-install.in; - powerpc_ieee1275 = util/grub-install.in; - - x86_efi = util/i386/efi/grub-install.in; - + common = util/grub-install.in; enable = noemu; }; diff --git a/util/grub-install.in b/util/grub-install.in index 7511522c7..910549d30 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -425,30 +425,35 @@ else fi case "${target_cpu}-${platform}" in - i386-pc) mkimage_target=i386-pc ;; sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; - i386-coreboot) mkimage_target=i386-coreboot ;; - i386-multiboot) mkimage_target=i386-multiboot ;; - i386-qemu) mkimage_target=i386-multiboot ;; - i386-ieee1275) mkimage_target=i386-ieee1275 ;; - powerpc-ieee1275) mkimage_target=powerpc-ieee1275 ;; - *) echo "Unknown platform"; exit 1 ;; + *) mkimage_target="${target_cpu}-${platform}" ;; esac -$grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +case "${target_cpu}-${platform}" in + i386-efi | x86_64-efi) imgext=efi ;; + mips-yeeloong | i386-coreboot | i386-multiboot | i386-ieee1275 \ + | powerpc-ieeee1275) imgext=elf ;; + *) imgext=img ;; +esac -# Copy to traditional location for compatibility + +$grub_mkimage ${config_opt} -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 - cp ${grubdir}/core.img /boot/grub.elf + cp ${grubdir}/core.${imgext} /boot/grub.elf elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then - cp ${grubdir}/core.img /boot/grub + cp ${grubdir}/core.${imgext} /boot/grub +elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ]; then + $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 fi +# Perform the platform-dependent install if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then # Now perform the installation. - $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ - ${install_device} || exit 1 + $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} \ + --device-map=${device_map} ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then if [ x"$update_nvram" = xyes ]; then set $ofpathname dummy @@ -475,7 +480,7 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla } # Point boot-device at the new grub install - boot_device="$ofpath:$partno,"`grub-mkrelpath ${grubdir}/core.img | sed 's,/,\\,g'` + boot_device="$ofpath:$partno,"`grub-mkrelpath ${grubdir}/core.${imgext} | sed 's,/,\\,g'` "$nvsetenv" boot-device "$boot_device" || { echo "$nvsetenv failed." echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in deleted file mode 100644 index d8554a328..000000000 --- a/util/i386/efi/grub-install.in +++ /dev/null @@ -1,261 +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. -transform="@program_transform_name@" - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -sbindir=@sbindir@ -bindir=@bindir@ -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 - -self=`basename $0` - -grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` -grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` -grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` -rootdir= -grub_prefix=`echo /boot/grub | sed ${transform}` -modules= - -no_floppy= -force_lba= -recheck=no -debug=no - -# Usage: usage -# Print the usage. -usage () { - cat <. -EOF -} - -argument () { - opt=$1 - shift - - if test $# -eq 0; then - echo "$0: option requires an argument -- '$opt'" 1>&2 - exit 1 - fi - echo $1 -} - -# Check the arguments. -while test $# -gt 0 -do - option=$1 - shift - - case "$option" in - -h | --help) - usage - exit 0 ;; - -v | --version) - echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" - exit 0 ;; - - --modules) - modules=`argument $option "$@"`; shift ;; - --modules=*) - modules=`echo "$option" | sed 's/--modules=//'` ;; - - --root-directory) - rootdir=`argument $option "$@"`; shift ;; - --root-directory=*) - rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; - - --grub-mkimage) - grub_mkimage=`argument $option "$@"`; shift ;; - --grub-mkimage=*) - grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; - - --grub-mkdevicemap) - grub_mkdevicemap=`argument $option "$@"`; shift ;; - --grub-mkdevicemap=*) - grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; - - --grub-probe) - grub_probe=`argument $option "$@"`; shift ;; - --grub-probe=*) - grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; - - --no-floppy) - no_floppy="--no-floppy" ;; - --recheck) - recheck=yes ;; - # This is an undocumented feature... - --debug) - debug=yes ;; - *) - echo "Unrecognized option \`$option'" 1>&2 - usage - exit 1 - ;; - esac -done - -# If the debugging feature is enabled, print commands. -if test $debug = yes; then - set -x -fi - -# Initialize these directories here, since ROOTDIR was initialized. -case "$host_os" in -netbsd* | openbsd*) - # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub - # instead of /boot/grub. - grub_prefix=`echo /grub | sed ${transform}` - bootdir=${rootdir} - ;; -*) - # Use /boot/grub by default. - bootdir=${rootdir}/boot - ;; -esac - -grubdir=${bootdir}/`echo grub | sed ${transform}` -device_map=${grubdir}/device.map - -# Check if GRUB is installed. -set $grub_mkimage dummy -if test -f "$1"; then - : -else - echo "$1: Not found." 1>&2 - exit 1 -fi - -set $grub_mkdevicemap dummy -if test -f "$1"; then - : -else - echo "$1: Not found." 1>&2 - exit 1 -fi - -# Create the GRUB directory if it is not present. -mkdir -p "$grubdir" || exit 1 - -# If --recheck is specified, remove the device map, if present. -if test $recheck = yes; then - rm -f $device_map -fi - -# Create the device map file if it is not present. -if test -f "$device_map"; then - : -else - # Create a safe temporary file. - test -n "$mklog" && log_file=`$mklog` - - $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 -fi - -# Make sure that there is no duplicated entry. -tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ - | sort | uniq -d | sed -n 1p` -if test -n "$tmp"; then - echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 - exit 1 -fi - -# Copy the GRUB images to the GRUB directory. -for file in ${grubdir}/*.mod ${grubdir}/*.lst; do - if test -f $file && [ "`basename $file`" != menu.lst ]; then - rm -f $file || exit 1 - fi -done -for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do - cp -f $file ${grubdir} || exit 1 -done - -# Copy gettext files -mkdir -p ${grubdir}/locale/ -for dir in ${localedir}/*; do - if test -f "$dir/LC_MESSAGES/grub.mo"; then - cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" - fi -done - -if ! test -f ${grubdir}/grubenv; then - $grub_editenv ${grubdir}/grubenv create -fi - -# Create the core image. First, auto-detect the filesystem module. -fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}` -if test "x$fs_module" = xfat; then :; else - echo "${grubdir} doesn't look like an EFI partition." 1>&2 - exit 1 -fi - -# Then the partition map module. In order to support partition-less media, -# this command is allowed to fail (--target=fs already grants us that the -# filesystem will be accessible). -partmap_module= -for x in `$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`; do - partmap_module="$partmap_module part_$x"; -done - -# Device abstraction module, if any (lvm, raid). -devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}` - -# The order in this list is critical. Be careful when modifying it. -modules="$modules $fs_module $partmap_module $devabstraction_module" - -$grub_mkimage -p "" -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1 - -# Prompt the user to check if the device map is correct. -echo "Installation finished. No error reported." -echo "This is the contents of the device map $device_map." -echo "Check if this is correct or not. If any of the lines is incorrect," -echo "fix it and re-run the script \`$self'." -echo - -cat $device_map - -# Bye. -exit 0 From 861d5b5c72578b3f95987c9f4d89a83f0da0f61d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 30 Aug 2010 21:00:48 +0200 Subject: [PATCH 0113/1414] Import EFI patch by cjwatson --- util/grub-install.in | 132 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/util/grub-install.in b/util/grub-install.in index 910549d30..4ce451d11 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -24,6 +24,7 @@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ bindir=@bindir@ libdir=@libdir@ +sysconfdir=@sysconfdir@ PACKAGE_NAME=@PACKAGE_NAME@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ @@ -56,6 +57,9 @@ update_nvram=yes ofpathname=`which ofpathname` nvsetenv=`which nvsetenv` +efibootmgr=`which efibootmgr 2>/dev/null || true` +removable=no +efi_quiet= if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=biosdisk @@ -103,6 +107,11 @@ if [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platf cat <&2 + efidir= + fi + fi + + if test -n "$efidir"; then + # The EFI specification requires that an EFI System Partition must + # contain an "EFI" subdirectory, and that OS loaders are stored in + # subdirectories below EFI. Vendors are expected to pick names that do + # not collide with other vendors. To minimise collisions, we use the + # name of our distributor if possible. + if test $removable = yes; then + # The specification makes stricter requirements of removable + # devices, in order that only one image can be automatically loaded + # from them. The image must always reside under /EFI/BOOT, and it + # must have a specific file name depending on the architecture. + efi_distributor=BOOT + case "$target_cpu" in + i386) + efi_file=BOOTIA32.EFI ;; + x86-64) + efi_file=BOOTX64.EFI ;; + # GRUB does not yet support these architectures, but they're defined + # by the specification so we include them here to ease future + # expansion. + ia64) + efi_file=BOOTIA64.EFI ;; + esac + else + efi_distributor="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut -d' ' -f1)" + if test -z "$efi_distributor"; then + efi_distributor=grub + fi + # It is convenient for each architecture to have a different + # efi_file, so that different versions can be installed in parallel. + case "$target_cpu" in + i386) + efi_file=grubia32.efi ;; + x86-64) + efi_file=grubx64.efi ;; + # GRUB does not yet support these architectures, but they're defined + # by the specification so we include them here to ease future + # expansion. + ia64) + efi_file=grubia64.efi ;; + *) + efi_file=grub.efi ;; + esac + # TODO: We should also use efibootmgr, if available, to add a Boot + # entry for ourselves. + fi + efidir="$efidir/EFI/$efi_distributor" + mkdir -p "$efidir" || exit 1 + else + # We don't know what's going on. Fall back to traditional + # (non-specification-compliant) behaviour. + efidir="$grubdir" + efi_distributor= + efi_file=grub.efi + fi + cp ${grubdir}/core.${imgext} ${efidir}/${efi_file} + # Try to make this image bootable using the EFI Boot Manager, if available. + if test "$removable" = no && test -n "$efi_distributor" && \ + test -n "$efibootmgr"; then + # On Linux, we need the efivars kernel modules. + case "$host_os" in + linux*) + modprobe -q efivars 2>/dev/null || true ;; + esac + + # Delete old entries from the same distributor. + for bootnum in `efibootmgr | grep '^Boot[0-9]' | \ + fgrep " $efi_distributor" | cut -b5-8`; do + efibootmgr $efi_quiet -b "$bootnum" -B + done + + # Add a new entry for the image we just created. efibootmgr needs to be + # given the disk device and partition number separately, so we have to + # fiddle about with grub-probe to get hold of this reasonably reliably. + # Use fresh device map text to avoid any problems with stale data, since + # all we need here is a one-to-one mapping. + clean_devmap="$($grub_mkdevicemap --device-map=/dev/stdout)" + efidir_drive="$(echo "$clean_devmap" | $grub_probe --target=drive --device-map=/dev/stdin "$efidir")" + if test -z "$efidir_drive"; then + echo "Can't find GRUB drive for $efidir; unable to create EFI Boot Manager entry." >&2 + else + 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" + fi + fi + fi echo "Installation finished. No error reported." From f15f9c5029692d3ff5c4731cde9bc11e1214f7ac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 02:41:21 +0200 Subject: [PATCH 0114/1414] 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 0115/1414] 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 0116/1414] 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 0117/1414] 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 0118/1414] 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 41a331a8d34879afedb0c8850fa48a63b1e73bcb Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 1 Sep 2010 10:12:41 +0200 Subject: [PATCH 0119/1414] * grub-core/commands/efi/lsefimmap.c: New file. * grub-core/Makefile.core.def (lsefimmap): New module. * include/grub/efi/api.h (PRIxGRUB_EFI_UINTN_T): New definition. Also-By: Robert Millan Also-By: Vladimir Serbinenko --- ChangeLog.gingold3 | 7 ++ grub-core/Makefile.core.def | 8 ++ grub-core/commands/efi/lsefimmap.c | 143 +++++++++++++++++++++++++++++ include/grub/efi/api.h | 2 + 4 files changed, 160 insertions(+) create mode 100644 ChangeLog.gingold3 create mode 100644 grub-core/commands/efi/lsefimmap.c diff --git a/ChangeLog.gingold3 b/ChangeLog.gingold3 new file mode 100644 index 000000000..f8e69c3cd --- /dev/null +++ b/ChangeLog.gingold3 @@ -0,0 +1,7 @@ +2008-01-28 Tristan Gingold +2010-01-18 Robert Millan +2010-08-31 Vladimir Serbinenko + + * grub-core/commands/efi/lsefimmap.c: New file. + * grub-core/Makefile.core.def (lsefimmap): New module. + * include/grub/efi/api.h (PRIxGRUB_EFI_UINTN_T): New definition. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f9cf382f2..576490fbf 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -441,6 +441,14 @@ module = { enable = x86_efi; }; +module = { + name = lsefimmap; + + common = commands/efi/lsefimmap.c; + + enable = x86_efi; +}; + module = { name = blocklist; common = commands/blocklist.c; diff --git a/grub-core/commands/efi/lsefimmap.c b/grub-core/commands/efi/lsefimmap.c new file mode 100644 index 000000000..010fc0d77 --- /dev/null +++ b/grub-core/commands/efi/lsefimmap.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_lsefimmap (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; + 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 grub_errno; + if (grub_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) <= 0) + goto fail; + + 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_uint64_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 < ARRAY_SIZE (types_str)) + grub_printf ("%s ", types_str[desc->type]); + else + grub_printf ("Unk %02x ", desc->type); + + grub_printf (" %016" PRIxGRUB_UINT64_T "-%016" PRIxGRUB_UINT64_T + " %08" PRIxGRUB_EFI_UINTN_T, + desc->physical_start, + desc->physical_start + (desc->num_pages << 12) - 1, + desc->num_pages); + + size = desc->num_pages; + size <<= (12 - 10); + if (size < 1024) + grub_printf (" %4" PRIuGRUB_UINT64_T "KB", size); + else + { + size /= 1024; + if (size < 1024) + grub_printf (" %4" PRIuGRUB_UINT64_T "MB", size); + else + { + size /= 1024; + grub_printf (" %4" PRIuGRUB_UINT64_T "GB", 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"); + } + + fail: + grub_free (memory_map); + return 0; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(lsefimmap) +{ + cmd = grub_register_command ("lsefimmap", grub_cmd_lsefimmap, + "", "Display EFI memory map."); +} + +GRUB_MOD_FINI(lsefimmap) +{ + grub_unregister_command (cmd); +} diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 5eededdc2..cb6b1113b 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -287,6 +287,8 @@ typedef grub_uint64_t grub_efi_uint64_t; typedef grub_uint8_t grub_efi_char8_t; typedef grub_uint16_t grub_efi_char16_t; +#define PRIxGRUB_EFI_UINTN_T "lx" + typedef grub_efi_intn_t grub_efi_status_t; #define GRUB_EFI_ERROR_CODE(value) \ From 4bec80482ea423c27c6de7a008d15ba44f8fbbfd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Sep 2010 10:21:05 +0200 Subject: [PATCH 0120/1414] 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 9a9852df79f459b52d51214ed51863b1828d42b1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 00:07:55 +0200 Subject: [PATCH 0121/1414] Hook network protocols --- grub-core/Makefile.am | 1 + grub-core/commands/net.c | 33 +++++++++++++++++++++++++++++++++ grub-core/kern/device.c | 23 ++++++++++++++++------- grub-core/kern/fs.c | 2 +- include/grub/device.h | 7 +------ include/grub/net.h | 37 +++++++++++++++++++++++++++++++++++-- 6 files changed, 87 insertions(+), 16 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5d13d0313..1fcc3d00d 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/net.h if COND_i386_pc KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h diff --git a/grub-core/commands/net.c b/grub-core/commands/net.c index 288ba4c2a..904c61a92 100644 --- a/grub-core/commands/net.c +++ b/grub-core/commands/net.c @@ -269,6 +269,37 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +grub_net_app_level_t grub_net_app_level_list; + +static grub_net_t +grub_net_open_real (const char *name) +{ + const char *comma = grub_strchr (name, ','); + grub_net_app_level_t proto; + + if (!comma) + comma = name + grub_strlen (name); + FOR_NET_APP_LEVEL (proto) + { + if (comma - name == (grub_ssize_t) grub_strlen (proto->name) + && grub_memcmp (proto->name, name, comma - name) == 0) + { + grub_net_t ret = grub_malloc (sizeof (*ret)); + if (!ret) + return NULL; + ret->protocol = proto; + ret->name = grub_strdup (name); + if (!ret->name) + { + grub_free (ret); + return NULL; + } + return ret; + } + } + return NULL; +} + static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; GRUB_MOD_INIT(net) @@ -285,6 +316,7 @@ GRUB_MOD_INIT(net) cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, "SHORTNAME", N_("Delete a network route.")); + grub_net_open = grub_net_open_real; } GRUB_MOD_FINI(net) @@ -293,4 +325,5 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_deladdr); grub_unregister_command (cmd_addroute); grub_unregister_command (cmd_delroute); + grub_net_open = NULL; } diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 4273fedfe..9de545910 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -26,6 +26,8 @@ #include #include +grub_net_t (*grub_net_open) (const char *name) = NULL; + grub_device_t grub_device_open (const char *name) { @@ -46,15 +48,16 @@ grub_device_open (const char *name) if (! dev) goto fail; + dev->net = NULL; /* Try to open a disk. */ - disk = grub_disk_open (name); - if (! disk) - goto fail; + dev->disk = grub_disk_open (name); + if (dev->disk) + return dev; + if (grub_net_open) + dev->net = grub_net_open (name); - dev->disk = disk; - dev->net = 0; /* FIXME */ - - return dev; + if (dev->net) + return dev; fail: if (disk) @@ -71,6 +74,12 @@ grub_device_close (grub_device_t device) if (device->disk) grub_disk_close (device->disk); + if (device->net) + { + grub_free (device->net->name); + grub_free (device->net); + } + grub_free (device); return grub_errno; diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c index 8ffb93c8b..c4d6efa96 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -95,7 +95,7 @@ grub_fs_probe (grub_device_t device) } } else if (device->net) - return device->net->fs; + return device->net->protocol; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); return 0; diff --git a/include/grub/device.h b/include/grub/device.h index d68c26e66..f3e43bf60 100644 --- a/include/grub/device.h +++ b/include/grub/device.h @@ -24,12 +24,7 @@ #include struct grub_disk; -struct grub_fs; -struct grub_net -{ - char *name; - struct grub_fs *fs; -}; +struct grub_net; struct grub_device { diff --git a/include/grub/net.h b/include/grub/net.h index 4ca873f74..b5e852f9b 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -22,6 +22,17 @@ #include #include #include +#include + +typedef struct grub_fs *grub_net_app_level_t; + +typedef struct grub_net +{ + char *name; + grub_net_app_level_t protocol; +} *grub_net_t; + +extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); struct grub_net_card; @@ -46,7 +57,7 @@ struct grub_net_network_level_interface; typedef union grub_net_network_level_address { grub_uint32_t ipv4; -} grub_net_network_level_netaddress_t; +} grub_net_network_level_address_t; typedef union grub_net_network_level_netaddress { @@ -54,7 +65,7 @@ typedef union grub_net_network_level_netaddress grub_uint32_t base; int masksize; } ipv4; -} grub_net_network_level_address_t; +} grub_net_network_level_netaddress_t; typedef enum grub_network_level_protocol_id { @@ -163,6 +174,28 @@ grub_net_network_level_interface_unregister (struct grub_net_network_level_inter #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) +extern grub_net_app_level_t grub_net_app_level_list; + +#ifndef GRUB_LST_GENERATOR +static inline void +grub_net_app_level_register (grub_net_app_level_t proto) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_app_level_list), + GRUB_AS_LIST (proto)); +} +#endif + +static inline void +grub_net_app_level_unregister (grub_net_app_level_t proto) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_app_level_list), + GRUB_AS_LIST (proto)); +} + +#define FOR_NET_APP_LEVEL(var) FOR_LIST_ELEMENTS((var), \ + (grub_net_app_level_list)) + + extern struct grub_net_route *grub_net_routes; static inline void From 03b170647d564e2211bb9f3745b18d67eb0c4158 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 17:18:02 +0200 Subject: [PATCH 0122/1414] Restructure pxe --- Makefile.util.def | 1 + grub-core/commands/ls.c | 13 ++ grub-core/commands/net.c | 361 +++++++++++++++++++++++++++---------- grub-core/fs/i386/pc/pxe.c | 268 +++++++++++++-------------- include/grub/net.h | 131 +++----------- 5 files changed, 433 insertions(+), 341 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 35bcd81b2..fe6894306 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -30,6 +30,7 @@ library = { common = grub-core/commands/blocklist.c; common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; + common = grub-core/commands/net.c; common = grub-core/disk/dmraid_nvidia.c; common = grub-core/disk/host.c; common = grub-core/disk/loopback.c; diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 9ee0a7a31..3179d271e 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -31,6 +31,7 @@ #include #include #include +#include static const struct grub_arg_option options[] = { @@ -45,6 +46,8 @@ static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'}; static grub_err_t grub_ls_list_devices (int longlist) { + grub_net_app_level_t proto; + auto int grub_ls_print_devices (const char *name); int grub_ls_print_devices (const char *name) { @@ -58,6 +61,16 @@ grub_ls_list_devices (int longlist) grub_device_iterate (grub_ls_print_devices); grub_xputs ("\n"); + + grub_puts_ (N_ ("Network protocols:\n")); + + FOR_NET_APP_LEVEL (proto) + { + grub_printf ("%s ", proto->name); + } + + grub_xputs ("\n"); + grub_refresh (); return 0; diff --git a/grub-core/commands/net.c b/grub-core/commands/net.c index 904c61a92..2062e1bd0 100644 --- a/grub-core/commands/net.c +++ b/grub-core/commands/net.c @@ -22,30 +22,135 @@ #include #include +struct grub_net_route +{ + struct grub_net_route *next; + grub_net_network_level_netaddress_t target; + char *name; + struct grub_net_network_level_protocol *prot; + int is_gateway; + union + { + struct grub_net_network_level_interface *interface; + grub_net_network_level_address_t gw; + }; +}; + struct grub_net_route *grub_net_routes = NULL; struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; struct grub_net_card *grub_net_cards = NULL; struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; -grub_err_t -grub_net_resolve_address (struct grub_net_network_level_protocol **prot, - char *name, - grub_net_network_level_address_t *addr) +static inline void +grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) { - FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot) + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +static inline void +grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) + +static inline void +grub_net_route_register (struct grub_net_route *route) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +static inline void +grub_net_route_unregister (struct grub_net_route *route) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes), + GRUB_AS_LIST (route)); +} + +#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) + +static int +parse_ip (const char *val, grub_uint32_t *ip, const char **rest) +{ + grub_uint32_t newip = 0; + unsigned long t; + int i; + const char *ptr = val; + + for (i = 0; i < 4; i++) { - grub_err_t err; - err = grub_net_resolve_address_in_protocol (*prot, name, addr); - if (err == GRUB_ERR_NET_BAD_ADDRESS) + t = grub_strtoul (ptr, (char **) &ptr, 0); + if (grub_errno) { grub_errno = GRUB_ERR_NONE; - continue; + return 0; } - if (err) - return err; + if (t & ~0xff) + return 0; + newip >>= 8; + newip |= (t << 24); + if (i != 3 && *ptr != '.') + return 0; + ptr++; + } + *ip = newip; + if (rest) + *rest = ptr - 1; + return 0; +} + +static int +match_net (const grub_net_network_level_netaddress_t *net, + const grub_net_network_level_address_t *addr) +{ + if (net->type != addr->type) + return 0; + switch (net->type) + { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: + { + grub_int32_t mask = (1 << net->ipv4.masksize) - 1; + return ((net->ipv4.base & mask) == (addr->ipv4 & mask)); + } + } + return 0; +} + +grub_err_t +grub_net_resolve_address (const char *name, + grub_net_network_level_address_t *addr) +{ + if (parse_ip (name, &addr->ipv4, NULL)) + { + addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; return GRUB_ERR_NONE; } - return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("Unrecognised address %s"), + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unrecognised address %s"), + name); +} + +grub_err_t +grub_net_resolve_net_address (const char *name, + grub_net_network_level_netaddress_t *addr) +{ + const char *rest; + if (parse_ip (name, &addr->ipv4.base, &rest)) + { + addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + if (*rest == '/') + { + addr->ipv4.masksize = grub_strtoul (rest + 1, NULL, 0); + if (!grub_errno) + return GRUB_ERR_NONE; + } + addr->ipv4.masksize = 32; + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unrecognised address %s"), name); } @@ -71,8 +176,7 @@ grub_net_route_address (grub_net_network_level_address_t addr, { if (depth && prot != route->prot) continue; - prot = route->prot; - if (!route->prot->match_net (route->target, curtarget)) + if (!match_net (&route->target, &curtarget)) continue; if (route->is_gateway) @@ -107,7 +211,6 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); - inter->protocol->fini (inter); grub_net_network_level_interface_unregister (inter); grub_free (inter->name); grub_free (inter); @@ -115,18 +218,35 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +struct grub_net_network_level_interface * +grub_net_add_addr (const char *name, struct grub_net_card *card, + grub_net_network_level_address_t addr) +{ + struct grub_net_network_level_interface *inter; + + inter = grub_zalloc (sizeof (*inter)); + if (!inter) + return NULL; + + inter->name = grub_strdup (name); + grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); + inter->card = card; + + grub_net_network_level_interface_register (inter); + + return inter; +} + static grub_err_t grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { struct grub_net_card *card; - struct grub_net_network_level_protocol *prot; - grub_err_t err; grub_net_network_level_address_t addr; - struct grub_net_network_level_interface *inter; + grub_err_t err; - if (argc != 4) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); + if (argc != 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected")); FOR_NET_CARDS (card) if (grub_strcmp (card->name, args[1])) @@ -134,36 +254,12 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), if (card == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); - FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot) - if (grub_strcmp (prot->name, args[2])) - break; - - if (card == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); - - err = grub_net_resolve_address_in_protocol (prot, args[3], &addr); + err = grub_net_resolve_address (args[2], &addr); if (err) return err; - inter = grub_zalloc (sizeof (*inter)); - if (!inter) - return grub_errno; - - inter->name = grub_strdup (args[0]); - inter->protocol = prot; - grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); - inter->card = card; - - err = prot->init (inter); - if (err) - { - grub_free (inter->name); - grub_free (inter); - return err; - } - grub_net_network_level_interface_register (inter); - - return GRUB_ERR_NONE; + grub_net_add_addr (args[0], card, addr); + return grub_errno; } static grub_err_t @@ -188,84 +284,157 @@ grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } -static grub_err_t -grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) +grub_err_t +grub_net_add_route (const char *name, + grub_net_network_level_netaddress_t target, + struct grub_net_network_level_interface *inter) { - struct grub_net_network_level_protocol *prot; struct grub_net_route *route; - if (argc < 3) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("At least 3 arguments are expected")); - route = grub_zalloc (sizeof (*route)); if (!route) return grub_errno; - route->name = grub_strdup (args[0]); + route->name = grub_strdup (name); if (!route->name) { grub_free (route); return grub_errno; } - FOR_NET_NETWORK_LEVEL_PROTOCOLS(prot) - { - grub_err_t err; - err = prot->net_ntoa (args[1], &(route->target)); - if (err == GRUB_ERR_NET_BAD_ADDRESS) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - if (err) - return err; - break; - } - - if (!prot) + route->target = target; + route->is_gateway = 0; + route->interface = inter; + + grub_net_route_register (route); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_net_add_route_gw (const char *name, + grub_net_network_level_netaddress_t target, + grub_net_network_level_address_t gw) +{ + struct grub_net_route *route; + + route = grub_zalloc (sizeof (*route)); + if (!route) + return grub_errno; + + route->name = grub_strdup (name); + if (!route->name) { - grub_free (route->name); grub_free (route); - return grub_error (GRUB_ERR_NET_BAD_ADDRESS, - N_("Unrecognised address %s"), args[1]); + return grub_errno; } + route->target = target; + route->is_gateway = 1; + route->gw = gw; + + grub_net_route_register (route); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_net_network_level_netaddress_t target; + if (argc < 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("At least 3 arguments are expected")); + + grub_net_resolve_net_address (args[1], &target); + if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) { grub_err_t err; - route->is_gateway = 1; - err = grub_net_resolve_address_in_protocol (prot, - args[3], &(route->gw)); + grub_net_network_level_address_t gw; + + err = grub_net_resolve_address (args[3], &gw); if (err) - { - grub_free (route->name); - grub_free (route); - return err; - } + return err; + return grub_net_add_route_gw (args[0], target, gw); } else { struct grub_net_network_level_interface *inter; - route->is_gateway = 0; FOR_NET_NETWORK_LEVEL_INTERFACES (inter) if (grub_strcmp (inter->name, args[2])) break; if (!inter) - { - grub_free (route->name); - grub_free (route); - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("Unrecognised interface %s"), args[2]); - } - route->interface = inter; + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unrecognised interface %s"), args[2]); + return grub_net_add_route (args[0], target, inter); } +} - grub_net_route_register (route); +static void +print_net_address (const grub_net_network_level_netaddress_t *target) +{ + switch (target->type) + { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: + grub_printf ("%d.%d.%d.%d/%d ", ((target->ipv4.base >> 24) & 0xff), + ((target->ipv4.base >> 16) & 0xff), + ((target->ipv4.base >> 8) & 0xff), + ((target->ipv4.base >> 0) & 0xff), + target->ipv4.masksize); + break; + } +} +static void +print_address (const grub_net_network_level_address_t *target) +{ + switch (target->type) + { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: + grub_printf ("%d.%d.%d.%d ", ((target->ipv4 >> 24) & 0xff), + ((target->ipv4 >> 16) & 0xff), + ((target->ipv4 >> 8) & 0xff), + ((target->ipv4 >> 0) & 0xff)); + break; + } +} + +static grub_err_t +grub_cmd_listroutes (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_net_route *route; + FOR_NET_ROUTES(route) + { + grub_printf ("%s ", route->name); + print_net_address (&route->target); + if (route->is_gateway) + { + grub_printf ("gw "); + print_address (&route->gw); + } + else + grub_printf ("%s", route->interface->name); + } + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_net_card *card; + FOR_NET_CARDS(card) + { + grub_printf ("%s ", card->name); + } + grub_printf ("\n"); return GRUB_ERR_NONE; } @@ -301,11 +470,12 @@ grub_net_open_real (const char *name) } static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; +static grub_command_t cmd_lsroutes, cmd_lscards; GRUB_MOD_INIT(net) { cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, - "SHORTNAME CARD PROTOCOL ADDRESS", + "SHORTNAME CARD ADDRESS", N_("Add a network address.")); cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, "SHORTNAME", @@ -316,6 +486,11 @@ GRUB_MOD_INIT(net) cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, "SHORTNAME", N_("Delete a network route.")); + cmd_lsroutes = grub_register_command ("net_ls_routes", grub_cmd_listroutes, + "", N_("list network routes")); + cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards, + "", N_("list network cards")); + grub_net_open = grub_net_open_real; } @@ -325,5 +500,7 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_deladdr); grub_unregister_command (cmd_addroute); grub_unregister_command (cmd_delroute); + grub_unregister_command (cmd_lsroutes); + grub_unregister_command (cmd_lscards); grub_net_open = NULL; } diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index 0dd44a30a..20d0e1979 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -18,9 +18,8 @@ */ #include -#include +#include #include -#include #include #include #include @@ -33,13 +32,7 @@ #define SEGMENT(x) ((x) >> 4) #define OFFSET(x) ((x) & 0xF) #define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) -#define LINEAR(x) (void *) (((x >> 16) <<4) + (x & 0xFFFF)) - -struct grub_pxe_disk_data -{ - grub_uint32_t server_ip; - grub_uint32_t gateway_ip; -}; +#define LINEAR(x) (void *) (((x >> 16) << 4) + (x & 0xFFFF)) struct grub_pxenv *grub_pxe_pxenv; static grub_uint32_t grub_pxe_your_ip; @@ -53,6 +46,8 @@ struct grub_pxe_data { grub_uint32_t packet_number; grub_uint32_t block_size; + grub_uint32_t server_ip; + grub_uint32_t gateway_ip; char filename[0]; }; @@ -95,55 +90,33 @@ grub_pxe_scan (void) return ret; } -static int -grub_pxe_iterate (int (*hook) (const char *name)) +static grub_err_t +grub_pxefs_dir (grub_device_t device __attribute__ ((unused)), + const char *path __attribute__ ((unused)), + int (*hook) (const char *filename, + const struct grub_dirhook_info *info) + __attribute__ ((unused))) { - if (hook ("pxe")) - return 1; - return 0; + return GRUB_ERR_NONE; } static grub_err_t -parse_ip (const char *val, grub_uint32_t *ip, const char **rest) +grub_pxefs_open (struct grub_file *file, const char *name) { - grub_uint32_t newip = 0; - unsigned long t; - int i; - const char *ptr = val; - - for (i = 0; i < 4; i++) + union { - t = grub_strtoul (ptr, (char **) &ptr, 0); - if (grub_errno) - return grub_errno; - if (t & ~0xff) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); - newip >>= 8; - newip |= (t << 24); - if (i != 3 && *ptr != '.') - return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); - ptr++; - } - *ip = newip; - if (rest) - *rest = ptr - 1; - return 0; -} - -static grub_err_t -grub_pxe_open (const char *name, grub_disk_t disk) -{ - struct grub_pxe_disk_data *data; - - if (grub_strcmp (name, "pxe") != 0 - && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk"); + struct grub_pxenv_tftp_get_fsize c1; + struct grub_pxenv_tftp_open c2; + } c; + struct grub_pxe_data *data; + grub_file_t file_int, bufio; data = grub_malloc (sizeof (*data)); if (!data) return grub_errno; - if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) +#if 0 + if (grub_strncmp (file->device->net->name, "pxe:", sizeof ("pxe:") - 1) == 0) { const char *ptr; grub_err_t err; @@ -161,93 +134,44 @@ grub_pxe_open (const char *name, grub_disk_t disk) else data->gateway_ip = grub_pxe_default_gateway_ip; } - else + else +#endif { - data->server_ip = grub_pxe_default_server_ip; - data->gateway_ip = grub_pxe_default_gateway_ip; + grub_net_network_level_address_t addr; + grub_net_network_level_address_t gateway; + struct grub_net_network_level_interface *interf; + grub_err_t err; + + if (grub_strncmp (file->device->net->name, + "pxe,", sizeof ("pxe,") - 1) == 0) + { + const char *ptr; + + ptr = name + sizeof ("pxe,") - 1; + err = grub_net_resolve_address (name + sizeof ("pxe,") - 1, &addr); + if (err) + return err; + } + else + { + addr.ipv4 = grub_pxe_default_server_ip; + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + } + err = grub_net_route_address (addr, &gateway, &interf); + if (err) + return err; + data->server_ip = addr.ipv4; + data->gateway_ip = gateway.ipv4; } - disk->total_sectors = 0; - disk->id = (unsigned long) data; - - disk->has_partitions = 0; - disk->data = data; - - return GRUB_ERR_NONE; -} - -static void -grub_pxe_close (grub_disk_t disk) -{ - grub_free (disk->data); -} - -static grub_err_t -grub_pxe_read (grub_disk_t disk __attribute((unused)), - grub_disk_addr_t sector __attribute((unused)), - grub_size_t size __attribute((unused)), - char *buf __attribute((unused))) -{ - return GRUB_ERR_OUT_OF_RANGE; -} - -static grub_err_t -grub_pxe_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_OUT_OF_RANGE; -} - -static struct grub_disk_dev grub_pxe_dev = - { - .name = "pxe", - .id = GRUB_DISK_DEVICE_PXE_ID, - .iterate = grub_pxe_iterate, - .open = grub_pxe_open, - .close = grub_pxe_close, - .read = grub_pxe_read, - .write = grub_pxe_write, - .next = 0 - }; - -static grub_err_t -grub_pxefs_dir (grub_device_t device, - const char *path __attribute__ ((unused)), - int (*hook) (const char *filename, - const struct grub_dirhook_info *info) - __attribute__ ((unused))) -{ - if (device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID) - return grub_error (GRUB_ERR_IO, "not a pxe disk"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_pxefs_open (struct grub_file *file, const char *name) -{ - union - { - struct grub_pxenv_tftp_get_fsize c1; - struct grub_pxenv_tftp_open c2; - } c; - struct grub_pxe_data *data; - struct grub_pxe_disk_data *disk_data = file->device->disk->data; - grub_file_t file_int, bufio; - - if (file->device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID) - return grub_error (GRUB_ERR_IO, "not a pxe disk"); - if (curr_file != 0) { grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2, pxe_rm_entry); curr_file = 0; } - c.c1.server_ip = disk_data->server_ip; - c.c1.gateway_ip = disk_data->gateway_ip; + c.c1.server_ip = data->server_ip; + c.c1.gateway_ip = data->gateway_ip; grub_strcpy ((char *)&c.c1.filename[0], name); grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry); if (c.c1.status) @@ -297,7 +221,6 @@ 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; data = file->data; @@ -317,8 +240,8 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) if (curr_file != 0) grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o, pxe_rm_entry); - o.server_ip = disk_data->server_ip; - o.gateway_ip = disk_data->gateway_ip; + o.server_ip = data->server_ip; + o.gateway_ip = data->gateway_ip; grub_strcpy ((char *)&o.filename[0], data->filename); o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); o.packet_size = grub_pxe_blksize; @@ -513,18 +436,46 @@ grub_pxe_detect (void) grub_pxe_pxenv = pxenv; } +static grub_size_t +grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)), + void *buf __attribute__ ((unused)), + grub_size_t buflen __attribute__ ((unused))) +{ + return 0; +} + +static grub_err_t +grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), + void *buf __attribute__ ((unused)), + grub_size_t buflen __attribute__ ((unused))) +{ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "not implemented"); +} + +struct grub_net_card_driver grub_pxe_card_driver = +{ + .send = grub_pxe_send, + .recv = grub_pxe_recv +}; + +struct grub_net_card grub_pxe_card = +{ + .driver = &grub_pxe_card_driver, + .name = "pxe" +}; + void grub_pxe_unload (void) { if (grub_pxe_pxenv) { - grub_fs_unregister (&grub_pxefs_fs); - grub_disk_dev_unregister (&grub_pxe_dev); - + grub_net_app_level_unregister (&grub_pxefs_fs); + grub_net_card_unregister (&grub_pxe_card); grub_pxe_pxenv = 0; } } +#if 0 static void set_ip_env (char *varname, grub_uint32_t ip) { @@ -556,7 +507,9 @@ write_ip_env (grub_uint32_t *ip, const char *val) return buf; } +#endif +#if 0 static char * grub_env_write_pxe_default_server (struct grub_env_var *var __attribute__ ((unused)), @@ -572,6 +525,7 @@ grub_env_write_pxe_default_gateway (struct grub_env_var *var { return write_ip_env (&grub_pxe_default_gateway_ip, val); } +#endif static char * grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), @@ -598,34 +552,58 @@ grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), return buf; } - GRUB_MOD_INIT(pxe) { grub_pxe_detect (); if (grub_pxe_pxenv) { char *buf; + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inter; + +#if 0 + grub_register_variable_hook ("pxe_default_server", 0, + grub_env_write_pxe_default_server); + grub_register_variable_hook ("pxe_default_gateway", 0, + grub_env_write_pxe_default_gateway); +#endif + grub_register_variable_hook ("pxe_blksize", 0, + grub_env_write_pxe_blocksize); buf = grub_xasprintf ("%d", grub_pxe_blksize); if (buf) grub_env_set ("pxe_blksize", buf); grub_free (buf); +#if 0 set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); - set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip); - set_ip_env ("net_pxe_ip", grub_pxe_your_ip); - grub_register_variable_hook ("pxe_default_server", 0, - grub_env_write_pxe_default_server); - grub_register_variable_hook ("pxe_default_gateway", 0, - grub_env_write_pxe_default_gateway); +#endif - /* XXX: Is it possible to change IP in PXE? */ - grub_register_variable_hook ("net_pxe_ip", 0, - grub_env_write_readonly); - grub_register_variable_hook ("pxe_blksize", 0, - grub_env_write_pxe_blocksize); - grub_disk_dev_register (&grub_pxe_dev); - grub_fs_register (&grub_pxefs_fs); + grub_net_app_level_register (&grub_pxefs_fs); + grub_net_card_register (&grub_pxe_card); + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + addr.ipv4 = grub_pxe_your_ip; + inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr); + if (grub_pxe_default_gateway_ip) + { + grub_net_network_level_netaddress_t target; + grub_net_network_level_address_t gw; + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = grub_pxe_default_server_ip; + target.ipv4.masksize = 32; + gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + gw.ipv4 = grub_pxe_default_gateway_ip; + grub_net_add_route_gw ("pxe_default", target, gw); + } + { + grub_net_network_level_netaddress_t target; + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = grub_pxe_default_gateway_ip ? + : grub_pxe_default_server_ip; + target.ipv4.masksize = 32; + grub_net_add_route ("pxe_default", target, inter); + } } } diff --git a/include/grub/net.h b/include/grub/net.h index b5e852f9b..84e881efe 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -54,71 +54,37 @@ struct grub_net_card struct grub_net_network_level_interface; +typedef enum grub_network_level_protocol_id +{ + GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 +} grub_network_level_protocol_id_t; + typedef union grub_net_network_level_address { + grub_network_level_protocol_id_t type; grub_uint32_t ipv4; } grub_net_network_level_address_t; typedef union grub_net_network_level_netaddress { + grub_network_level_protocol_id_t type; struct { grub_uint32_t base; int masksize; } ipv4; } grub_net_network_level_netaddress_t; -typedef enum grub_network_level_protocol_id -{ - GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 -} grub_network_level_protocol_id_t; - struct grub_net_network_level_interface; -struct grub_net_network_level_protocol -{ - struct grub_net_network_level_protocol *next; - char *name; - grub_network_level_protocol_id_t id; - grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr); - char * (*aton) (union grub_net_network_level_address addr); - grub_err_t (*net_ntoa) (char *name, - grub_net_network_level_netaddress_t *addr); - char * (*net_aton) (grub_net_network_level_netaddress_t addr); - int (* match_net) (grub_net_network_level_netaddress_t net, - grub_net_network_level_address_t addr); - grub_err_t (*init) (struct grub_net_network_level_interface *dev); - grub_err_t (*fini) (struct grub_net_network_level_interface *dev); - grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf, - grub_size_t buflen); - grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf, - grub_size_t buflen); -}; - struct grub_net_network_level_interface { struct grub_net_network_level_interface *next; char *name; - /* Underlying protocol. */ - struct grub_net_network_level_protocol *protocol; struct grub_net_card *card; union grub_net_network_level_address address; void *data; }; -struct grub_net_route -{ - struct grub_net_route *next; - grub_net_network_level_netaddress_t target; - char *name; - struct grub_net_network_level_protocol *prot; - int is_gateway; - union - { - struct grub_net_network_level_interface *interface; - grub_net_network_level_address_t gw; - }; -}; - struct grub_net_session; struct grub_net_session_level_protocol @@ -156,24 +122,12 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, return session->protocol->recv (session, buf, size); } +struct grub_net_network_level_interface * +grub_net_add_addr (const char *name, struct grub_net_card *card, + grub_net_network_level_address_t addr); + extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; -static inline void -grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); -} - -static inline void -grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); -} - -#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) - extern grub_net_app_level_t grub_net_app_level_list; #ifndef GRUB_LST_GENERATOR @@ -195,25 +149,6 @@ grub_net_app_level_unregister (grub_net_app_level_t proto) #define FOR_NET_APP_LEVEL(var) FOR_LIST_ELEMENTS((var), \ (grub_net_app_level_list)) - -extern struct grub_net_route *grub_net_routes; - -static inline void -grub_net_route_register (struct grub_net_route *route) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_routes), - GRUB_AS_LIST (route)); -} - -static inline void -grub_net_route_unregister (struct grub_net_route *route) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes), - GRUB_AS_LIST (route)); -} - -#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) - extern struct grub_net_card *grub_net_cards; static inline void @@ -232,44 +167,32 @@ grub_net_card_unregister (struct grub_net_card *card) #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) -extern struct grub_net_network_level_protocol *grub_net_network_level_protocols; - -static inline void -grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols), - GRUB_AS_LIST (prot)); -} - -static inline void -grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols), - GRUB_AS_LIST (prot)); -} - -#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next) - -static inline grub_err_t -grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot, - char *name, - grub_net_network_level_address_t *addr) -{ - return prot->ntoa (name, addr); -} - struct grub_net_session * grub_net_open_tcp (char *address, grub_uint16_t port); grub_err_t -grub_net_resolve_address (struct grub_net_network_level_protocol **prot, - char *name, +grub_net_resolve_address (const char *name, grub_net_network_level_address_t *addr); +grub_err_t +grub_net_resolve_net_address (const char *name, + grub_net_network_level_netaddress_t *addr); + grub_err_t grub_net_route_address (grub_net_network_level_address_t addr, grub_net_network_level_address_t *gateway, struct grub_net_network_level_interface **interf); +grub_err_t +grub_net_add_route (const char *name, + grub_net_network_level_netaddress_t target, + struct grub_net_network_level_interface *inter); + +grub_err_t +grub_net_add_route_gw (const char *name, + grub_net_network_level_netaddress_t target, + grub_net_network_level_address_t gw); + + #endif /* ! GRUB_NET_HEADER */ From e571f2332e90dec534f0b8beb1a943b699c1271b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 18:15:59 +0200 Subject: [PATCH 0123/1414] Fix regressions by previous commits --- grub-core/commands/ls.c | 6 ++++-- grub-core/commands/net.c | 38 +++++++++++++++++++++++++------------- grub-core/fs/i386/pc/pxe.c | 8 ++++---- grub-core/kern/device.c | 7 +++++-- include/grub/net.h | 22 ++++++++++++++-------- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 3179d271e..300c21cc9 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -47,6 +47,7 @@ static grub_err_t grub_ls_list_devices (int longlist) { grub_net_app_level_t proto; + int first = 1; auto int grub_ls_print_devices (const char *name); int grub_ls_print_devices (const char *name) @@ -62,10 +63,11 @@ grub_ls_list_devices (int longlist) grub_device_iterate (grub_ls_print_devices); grub_xputs ("\n"); - grub_puts_ (N_ ("Network protocols:\n")); - FOR_NET_APP_LEVEL (proto) { + if (first) + grub_puts_ (N_ ("Network protocols:")); + first = 0; grub_printf ("%s ", proto->name); } diff --git a/grub-core/commands/net.c b/grub-core/commands/net.c index 2062e1bd0..9d28c2ff7 100644 --- a/grub-core/commands/net.c +++ b/grub-core/commands/net.c @@ -97,7 +97,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) return 0; ptr++; } - *ip = newip; + *ip = grub_cpu_to_le32 (newip); if (rest) *rest = ptr - 1; return 0; @@ -114,7 +114,8 @@ match_net (const grub_net_network_level_netaddress_t *net, case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_int32_t mask = (1 << net->ipv4.masksize) - 1; - return ((net->ipv4.base & mask) == (addr->ipv4 & mask)); + return ((grub_be_to_cpu32 (net->ipv4.base) & mask) + == (grub_be_to_cpu32 (addr->ipv4) & mask)); } } return 0; @@ -380,13 +381,17 @@ print_net_address (const grub_net_network_level_netaddress_t *target) switch (target->type) { case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - grub_printf ("%d.%d.%d.%d/%d ", ((target->ipv4.base >> 24) & 0xff), - ((target->ipv4.base >> 16) & 0xff), - ((target->ipv4.base >> 8) & 0xff), - ((target->ipv4.base >> 0) & 0xff), - target->ipv4.masksize); - break; + { + grub_uint32_t n = grub_be_to_cpu32 (target->ipv4.base); + grub_printf ("%d.%d.%d.%d/%d ", ((n >> 24) & 0xff), + ((n >> 16) & 0xff), + ((n >> 8) & 0xff), + ((n >> 0) & 0xff), + target->ipv4.masksize); + } + return; } + grub_printf ("Unknown address type %d\n", target->type); } static void @@ -395,12 +400,16 @@ print_address (const grub_net_network_level_address_t *target) switch (target->type) { case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - grub_printf ("%d.%d.%d.%d ", ((target->ipv4 >> 24) & 0xff), - ((target->ipv4 >> 16) & 0xff), - ((target->ipv4 >> 8) & 0xff), - ((target->ipv4 >> 0) & 0xff)); - break; + { + grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); + grub_printf ("%d.%d.%d.%d ", ((n >> 24) & 0xff), + ((n >> 16) & 0xff), + ((n >> 8) & 0xff), + ((n >> 0) & 0xff)); + } + return; } + grub_printf ("Unknown address type %d\n", target->type); } static grub_err_t @@ -420,6 +429,7 @@ grub_cmd_listroutes (struct grub_command *cmd __attribute__ ((unused)), } else grub_printf ("%s", route->interface->name); + grub_printf ("\n"); } return GRUB_ERR_NONE; } @@ -466,6 +476,8 @@ grub_net_open_real (const char *name) return ret; } } + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); + return NULL; } diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index eac3bf770..85d138bb0 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -306,7 +306,7 @@ grub_pxefs_label (grub_device_t device __attribute ((unused)), static struct grub_fs grub_pxefs_fs = { - .name = "pxefs", + .name = "pxe", .dir = grub_pxefs_dir, .open = grub_pxefs_open, .read = grub_pxefs_read, @@ -590,7 +590,7 @@ GRUB_MOD_INIT(pxe) addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = grub_pxe_your_ip; inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr); - if (grub_pxe_default_gateway_ip) + if (grub_pxe_default_gateway_ip != grub_pxe_default_server_ip) { grub_net_network_level_netaddress_t target; grub_net_network_level_address_t gw; @@ -600,7 +600,7 @@ GRUB_MOD_INIT(pxe) target.ipv4.masksize = 32; gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; gw.ipv4 = grub_pxe_default_gateway_ip; - grub_net_add_route_gw ("pxe_default", target, gw); + grub_net_add_route_gw ("pxe_gw", target, gw); } { grub_net_network_level_netaddress_t target; @@ -608,7 +608,7 @@ GRUB_MOD_INIT(pxe) target.ipv4.base = grub_pxe_default_gateway_ip ? : grub_pxe_default_server_ip; target.ipv4.masksize = 32; - grub_net_add_route ("pxe_default", target, inter); + grub_net_add_route ("pxe", target, inter); } } } diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 9de545910..545487a6b 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -53,8 +53,11 @@ grub_device_open (const char *name) dev->disk = grub_disk_open (name); if (dev->disk) return dev; - if (grub_net_open) - dev->net = grub_net_open (name); + if (grub_net_open && grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + { + grub_errno = GRUB_ERR_NONE; + dev->net = grub_net_open (name); + } if (dev->net) return dev; diff --git a/include/grub/net.h b/include/grub/net.h index 84e881efe..4efd79f79 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -59,19 +59,25 @@ typedef enum grub_network_level_protocol_id GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 } grub_network_level_protocol_id_t; -typedef union grub_net_network_level_address +typedef struct grub_net_network_level_address { grub_network_level_protocol_id_t type; - grub_uint32_t ipv4; + union + { + grub_uint32_t ipv4; + }; } grub_net_network_level_address_t; -typedef union grub_net_network_level_netaddress +typedef struct grub_net_network_level_netaddress { grub_network_level_protocol_id_t type; - struct { - grub_uint32_t base; - int masksize; - } ipv4; + union + { + struct { + grub_uint32_t base; + int masksize; + } ipv4; + }; } grub_net_network_level_netaddress_t; struct grub_net_network_level_interface; @@ -81,7 +87,7 @@ struct grub_net_network_level_interface struct grub_net_network_level_interface *next; char *name; struct grub_net_card *card; - union grub_net_network_level_address address; + grub_net_network_level_address_t address; void *data; }; From 0f37e4936515fb9d2c2204d3640d33a2a5ae4595 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 20:00:56 +0200 Subject: [PATCH 0124/1414] Implement few variables --- grub-core/commands/net.c | 141 +++++++++++++++++++++++++++++++------ grub-core/fs/i386/pc/pxe.c | 35 +++------ include/grub/net.h | 35 ++++++++- 3 files changed, 161 insertions(+), 50 deletions(-) diff --git a/grub-core/commands/net.c b/grub-core/commands/net.c index 9d28c2ff7..5a21178e5 100644 --- a/grub-core/commands/net.c +++ b/grub-core/commands/net.c @@ -21,6 +21,7 @@ #include #include #include +#include struct grub_net_route { @@ -41,13 +42,6 @@ struct grub_net_network_level_interface *grub_net_network_level_interfaces = NUL struct grub_net_card *grub_net_cards = NULL; struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; -static inline void -grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); -} - static inline void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) { @@ -212,6 +206,10 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); + if (inter->flags & GRUB_NET_INTERFACE_PERMANENT) + return grub_error (GRUB_ERR_IO, + N_("you can't delete this address")); + grub_net_network_level_interface_unregister (inter); grub_free (inter->name); grub_free (inter); @@ -219,9 +217,104 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +/* + Currently suppoerted adresses: + IPv4: XXX.XXX.XXX.XXX + */ +#define MAX_STR_ADDR_LEN sizeof ("XXX.XXX.XXX.XXX") + +static void +addr_to_str (const grub_net_network_level_address_t *target, char *buf) +{ + switch (target->type) + { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: + { + grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); + grub_snprintf (buf, MAX_STR_ADDR_LEN, "%d.%d.%d.%d", + ((n >> 24) & 0xff), ((n >> 16) & 0xff), + ((n >> 8) & 0xff), ((n >> 0) & 0xff)); + } + return; + } + grub_printf ("Unknown address type %d\n", target->type); +} + +/* + Currently suppoerted adresses: + ethernet: XX:XX:XX:XX:XX:XX + */ + +#define MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) + +static void +hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) +{ + str[0] = 0; + switch (addr->type) + { + case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: + { + char *ptr; + unsigned i; + for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++) + { + grub_snprintf (ptr, MAX_STR_HWADDR_LEN - (ptr - str), + "%02x:", addr->mac[i] & 0xff); + ptr += (sizeof ("XX:") - 1); + } + return; + } + } + grub_printf ("Unsupported hw address type %d\n", addr->type); +} + +/* FIXME: implement this. */ +static char * +hwaddr_set_env (struct grub_env_var *var __attribute__ ((unused)), + const char *val __attribute__ ((unused))) +{ + return NULL; +} + +/* FIXME: implement this. */ +static char * +addr_set_env (struct grub_env_var *var __attribute__ ((unused)), + const char *val __attribute__ ((unused))) +{ + return NULL; +} + +static void +grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) +{ + { + char buf[MAX_STR_HWADDR_LEN]; + char name[grub_strlen (inter->name) + sizeof ("net__mac")]; + hwaddr_to_str (&inter->hwaddress, buf); + grub_snprintf (name, sizeof (name), "net_%s_mac", inter->name); + grub_env_set (name, buf); + grub_register_variable_hook (name, 0, hwaddr_set_env); + } + + { + char buf[MAX_STR_ADDR_LEN]; + char name[grub_strlen (inter->name) + sizeof ("net__ip")]; + addr_to_str (&inter->address, buf); + grub_snprintf (name, sizeof (name), "net_%s_ip", inter->name); + grub_env_set (name, buf); + grub_register_variable_hook (name, 0, addr_set_env); + } + + grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), + GRUB_AS_LIST (inter)); +} + struct grub_net_network_level_interface * grub_net_add_addr (const char *name, struct grub_net_card *card, - grub_net_network_level_address_t addr) + grub_net_network_level_address_t addr, + grub_net_link_level_address_t hwaddress, + grub_net_interface_flags_t flags) { struct grub_net_network_level_interface *inter; @@ -231,6 +324,8 @@ grub_net_add_addr (const char *name, struct grub_net_card *card, inter->name = grub_strdup (name); grub_memcpy (&(inter->address), &addr, sizeof (inter->address)); + grub_memcpy (&(inter->hwaddress), &hwaddress, sizeof (inter->hwaddress)); + inter->flags = flags; inter->card = card; grub_net_network_level_interface_register (inter); @@ -238,6 +333,7 @@ grub_net_add_addr (const char *name, struct grub_net_card *card, return inter; } +/* FIXME: support MAC specifying. */ static grub_err_t grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) @@ -245,6 +341,7 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), struct grub_net_card *card; grub_net_network_level_address_t addr; grub_err_t err; + grub_net_interface_flags_t flags = 0; if (argc != 3) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected")); @@ -259,7 +356,15 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), if (err) return err; - grub_net_add_addr (args[0], card, addr); + if (card->flags & GRUB_NET_CARD_NO_MANUAL_INTERFACES) + return grub_error (GRUB_ERR_IO, + "this card doesn't support address addition"); + + if (card->flags & GRUB_NET_CARD_HWADDRESS_IMMUTABLE) + flags |= GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE; + + grub_net_add_addr (args[0], card, addr, card->default_address, + flags); return grub_errno; } @@ -397,19 +502,9 @@ print_net_address (const grub_net_network_level_netaddress_t *target) static void print_address (const grub_net_network_level_address_t *target) { - switch (target->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - { - grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); - grub_printf ("%d.%d.%d.%d ", ((n >> 24) & 0xff), - ((n >> 16) & 0xff), - ((n >> 8) & 0xff), - ((n >> 0) & 0xff)); - } - return; - } - grub_printf ("Unknown address type %d\n", target->type); + char buf[MAX_STR_ADDR_LEN]; + addr_to_str (target, buf); + grub_xputs (buf); } static grub_err_t @@ -487,7 +582,7 @@ static grub_command_t cmd_lsroutes, cmd_lscards; GRUB_MOD_INIT(net) { cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, - "SHORTNAME CARD ADDRESS", + "SHORTNAME CARD ADDRESS [HWADDRESS]", N_("Add a network address.")); cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, "SHORTNAME", diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index 85d138bb0..1d9ea8f89 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -41,6 +41,7 @@ static grub_uint32_t grub_pxe_default_gateway_ip; static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE; static grub_file_t curr_file = 0; +static grub_net_link_level_address_t pxe_hwaddr; struct grub_pxe_data { @@ -322,29 +323,6 @@ grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), return NULL; } -static void -set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len) -{ - char buf[(sizeof ("XX:") - 1) * mac_len + 1]; - char *ptr = buf; - unsigned i; - - for (i = 0; i < mac_len; i++) - { - grub_snprintf (ptr, sizeof (buf) - (ptr - buf), - "%02x:", mac_addr[i] & 0xff); - ptr += (sizeof ("XX:") - 1); - } - if (mac_len) - *(ptr - 1) = 0; - else - buf[0] = 0; - - grub_env_set ("net_pxe_mac", buf); - /* XXX: Is it possible to change MAC in PXE? */ - grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly); -} - static void set_env_limn_ro (const char *varname, char *value, grub_size_t len) { @@ -432,8 +410,10 @@ grub_pxe_detect (void) grub_pxe_your_ip = bp->your_ip; grub_pxe_default_server_ip = bp->server_ip; grub_pxe_default_gateway_ip = bp->gateway_ip; - set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len - : sizeof (bp->mac_addr)); + grub_memcpy (pxe_hwaddr.mac, bp->mac_addr, + bp->hw_len < sizeof (pxe_hwaddr.mac) + ? bp->hw_len : sizeof (pxe_hwaddr.mac)); + pxe_hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file, sizeof (bp->boot_file)); set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name, @@ -589,7 +569,10 @@ GRUB_MOD_INIT(pxe) grub_net_card_register (&grub_pxe_card); addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = grub_pxe_your_ip; - inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr); + inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr, pxe_hwaddr, + GRUB_NET_INTERFACE_PERMANENT + | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE + | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE); if (grub_pxe_default_gateway_ip != grub_pxe_default_server_ip) { grub_net_network_level_netaddress_t target; diff --git a/include/grub/net.h b/include/grub/net.h index 4efd79f79..649bf4096 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -34,6 +34,33 @@ typedef struct grub_net extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); +typedef enum grub_link_level_protocol_id +{ + GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET +} grub_link_level_protocol_id_t; + +typedef struct grub_net_link_level_address +{ + grub_link_level_protocol_id_t type; + union + { + grub_uint8_t mac[6]; + }; +} grub_net_link_level_address_t; + +typedef enum grub_net_interface_flags + { + GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE = 1, + GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE = 2, + GRUB_NET_INTERFACE_PERMANENT = 4 + } grub_net_interface_flags_t; + +typedef enum grub_net_card_flags + { + GRUB_NET_CARD_HWADDRESS_IMMUTABLE = 1, + GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2 + } grub_net_card_flags_t; + struct grub_net_card; struct grub_net_card_driver @@ -49,6 +76,8 @@ struct grub_net_card struct grub_net_card *next; char *name; struct grub_net_card_driver *driver; + grub_net_link_level_address_t default_address; + grub_net_card_flags_t flags; void *data; }; @@ -88,6 +117,8 @@ struct grub_net_network_level_interface char *name; struct grub_net_card *card; grub_net_network_level_address_t address; + grub_net_link_level_address_t hwaddress; + grub_net_interface_flags_t flags; void *data; }; @@ -130,7 +161,9 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, struct grub_net_network_level_interface * grub_net_add_addr (const char *name, struct grub_net_card *card, - grub_net_network_level_address_t addr); + grub_net_network_level_address_t addr, + grub_net_link_level_address_t hwaddress, + grub_net_interface_flags_t flags); extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; From 308fad6dc87b752d32e383d8670a8a7fcf4bafa9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 22:10:55 +0200 Subject: [PATCH 0125/1414] Move DHCP parsing to net module and reintroduce most variables --- grub-core/commands/net.c | 161 +++++++++++++++++++++++-- grub-core/fs/i386/pc/pxe.c | 235 ++++++++++--------------------------- include/grub/i386/pc/pxe.h | 38 +----- include/grub/net.h | 43 +++++++ 4 files changed, 257 insertions(+), 220 deletions(-) diff --git a/grub-core/commands/net.c b/grub-core/commands/net.c index 5a21178e5..f1838569b 100644 --- a/grub-core/commands/net.c +++ b/grub-core/commands/net.c @@ -217,21 +217,15 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } -/* - Currently suppoerted adresses: - IPv4: XXX.XXX.XXX.XXX - */ -#define MAX_STR_ADDR_LEN sizeof ("XXX.XXX.XXX.XXX") - -static void -addr_to_str (const grub_net_network_level_address_t *target, char *buf) +void +grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) { switch (target->type) { case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); - grub_snprintf (buf, MAX_STR_ADDR_LEN, "%d.%d.%d.%d", + grub_snprintf (buf, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d", ((n >> 24) & 0xff), ((n >> 16) & 0xff), ((n >> 8) & 0xff), ((n >> 0) & 0xff)); } @@ -298,9 +292,9 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa } { - char buf[MAX_STR_ADDR_LEN]; + char buf[GRUB_NET_MAX_STR_ADDR_LEN]; char name[grub_strlen (inter->name) + sizeof ("net__ip")]; - addr_to_str (&inter->address, buf); + grub_net_addr_to_str (&inter->address, buf); grub_snprintf (name, sizeof (name), "net_%s_ip", inter->name); grub_env_set (name, buf); grub_register_variable_hook (name, 0, addr_set_env); @@ -327,6 +321,8 @@ grub_net_add_addr (const char *name, struct grub_net_card *card, grub_memcpy (&(inter->hwaddress), &hwaddress, sizeof (inter->hwaddress)); inter->flags = flags; inter->card = card; + inter->dhcp_ack = NULL; + inter->dhcp_acklen = 0; grub_net_network_level_interface_register (inter); @@ -502,8 +498,8 @@ print_net_address (const grub_net_network_level_netaddress_t *target) static void print_address (const grub_net_network_level_address_t *target) { - char buf[MAX_STR_ADDR_LEN]; - addr_to_str (target, buf); + char buf[GRUB_NET_MAX_STR_ADDR_LEN]; + grub_net_addr_to_str (target, buf); grub_xputs (buf); } @@ -576,6 +572,145 @@ grub_net_open_real (const char *name) return NULL; } +static char * +grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), + const char *val __attribute__ ((unused))) +{ + return NULL; +} + +static void +set_env_limn_ro (const char *intername, const char *suffix, + char *value, grub_size_t len) +{ + char c; + char varname[sizeof ("net_") + grub_strlen (intername) + sizeof ("_") + + grub_strlen (suffix)]; + grub_snprintf (varname, sizeof (varname), "net_%s_%s", intername, suffix); + c = value[len]; + value[len] = 0; + grub_env_set (varname, value); + value[len] = c; + grub_register_variable_hook (varname, 0, grub_env_write_readonly); +} + +static void +parse_dhcp_vendor (const char *name, void *vend, int limit) +{ + grub_uint8_t *ptr, *ptr0; + + ptr = ptr0 = vend; + + if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != GRUB_NET_BOOTP_RFC1048_MAGIC) + return; + ptr = ptr + sizeof (grub_uint32_t); + while (ptr - ptr0 < limit) + { + grub_uint8_t tagtype; + grub_uint8_t taglength; + + tagtype = *ptr++; + + /* Pad tag. */ + if (tagtype == 0) + continue; + + /* End tag. */ + if (tagtype == 0xff) + return; + + taglength = *ptr++; + + switch (tagtype) + { + case 12: + set_env_limn_ro (name, "hostname", (char *) ptr, taglength); + break; + + case 15: + set_env_limn_ro (name, "domain", (char *) ptr, taglength); + break; + + case 17: + set_env_limn_ro (name, "rootpath", (char *) ptr, taglength); + break; + + case 18: + set_env_limn_ro (name, "extensionspath", (char *) ptr, taglength); + break; + + /* If you need any other options please contact GRUB + developpement team. */ + } + + ptr += taglength; + } +} + +#define OFFSET_OF(x, y) ((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)) + +struct grub_net_network_level_interface * +grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, + grub_net_interface_flags_t flags, + struct grub_net_bootp_ack *bp, + grub_size_t size) +{ + grub_net_network_level_address_t addr; + grub_net_link_level_address_t hwaddr; + struct grub_net_network_level_interface *inter; + + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + addr.ipv4 = bp->your_ip; + + grub_memcpy (hwaddr.mac, bp->mac_addr, + bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len + : sizeof (hwaddr.mac)); + hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + + inter = grub_net_add_addr (name, card, addr, hwaddr, flags); + if (bp->gateway_ip != bp->server_ip) + { + grub_net_network_level_netaddress_t target; + grub_net_network_level_address_t gw; + char rname[grub_strlen (name) + sizeof ("_gw")]; + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = bp->server_ip; + target.ipv4.masksize = 32; + gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + gw.ipv4 = bp->gateway_ip; + grub_snprintf (rname, sizeof (rname), "%s_gw", name); + grub_net_add_route_gw (rname, target, gw); + } + { + grub_net_network_level_netaddress_t target; + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = bp->gateway_ip; + target.ipv4.masksize = 32; + grub_net_add_route (name, target, inter); + } + + if (size > OFFSET_OF (boot_file, bp)) + set_env_limn_ro (name, "boot_file", (char *) bp->boot_file, + sizeof (bp->boot_file)); + if (size > OFFSET_OF (server_name, bp)) + set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, + sizeof (bp->server_name)); + if (size > OFFSET_OF (vendor, bp)) + parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp)); + + inter->dhcp_ack = grub_malloc (size); + if (inter->dhcp_ack) + { + grub_memcpy (inter->dhcp_ack, bp, size); + inter->dhcp_acklen = size; + } + else + grub_errno = GRUB_ERR_NONE; + + return inter; +} + static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; static grub_command_t cmd_lsroutes, cmd_lscards; diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index 1d9ea8f89..513a8cb7d 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -35,13 +35,13 @@ #define LINEAR(x) (void *) (((x >> 16) << 4) + (x & 0xFFFF)) struct grub_pxe_bangpxe *grub_pxe_pxenv; -static grub_uint32_t grub_pxe_your_ip; static grub_uint32_t grub_pxe_default_server_ip; +#if 0 static grub_uint32_t grub_pxe_default_gateway_ip; +#endif static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE; - +static grub_uint32_t pxe_rm_entry = 0; static grub_file_t curr_file = 0; -static grub_net_link_level_address_t pxe_hwaddr; struct grub_pxe_data { @@ -52,7 +52,6 @@ struct grub_pxe_data char filename[0]; }; -static grub_uint32_t pxe_rm_entry = 0; static struct grub_pxe_bangpxe * grub_pxe_scan (void) @@ -316,112 +315,6 @@ static struct grub_fs grub_pxefs_fs = .next = 0 }; -static char * -grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - return NULL; -} - -static void -set_env_limn_ro (const char *varname, char *value, grub_size_t len) -{ - char c; - c = value[len]; - value[len] = 0; - grub_env_set (varname, value); - value[len] = c; - grub_register_variable_hook (varname, 0, grub_env_write_readonly); -} - -static void -parse_dhcp_vendor (void *vend, int limit) -{ - grub_uint8_t *ptr, *ptr0; - - ptr = ptr0 = vend; - - if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363) - return; - ptr = ptr + sizeof (grub_uint32_t); - while (ptr - ptr0 < limit) - { - grub_uint8_t tagtype; - grub_uint8_t taglength; - - tagtype = *ptr++; - - /* Pad tag. */ - if (tagtype == 0) - continue; - - /* End tag. */ - if (tagtype == 0xff) - return; - - taglength = *ptr++; - - switch (tagtype) - { - case 12: - set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength); - break; - - case 15: - set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength); - break; - - case 17: - set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength); - break; - - case 18: - set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength); - break; - - /* If you need any other options please contact GRUB - developpement team. */ - } - - ptr += taglength; - } -} - -static void -grub_pxe_detect (void) -{ - struct grub_pxe_bangpxe *pxenv; - struct grub_pxenv_get_cached_info ci; - struct grub_pxenv_boot_player *bp; - - pxenv = grub_pxe_scan (); - if (! pxenv) - return; - - ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK; - ci.buffer = 0; - ci.buffer_size = 0; - grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry); - if (ci.status) - return; - - bp = LINEAR (ci.buffer); - - grub_pxe_your_ip = bp->your_ip; - grub_pxe_default_server_ip = bp->server_ip; - grub_pxe_default_gateway_ip = bp->gateway_ip; - grub_memcpy (pxe_hwaddr.mac, bp->mac_addr, - bp->hw_len < sizeof (pxe_hwaddr.mac) - ? bp->hw_len : sizeof (pxe_hwaddr.mac)); - pxe_hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file, - sizeof (bp->boot_file)); - set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name, - sizeof (bp->server_name)); - parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor)); - grub_pxe_pxenv = pxenv; -} - static grub_size_t grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)), void *buf __attribute__ ((unused)), @@ -461,14 +354,15 @@ grub_pxe_unload (void) } } -#if 0 static void set_ip_env (char *varname, grub_uint32_t ip) { - char buf[sizeof ("XXX.XXX.XXX.XXX")]; + char buf[GRUB_NET_MAX_STR_ADDR_LEN]; + grub_net_network_level_address_t addr; + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + addr.ipv4 = ip; - grub_snprintf (buf, sizeof (buf), "%d.%d.%d.%d", (ip & 0xff), - (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff); + grub_net_addr_to_str (&addr, buf); grub_env_set (varname, buf); } @@ -477,25 +371,25 @@ write_ip_env (grub_uint32_t *ip, const char *val) { char *buf; grub_err_t err; - grub_uint32_t newip; - - err = parse_ip (val, &newip, 0); + grub_net_network_level_address_t addr; + + err = grub_net_resolve_address (val, &addr); if (err) return 0; + if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) + return NULL; /* Normalize the IP. */ - buf = grub_xasprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff, - (newip >> 16) & 0xff, (newip >> 24) & 0xff); + buf = grub_malloc (GRUB_NET_MAX_STR_ADDR_LEN); if (!buf) return 0; + grub_net_addr_to_str (&addr, buf); - *ip = newip; + *ip = addr.ipv4; return buf; } -#endif -#if 0 static char * grub_env_write_pxe_default_server (struct grub_env_var *var __attribute__ ((unused)), @@ -504,6 +398,7 @@ grub_env_write_pxe_default_server (struct grub_env_var *var return write_ip_env (&grub_pxe_default_server_ip, val); } +#if 0 static char * grub_env_write_pxe_default_gateway (struct grub_env_var *var __attribute__ ((unused)), @@ -540,60 +435,58 @@ grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), GRUB_MOD_INIT(pxe) { - grub_pxe_detect (); - if (grub_pxe_pxenv) - { - char *buf; - grub_net_network_level_address_t addr; - struct grub_net_network_level_interface *inter; - -#if 0 - grub_register_variable_hook ("pxe_default_server", 0, - grub_env_write_pxe_default_server); - grub_register_variable_hook ("pxe_default_gateway", 0, - grub_env_write_pxe_default_gateway); -#endif - grub_register_variable_hook ("pxe_blksize", 0, - grub_env_write_pxe_blocksize); + struct grub_pxe_bangpxe *pxenv; + struct grub_pxenv_get_cached_info ci; + struct grub_net_bootp_ack *bp; + char *buf; - buf = grub_xasprintf ("%d", grub_pxe_blksize); - if (buf) - grub_env_set ("pxe_blksize", buf); - grub_free (buf); + pxenv = grub_pxe_scan (); + if (! pxenv) + return; + + ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK; + ci.buffer = 0; + ci.buffer_size = 0; + grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry); + if (ci.status) + return; + + bp = LINEAR (ci.buffer); + + grub_pxe_default_server_ip = bp->server_ip; + grub_pxe_pxenv = pxenv; + + set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); + grub_register_variable_hook ("pxe_default_server", 0, + grub_env_write_pxe_default_server); #if 0 - set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); + grub_pxe_default_gateway_ip = bp->gateway_ip; + + grub_register_variable_hook ("pxe_default_gateway", 0, + grub_env_write_pxe_default_gateway); #endif - grub_net_app_level_register (&grub_pxefs_fs); - grub_net_card_register (&grub_pxe_card); - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = grub_pxe_your_ip; - inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr, pxe_hwaddr, - GRUB_NET_INTERFACE_PERMANENT - | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE - | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE); - if (grub_pxe_default_gateway_ip != grub_pxe_default_server_ip) - { - grub_net_network_level_netaddress_t target; - grub_net_network_level_address_t gw; - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = grub_pxe_default_server_ip; - target.ipv4.masksize = 32; - gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - gw.ipv4 = grub_pxe_default_gateway_ip; - grub_net_add_route_gw ("pxe_gw", target, gw); - } - { - grub_net_network_level_netaddress_t target; - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = grub_pxe_default_gateway_ip ? - : grub_pxe_default_server_ip; - target.ipv4.masksize = 32; - grub_net_add_route ("pxe", target, inter); - } - } + buf = grub_xasprintf ("%d", grub_pxe_blksize); + if (buf) + grub_env_set ("pxe_blksize", buf); + grub_free (buf); + + grub_register_variable_hook ("pxe_blksize", 0, + grub_env_write_pxe_blocksize); + + grub_memcpy (grub_pxe_card.default_address.mac, bp->mac_addr, + bp->hw_len < sizeof (grub_pxe_card.default_address.mac) + ? bp->hw_len : sizeof (grub_pxe_card.default_address.mac)); + grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + + grub_net_app_level_register (&grub_pxefs_fs); + grub_net_card_register (&grub_pxe_card); + grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, + GRUB_NET_INTERFACE_PERMANENT + | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE + | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE, + bp, GRUB_PXE_BOOTP_SIZE); } GRUB_MOD_FINI(pxe) diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h index 62ece21b0..781b53df5 100644 --- a/include/grub/i386/pc/pxe.h +++ b/include/grub/i386/pc/pxe.h @@ -152,9 +152,9 @@ #define GRUB_PXE_BOOTP_BCAST 0x8000 #if 1 -#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size. */ +#define GRUB_PXE_BOOTP_SIZE (1024 + 236) /* DHCP extended vendor field size. */ #else -#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size. */ +#define GRUB_PXE_BOOTP_SIZE (312 + 236) /* DHCP standard vendor field size. */ #endif #define GRUB_PXE_MIN_BLKSIZE 512 @@ -162,8 +162,6 @@ #define GRUB_PXE_TFTP_PORT 69 -#define GRUB_PXE_VM_RFC1048 0x63825363L - #define GRUB_PXE_ERR_LEN 0xFFFFFFFF #ifndef ASM_FILE @@ -214,38 +212,6 @@ struct grub_pxenv_get_cached_info grub_uint16_t buffer_limit; } __attribute__ ((packed)); -#define GRUB_PXE_MAC_ADDR_LEN 16 - -typedef grub_uint8_t grub_pxe_mac_addr_t[GRUB_PXE_MAC_ADDR_LEN]; - -struct grub_pxenv_boot_player -{ - grub_uint8_t opcode; - grub_uint8_t hw_type; /* hardware type. */ - grub_uint8_t hw_len; /* hardware addr len. */ - grub_uint8_t gate_hops; /* zero it. */ - grub_uint32_t ident; /* random number chosen by client. */ - grub_uint16_t seconds; /* seconds since did initial bootstrap. */ - grub_uint16_t flags; - grub_uint32_t client_ip; - grub_uint32_t your_ip; - grub_uint32_t server_ip; - grub_uint32_t gateway_ip; - grub_pxe_mac_addr_t mac_addr; - grub_uint8_t server_name[64]; - grub_uint8_t boot_file[128]; - union - { - grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options. */ - struct - { - grub_uint32_t magic; /* DHCP magic cookie. */ - grub_uint32_t flags; /* bootp flags/opcodes. */ - grub_uint8_t padding[56]; - } v; - } vendor; -} __attribute__ ((packed)); - struct grub_pxenv_tftp_open { grub_uint16_t status; diff --git a/include/grub/net.h b/include/grub/net.h index 649bf4096..ec334092d 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -119,6 +119,8 @@ struct grub_net_network_level_interface grub_net_network_level_address_t address; grub_net_link_level_address_t hwaddress; grub_net_interface_flags_t flags; + struct grub_net_bootp_ack *dhcp_ack; + grub_size_t dhcp_acklen; void *data; }; @@ -234,4 +236,45 @@ grub_net_add_route_gw (const char *name, grub_net_network_level_address_t gw); +#define GRUB_NET_BOOTP_MAC_ADDR_LEN 16 + +typedef grub_uint8_t grub_net_bootp_mac_addr_t[GRUB_NET_BOOTP_MAC_ADDR_LEN]; + +struct grub_net_bootp_ack +{ + grub_uint8_t opcode; + grub_uint8_t hw_type; /* hardware type. */ + grub_uint8_t hw_len; /* hardware addr len. */ + grub_uint8_t gate_hops; /* zero it. */ + grub_uint32_t ident; /* random number chosen by client. */ + grub_uint16_t seconds; /* seconds since did initial bootstrap. */ + grub_uint16_t flags; + grub_uint32_t client_ip; + grub_uint32_t your_ip; + grub_uint32_t server_ip; + grub_uint32_t gateway_ip; + grub_net_bootp_mac_addr_t mac_addr; + grub_uint8_t server_name[64]; + grub_uint8_t boot_file[128]; + grub_uint8_t vendor[0]; +} __attribute__ ((packed)); + +#define GRUB_NET_BOOTP_RFC1048_MAGIC 0x63825363L + +struct grub_net_network_level_interface * +grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, + grub_net_interface_flags_t flags, + struct grub_net_bootp_ack *bp, + grub_size_t size); + +/* + Currently suppoerted adresses: + IPv4: XXX.XXX.XXX.XXX + */ +#define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXX.XXX.XXX.XXX") + +void +grub_net_addr_to_str (const grub_net_network_level_address_t *target, + char *buf); + #endif /* ! GRUB_NET_HEADER */ From 9daa20394429830d83a26c4eda35ab1a085fadd9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 22:12:37 +0200 Subject: [PATCH 0126/1414] Reintroduce pxe: syntax --- grub-core/fs/i386/pc/pxe.c | 77 ++++++++++++++------------------------ 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index 513a8cb7d..dc447d92c 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -121,54 +121,35 @@ grub_pxefs_open (struct grub_file *file, const char *name) if (!data) return grub_errno; -#if 0 - if (grub_strncmp (file->device->net->name, "pxe:", sizeof ("pxe:") - 1) == 0) - { - const char *ptr; - grub_err_t err; - - ptr = name + sizeof ("pxe:") - 1; - err = parse_ip (ptr, &(data->server_ip), &ptr); - if (err) - return err; - if (*ptr == ':') - { - err = parse_ip (ptr + 1, &(data->gateway_ip), 0); - if (err) - return err; - } - else - data->gateway_ip = grub_pxe_default_gateway_ip; - } - else -#endif - { - grub_net_network_level_address_t addr; - grub_net_network_level_address_t gateway; - struct grub_net_network_level_interface *interf; - grub_err_t err; - - if (grub_strncmp (file->device->net->name, - "pxe,", sizeof ("pxe,") - 1) == 0) - { - const char *ptr; - - ptr = name + sizeof ("pxe,") - 1; - err = grub_net_resolve_address (name + sizeof ("pxe,") - 1, &addr); - if (err) - return err; - } - else - { - addr.ipv4 = grub_pxe_default_server_ip; - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - } - err = grub_net_route_address (addr, &gateway, &interf); - if (err) - return err; - data->server_ip = addr.ipv4; - data->gateway_ip = gateway.ipv4; - } + { + grub_net_network_level_address_t addr; + grub_net_network_level_address_t gateway; + struct grub_net_network_level_interface *interf; + grub_err_t err; + + if (grub_strncmp (file->device->net->name, + "pxe,", sizeof ("pxe,") - 1) == 0 + || grub_strncmp (file->device->net->name, + "pxe:", sizeof ("pxe:") - 1) == 0) + { + const char *ptr; + + ptr = name + sizeof ("pxe,") - 1; + err = grub_net_resolve_address (name + sizeof ("pxe,") - 1, &addr); + if (err) + return err; + } + else + { + addr.ipv4 = grub_pxe_default_server_ip; + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + } + err = grub_net_route_address (addr, &gateway, &interf); + if (err) + return err; + data->server_ip = addr.ipv4; + data->gateway_ip = gateway.ipv4; + } if (curr_file != 0) { From c04256771534fc5dcd1ce71e335b37d5cacc7b42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Sep 2010 22:20:48 +0200 Subject: [PATCH 0127/1414] Create directory net and move all net files there --- Makefile.util.def | 2 +- grub-core/Makefile.core.def | 4 ++-- grub-core/{fs => net}/i386/pc/pxe.c | 0 grub-core/{commands => net}/net.c | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename grub-core/{fs => net}/i386/pc/pxe.c (100%) rename grub-core/{commands => net}/net.c (100%) diff --git a/Makefile.util.def b/Makefile.util.def index 5fd53680d..68c105a9b 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -30,7 +30,7 @@ library = { common = grub-core/commands/blocklist.c; common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; - common = grub-core/commands/net.c; + common = grub-core/net/net.c; common = grub-core/disk/dmraid_nvidia.c; common = grub-core/disk/host.c; common = grub-core/disk/loopback.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fb68f344c..bd5d78160 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -930,7 +930,7 @@ module = { module = { name = pxe; - i386_pc = fs/i386/pc/pxe.c; + i386_pc = net/i386/pc/pxe.c; enable = i386_pc; }; @@ -1379,5 +1379,5 @@ module = { module = { name = net; - common = commands/net.c; + common = net/net.c; }; \ No newline at end of file diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/net/i386/pc/pxe.c similarity index 100% rename from grub-core/fs/i386/pc/pxe.c rename to grub-core/net/i386/pc/pxe.c diff --git a/grub-core/commands/net.c b/grub-core/net/net.c similarity index 100% rename from grub-core/commands/net.c rename to grub-core/net/net.c From 56a4b23d37ac352169f85fdbfab99d3c219cdbb2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 00:49:45 +0200 Subject: [PATCH 0128/1414] fix several issues with nested labels --- Makefile.util.def | 3 + grub-core/Makefile.core.def | 10 +++ grub-core/partmap/bsdlabel.c | 120 +++++++++++++++++++++++++++---- grub-core/partmap/msdos.c | 12 +++- grub-core/partmap/netbsdlabel.c | 2 + grub-core/partmap/openbsdlabel.c | 2 + include/grub/partition.h | 4 ++ 7 files changed, 140 insertions(+), 13 deletions(-) create mode 100644 grub-core/partmap/netbsdlabel.c create mode 100644 grub-core/partmap/openbsdlabel.c diff --git a/Makefile.util.def b/Makefile.util.def index 35bcd81b2..20224cf02 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -89,6 +89,9 @@ library = { common = grub-core/partmap/msdos.c; common = grub-core/partmap/sun.c; common = grub-core/partmap/sunpc.c; + common = grub-core/partmap/bsdlabel.c; + common = grub-core/partmap/netbsdlabel.c; + common = grub-core/partmap/openbsdlabel.c; common = grub-core/script/function.c; common = grub-core/script/lexer.c; common = grub-core/script/main.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 353b9d123..4f28c54f4 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1208,6 +1208,16 @@ module = { common = partmap/bsdlabel.c; }; +module = { + name = part_netbsd; + common = partmap/netbsdlabel.c; +}; + +module = { + name = part_openbsd; + common = partmap/openbsdlabel.c; +}; + module = { name = part_sunpc; common = partmap/sunpc.c; diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index a27b8eaec..3d481843a 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -32,9 +33,9 @@ static struct grub_partition_map grub_bsdlabel_partition_map; static grub_err_t -bsdlabel_partition_map_iterate (grub_disk_t disk, - int (*hook) (grub_disk_t disk, - const grub_partition_t partition)) +iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) { struct grub_partition_bsd_disk_label label; struct grub_partition p; @@ -42,22 +43,27 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, unsigned pos; /* Read the BSD label. */ - if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, - 0, sizeof (label), &label)) + if (grub_disk_read (disk, sector, 0, sizeof (label), &label)) return grub_errno; /* Check if it is valid. */ if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + { + grub_dprintf ("partition", + "bad signature (found 0x%08x, expected 0x%08x)\n", + label.magic, + grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)); + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + } /* A kludge to determine a base of be.offset. */ if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION - < grub_cpu_to_le16 (label.num_partitions)) + < grub_cpu_to_le16 (label.num_partitions) && freebsd) { struct grub_partition_bsd_entry whole_disk_be; - pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR - * GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry) + pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE + + sizeof (struct grub_partition_bsd_entry) * GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION; if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE, @@ -68,8 +74,10 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, delta = grub_le_to_cpu32 (whole_disk_be.offset); } - pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR - * GRUB_DISK_SECTOR_SIZE; + pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE; + + grub_dprintf ("partition", "bsdlabel with %d partitions detected\n", + grub_cpu_to_le16 (label.num_partitions)); for (p.number = 0; p.number < grub_cpu_to_le16 (label.num_partitions); @@ -124,24 +132,112 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, if (hook (disk, &p)) return grub_errno; } - return GRUB_ERR_NONE; } +#if !defined (NETBSDLABEL) && !defined (OPENBSDLABEL) + +static grub_err_t +bsdlabel_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + + if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") + == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD) + { + grub_dprintf ("partition", "FreeBSD embedded iterating\n"); + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, + hook); + } + + if (disk->partition + && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 + || grub_strcmp (disk->partition->partmap->name, "bsd") == 0 + || grub_strcmp (disk->partition->partmap->name, "netbsd") == 0 + || grub_strcmp (disk->partition->partmap->name, "openbsd") == 0)) + { + grub_dprintf ("partition", "no embedded iterating\n"); + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); + } + + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, hook); +} + +#else + +#ifdef OPENBSDLABEL +#define GRUB_PC_PARTITION_TYPE_BSD GRUB_PC_PARTITION_TYPE_OPENBSD +#else +#define GRUB_PC_PARTITION_TYPE_BSD GRUB_PC_PARTITION_TYPE_NETBSD +#endif + +static grub_err_t +bsdlabel_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + grub_err_t err; + + if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") + == 0) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); + + { + struct grub_msdos_partition_mbr mbr; + unsigned i; + + err = grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr); + if (err) + return err; + + for (i = 0; i < ARRAY_SIZE (mbr.entries); i++) + if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_BSD) + { + err = iterate_real (disk, mbr.entries[i].start + + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, hook); + if (err != GRUB_ERR_BAD_PART_TABLE) + return err; + } + } + + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found"); +} + +#endif + /* Partition map type. */ static struct grub_partition_map grub_bsdlabel_partition_map = { +#if defined (OPENBSDLABEL) + .name = "openbsd", +#elif defined (NETBSDLABEL) + .name = "netbsd", +#else .name = "bsd", +#endif .iterate = bsdlabel_partition_map_iterate, }; +#if defined (OPENBSDLABEL) +GRUB_MOD_INIT(part_openbsd) +#elif defined (NETBSDLABEL) +GRUB_MOD_INIT(part_netbsd) +#else GRUB_MOD_INIT(part_bsd) +#endif { grub_partition_map_register (&grub_bsdlabel_partition_map); } +#if defined (OPENBSDLABEL) +GRUB_MOD_FINI(part_openbsd) +#elif defined (NETBSDLABEL) +GRUB_MOD_FINI(part_netbsd) +#else GRUB_MOD_FINI(part_bsd) +#endif { grub_partition_map_unregister (&grub_bsdlabel_partition_map); } diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 3898d09fa..02105e622 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -37,6 +37,15 @@ pc_partition_map_iterate (grub_disk_t disk, int labeln = 0; grub_disk_addr_t lastaddr; grub_disk_addr_t ext_offset; + grub_disk_addr_t delta = 0; + + if (disk->partition && disk->partition->partmap == &grub_msdos_partition_map) + { + if (disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_LINUX_MINIX) + delta = disk->partition->offset; + else + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); + } p.offset = 0; ext_offset = 0; @@ -81,8 +90,9 @@ pc_partition_map_iterate (grub_disk_t disk, { e = mbr.entries + p.index; - p.start = p.offset + grub_le_to_cpu32 (e->start); + p.start = p.offset + grub_le_to_cpu32 (e->start) - delta; p.len = grub_le_to_cpu32 (e->length); + p.msdostype = e->type; grub_dprintf ("partition", "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n", diff --git a/grub-core/partmap/netbsdlabel.c b/grub-core/partmap/netbsdlabel.c new file mode 100644 index 000000000..63c0166da --- /dev/null +++ b/grub-core/partmap/netbsdlabel.c @@ -0,0 +1,2 @@ +#define NETBSDLABEL 1 +#include "bsdlabel.c" diff --git a/grub-core/partmap/openbsdlabel.c b/grub-core/partmap/openbsdlabel.c new file mode 100644 index 000000000..4df075a9c --- /dev/null +++ b/grub-core/partmap/openbsdlabel.c @@ -0,0 +1,2 @@ +#define OPENBSDLABEL 1 +#include "bsdlabel.c" diff --git a/include/grub/partition.h b/include/grub/partition.h index 20705c527..d5398def7 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -65,6 +65,10 @@ struct grub_partition /* The type partition map. */ grub_partition_map_t partmap; + + /* The type of partition whne it's on MSDOS. + Used for embedding detection. */ + grub_uint8_t msdostype; }; grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk, From babad161fb20b59786d4809f7567f8972a393273 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 01:10:58 +0200 Subject: [PATCH 0129/1414] Reorganise net and openbsdlabel --- Makefile.util.def | 2 - grub-core/partmap/bsdlabel.c | 100 ++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 20224cf02..88207979d 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -90,8 +90,6 @@ library = { common = grub-core/partmap/sun.c; common = grub-core/partmap/sunpc.c; common = grub-core/partmap/bsdlabel.c; - common = grub-core/partmap/netbsdlabel.c; - common = grub-core/partmap/openbsdlabel.c; common = grub-core/script/function.c; common = grub-core/script/lexer.c; common = grub-core/script/main.c; diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 3d481843a..6fdac94a1 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -30,10 +30,14 @@ #endif static struct grub_partition_map grub_bsdlabel_partition_map; +static struct grub_partition_map grub_netbsdlabel_partition_map; +static struct grub_partition_map grub_openbsdlabel_partition_map; + static grub_err_t iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, + struct grub_partition_map *pmap, int (*hook) (grub_disk_t disk, const grub_partition_t partition)) { @@ -96,7 +100,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, p.start = grub_le_to_cpu32 (be.offset); p.len = grub_le_to_cpu32 (be.size); - p.partmap = &grub_bsdlabel_partition_map; + p.partmap = pmap; grub_dprintf ("partition", "partition %d: type 0x%x, start 0x%llx, len 0x%llx\n", @@ -135,8 +139,6 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, return GRUB_ERR_NONE; } -#if !defined (NETBSDLABEL) && !defined (OPENBSDLABEL) - static grub_err_t bsdlabel_partition_map_iterate (grub_disk_t disk, int (*hook) (grub_disk_t disk, @@ -148,34 +150,28 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, { grub_dprintf ("partition", "FreeBSD embedded iterating\n"); return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, - hook); + &grub_bsdlabel_partition_map, hook); } if (disk->partition && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 - || grub_strcmp (disk->partition->partmap->name, "bsd") == 0 - || grub_strcmp (disk->partition->partmap->name, "netbsd") == 0 - || grub_strcmp (disk->partition->partmap->name, "openbsd") == 0)) + || disk->partition->partmap == &grub_bsdlabel_partition_map + || disk->partition->partmap == &grub_netbsdlabel_partition_map + || disk->partition->partmap == &grub_openbsdlabel_partition_map)) { grub_dprintf ("partition", "no embedded iterating\n"); return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); } - return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, hook); + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, + &grub_bsdlabel_partition_map, hook); } -#else - -#ifdef OPENBSDLABEL -#define GRUB_PC_PARTITION_TYPE_BSD GRUB_PC_PARTITION_TYPE_OPENBSD -#else -#define GRUB_PC_PARTITION_TYPE_BSD GRUB_PC_PARTITION_TYPE_NETBSD -#endif - static grub_err_t -bsdlabel_partition_map_iterate (grub_disk_t disk, - int (*hook) (grub_disk_t disk, - const grub_partition_t partition)) +netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type, + struct grub_partition_map *pmap, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) { grub_err_t err; @@ -192,10 +188,11 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, return err; for (i = 0; i < ARRAY_SIZE (mbr.entries); i++) - if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_BSD) + if (mbr.entries[i].type == type) { err = iterate_real (disk, mbr.entries[i].start - + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, hook); + + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, + hook); if (err != GRUB_ERR_BAD_PART_TABLE) return err; } @@ -204,40 +201,59 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found"); } -#endif +static grub_err_t +netbsdlabel_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + return netopenbsdlabel_partition_map_iterate (disk, + GRUB_PC_PARTITION_TYPE_NETBSD, + &grub_netbsdlabel_partition_map, + hook); +} + +static grub_err_t +openbsdlabel_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + return netopenbsdlabel_partition_map_iterate (disk, + GRUB_PC_PARTITION_TYPE_OPENBSD, + &grub_openbsdlabel_partition_map, + hook); +} + - -/* Partition map type. */ static struct grub_partition_map grub_bsdlabel_partition_map = { -#if defined (OPENBSDLABEL) - .name = "openbsd", -#elif defined (NETBSDLABEL) - .name = "netbsd", -#else .name = "bsd", -#endif .iterate = bsdlabel_partition_map_iterate, }; -#if defined (OPENBSDLABEL) -GRUB_MOD_INIT(part_openbsd) -#elif defined (NETBSDLABEL) -GRUB_MOD_INIT(part_netbsd) -#else +static struct grub_partition_map grub_openbsdlabel_partition_map = + { + .name = "openbsd", + .iterate = openbsdlabel_partition_map_iterate, + }; + +static struct grub_partition_map grub_netbsdlabel_partition_map = + { + .name = "netbsd", + .iterate = netbsdlabel_partition_map_iterate, + }; + + + GRUB_MOD_INIT(part_bsd) -#endif { grub_partition_map_register (&grub_bsdlabel_partition_map); + grub_partition_map_register (&grub_netbsdlabel_partition_map); + grub_partition_map_register (&grub_openbsdlabel_partition_map); } -#if defined (OPENBSDLABEL) -GRUB_MOD_FINI(part_openbsd) -#elif defined (NETBSDLABEL) -GRUB_MOD_FINI(part_netbsd) -#else GRUB_MOD_FINI(part_bsd) -#endif { grub_partition_map_unregister (&grub_bsdlabel_partition_map); + grub_partition_map_unregister (&grub_netbsdlabel_partition_map); + grub_partition_map_unregister (&grub_openbsdlabel_partition_map); } From 844d0fd5aab767a574236dd2c771f72e95780831 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 01:13:20 +0200 Subject: [PATCH 0130/1414] Remove excessive dprintfs --- grub-core/partmap/bsdlabel.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 6fdac94a1..f25b9548e 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -52,13 +52,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, /* Check if it is valid. */ if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) - { - grub_dprintf ("partition", - "bad signature (found 0x%08x, expected 0x%08x)\n", - label.magic, - grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)); - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); - } + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); /* A kludge to determine a base of be.offset. */ if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION @@ -80,9 +74,6 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE; - grub_dprintf ("partition", "bsdlabel with %d partitions detected\n", - grub_cpu_to_le16 (label.num_partitions)); - for (p.number = 0; p.number < grub_cpu_to_le16 (label.num_partitions); p.number++, pos += sizeof (struct grub_partition_bsd_entry)) @@ -102,12 +93,6 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, p.len = grub_le_to_cpu32 (be.size); p.partmap = pmap; - grub_dprintf ("partition", - "partition %d: type 0x%x, start 0x%llx, len 0x%llx\n", - p.number, be.fs_type, - (unsigned long long) p.start, - (unsigned long long) p.len); - if (p.len == 0) continue; @@ -115,13 +100,6 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, { #ifdef GRUB_UTIL char *partname; -#endif - grub_dprintf ("partition", - "partition %d: invalid start (found 0x%llx, wanted >= 0x%llx)\n", - p.number, - (unsigned long long) p.start, - (unsigned long long) delta); -#ifdef GRUB_UTIL /* disk->partition != NULL as 0 < delta */ partname = grub_partition_get_name (disk->partition); grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", @@ -147,21 +125,15 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD) - { - grub_dprintf ("partition", "FreeBSD embedded iterating\n"); - return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, - &grub_bsdlabel_partition_map, hook); - } + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, + &grub_bsdlabel_partition_map, hook); if (disk->partition && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 || disk->partition->partmap == &grub_bsdlabel_partition_map || disk->partition->partmap == &grub_netbsdlabel_partition_map || disk->partition->partmap == &grub_openbsdlabel_partition_map)) - { - grub_dprintf ("partition", "no embedded iterating\n"); return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); - } return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, &grub_bsdlabel_partition_map, hook); From 5b1d8b4832a17e2fbb2668d0c8d8cb097eac2fb8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 01:17:08 +0200 Subject: [PATCH 0131/1414] Remove leftover files --- grub-core/partmap/netbsdlabel.c | 2 -- grub-core/partmap/openbsdlabel.c | 2 -- 2 files changed, 4 deletions(-) delete mode 100644 grub-core/partmap/netbsdlabel.c delete mode 100644 grub-core/partmap/openbsdlabel.c diff --git a/grub-core/partmap/netbsdlabel.c b/grub-core/partmap/netbsdlabel.c deleted file mode 100644 index 63c0166da..000000000 --- a/grub-core/partmap/netbsdlabel.c +++ /dev/null @@ -1,2 +0,0 @@ -#define NETBSDLABEL 1 -#include "bsdlabel.c" diff --git a/grub-core/partmap/openbsdlabel.c b/grub-core/partmap/openbsdlabel.c deleted file mode 100644 index 4df075a9c..000000000 --- a/grub-core/partmap/openbsdlabel.c +++ /dev/null @@ -1,2 +0,0 @@ -#define OPENBSDLABEL 1 -#include "bsdlabel.c" From 208b94005453b34ebc60d2e341bc03e573cc5ee9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 01:19:11 +0200 Subject: [PATCH 0132/1414] Handle new names in grub-install --- util/grub-install.in | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/util/grub-install.in b/util/grub-install.in index e6521f069..02b05136b 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -332,7 +332,12 @@ fi # filesystem will be accessible). partmap_module= for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do - partmap_module="$partmap_module part_$x"; + case "$x" in + netbsd | openbsd) + partmap_module="$partmap_module part_bsd";; + *) + partmap_module="$partmap_module part_$x";; + esac done # Device abstraction module, if any (lvm, raid). From 7b111db538d28029d1c5c3d65d7ec4b83984d68e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 01:31:13 +0200 Subject: [PATCH 0133/1414] resync MAkefile.core.def --- grub-core/Makefile.core.def | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 4f28c54f4..353b9d123 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1208,16 +1208,6 @@ module = { common = partmap/bsdlabel.c; }; -module = { - name = part_netbsd; - common = partmap/netbsdlabel.c; -}; - -module = { - name = part_openbsd; - common = partmap/openbsdlabel.c; -}; - module = { name = part_sunpc; common = partmap/sunpc.c; From df3df23d5cc5b2eb0598dc10b9378a64a0ebd956 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 17:10:10 +0200 Subject: [PATCH 0134/1414] Reorganise memory map handling --- grub-core/Makefile.am | 9 +--- grub-core/boot/i386/qemu/boot.S | 1 + grub-core/commands/acpi.c | 9 ++-- grub-core/commands/i386/pc/drivemap.c | 5 +- grub-core/commands/lsmmap.c | 31 +++++++++--- grub-core/disk/i386/pc/biosdisk.c | 2 +- grub-core/efiemu/mm.c | 46 +++++++++--------- grub-core/kern/i386/coreboot/init.c | 9 ++-- grub-core/kern/i386/coreboot/mmap.c | 3 +- grub-core/kern/i386/coreboot/startup.S | 2 + grub-core/kern/i386/ieee1275/startup.S | 2 +- grub-core/kern/i386/multiboot_mmap.c | 15 +----- grub-core/kern/i386/pc/init.c | 8 +-- grub-core/kern/i386/pc/mmap.c | 27 ++++++++--- grub-core/kern/i386/qemu/mmap.c | 16 +++--- grub-core/kern/i386/qemu/startup.S | 2 + grub-core/kern/ieee1275/init.c | 35 ++------------ grub-core/kern/ieee1275/mmap.c | 6 +-- grub-core/kern/mips/qemu-mips/init.c | 7 +-- grub-core/kern/mips/yeeloong/init.c | 9 ++-- grub-core/lib/ieee1275/relocator.c | 10 ++-- grub-core/lib/relocator.c | 8 +-- grub-core/loader/i386/bsd.c | 25 ++++------ grub-core/loader/i386/linux.c | 34 ++++++------- grub-core/loader/i386/multiboot_mbi.c | 17 +++---- grub-core/loader/i386/pc/chainloader.c | 2 +- grub-core/loader/i386/pc/linux.c | 2 +- grub-core/loader/mips/linux.c | 2 +- grub-core/loader/multiboot.c | 3 +- grub-core/loader/multiboot_mbi2.c | 18 +++---- grub-core/loader/sparc64/ieee1275/linux.c | 7 ++- grub-core/mmap/efi/mmap.c | 39 ++++++++------- grub-core/mmap/i386/mmap.c | 7 +-- grub-core/mmap/i386/pc/mmap.c | 6 +-- grub-core/mmap/i386/uppermem.c | 22 +++++---- grub-core/mmap/mips/yeeloong/uppermem.c | 14 +++--- grub-core/mmap/mmap.c | 59 +++++++++-------------- grub-core/term/ns8250.c | 2 +- include/grub/autoefi.h | 16 ------ include/grub/efi/memory.h | 10 ---- include/grub/efiemu/efiemu.h | 5 -- include/grub/i386/coreboot/memory.h | 43 ++++++----------- include/grub/i386/ieee1275/memory.h | 2 +- include/grub/i386/memory.h | 8 +++ include/grub/i386/pc/memory.h | 42 ---------------- include/grub/i386/qemu/memory.h | 5 +- include/grub/memory.h | 31 ++++++++++-- include/grub/mips/qemu-mips/memory.h | 2 - include/grub/mips/yeeloong/memory.h | 7 --- include/grub/powerpc/ieee1275/memory.h | 26 ---------- include/grub/sparc64/ieee1275/memory.h | 26 ---------- 51 files changed, 301 insertions(+), 443 deletions(-) delete mode 100644 include/grub/powerpc/ieee1275/memory.h delete mode 100644 include/grub/sparc64/ieee1275/memory.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5d13d0313..135125f7a 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -74,9 +74,9 @@ 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/memory.h if COND_i386_pc -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h @@ -92,24 +92,20 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif if COND_i386_coreboot -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif if COND_i386_multiboot -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif if COND_i386_qemu -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif if COND_i386_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif @@ -123,7 +119,6 @@ endif if COND_mips_yeeloong KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.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 @@ -135,7 +130,7 @@ 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 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h endif if COND_powerpc_ieee1275 diff --git a/grub-core/boot/i386/qemu/boot.S b/grub-core/boot/i386/qemu/boot.S index fe14f0f06..97aeab9e6 100644 --- a/grub-core/boot/i386/qemu/boot.S +++ b/grub-core/boot/i386/qemu/boot.S @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index 884ddf000..71d5fe812 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -152,10 +151,10 @@ grub_acpi_create_ebda (void) auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { grub_uint64_t end = start + size; - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (end > 0x100000) end = 0x100000; @@ -181,7 +180,7 @@ grub_acpi_create_ebda (void) "couldn't find space for the new EBDA"); mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len, - GRUB_MACHINE_MEMORY_RESERVED); + GRUB_MEMORY_RESERVED); if (! mmapregion) return grub_errno; @@ -706,7 +705,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd, playground = playground_ptr = grub_mmap_malign_and_register (1, playground_size, &mmapregion, - GRUB_MACHINE_MEMORY_ACPI, 0); + GRUB_MEMORY_ACPI, 0); if (! playground) { diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index 4afc43358..6a60671f8 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -24,9 +24,10 @@ #include #include #include -#include #include #include +#include +#include /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */ @@ -306,7 +307,7 @@ install_int13_handler (int noret __attribute__ ((unused))) grub_dprintf ("drivemap", "Payload is %u bytes long\n", total_size); handler_base = grub_mmap_malign_and_register (16, total_size, &drivemap_mmap, - GRUB_MACHINE_MEMORY_RESERVED, + GRUB_MEMORY_RESERVED, GRUB_MMAP_MALLOC_LOW); if (! handler_base) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reserve " diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c index 2755df9c4..657f81387 100644 --- a/grub-core/commands/lsmmap.c +++ b/grub-core/commands/lsmmap.c @@ -16,24 +16,39 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_MACHINE_EMU -#include -#endif #include #include #include #include +#include + +static const char *names[] = + { + [GRUB_MEMORY_AVAILABLE] = "available", + [GRUB_MEMORY_RESERVED] = "reserved", + [GRUB_MEMORY_ACPI] = "ACPI reclamaible", + [GRUB_MEMORY_NVS] = "NVS", + [GRUB_MEMORY_BADRAM] = "BadRAM", + [GRUB_MEMORY_CODE] = "firmware code", + [GRUB_MEMORY_HOLE] = "hole" + }; static grub_err_t grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) { - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { - grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n", - (long long) addr, (long long) size, type); + if (type < ARRAY_SIZE (names) && names[type]) + grub_printf ("base_addr = 0x%llx, length = 0x%llx, %s\n", + (long long) addr, (long long) size, names[type]); + else + grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n", + (long long) addr, (long long) size, type); return 0; } #ifndef GRUB_MACHINE_EMU diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 17de0c1a1..934a4692a 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -17,8 +17,8 @@ */ #include -#include #include +#include #include #include #include diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c index de7d309be..3c1dc2946 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -29,8 +29,8 @@ #include #include #include -#include #include +#include struct grub_efiemu_memrequest { @@ -269,10 +269,11 @@ static grub_err_t grub_efiemu_mmap_init (void) { auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t, - grub_uint32_t); + grub_memory_type_t); int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type + __attribute__ ((unused))) { mmap_reserved_size++; return 0; @@ -382,32 +383,29 @@ grub_efiemu_mm_init (void) static grub_err_t grub_efiemu_mmap_fill (void) { - auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { switch (type) { - case GRUB_MACHINE_MEMORY_AVAILABLE: + case GRUB_MEMORY_AVAILABLE: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_CONVENTIONAL_MEMORY); -#ifdef GRUB_MACHINE_MEMORY_ACPI - case GRUB_MACHINE_MEMORY_ACPI: + case GRUB_MEMORY_ACPI: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_ACPI_RECLAIM_MEMORY); -#endif -#ifdef GRUB_MACHINE_MEMORY_NVS - case GRUB_MACHINE_MEMORY_NVS: + case GRUB_MEMORY_NVS: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_ACPI_MEMORY_NVS); -#endif default: - grub_printf ("Unknown memory type %d. Marking as unusable\n", type); - case GRUB_MACHINE_MEMORY_RESERVED: + grub_printf ("Unknown memory type %d. Assuming unusable\n", type); + case GRUB_MEMORY_RESERVED: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_UNUSABLE_MEMORY); } @@ -421,9 +419,7 @@ grub_efiemu_mmap_fill (void) } grub_err_t -grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)) +grub_efiemu_mmap_iterate (grub_memory_hook_t hook) { unsigned i; @@ -432,18 +428,22 @@ grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, { case GRUB_EFI_RUNTIME_SERVICES_CODE: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_EFIEMU_MEMORY_CODE); + GRUB_MEMORY_CODE); + break; + + case GRUB_EFI_UNUSABLE_MEMORY: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, + GRUB_MEMORY_BADRAM); break; case GRUB_EFI_RESERVED_MEMORY_TYPE: case GRUB_EFI_RUNTIME_SERVICES_DATA: - case GRUB_EFI_UNUSABLE_MEMORY: case GRUB_EFI_MEMORY_MAPPED_IO: case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE: case GRUB_EFI_PAL_CODE: case GRUB_EFI_MAX_MEMORY_TYPE: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_EFIEMU_MEMORY_RESERVED); + GRUB_MEMORY_RESERVED); break; case GRUB_EFI_LOADER_CODE: @@ -452,17 +452,17 @@ grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, case GRUB_EFI_BOOT_SERVICES_DATA: case GRUB_EFI_CONVENTIONAL_MEMORY: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_EFIEMU_MEMORY_AVAILABLE); + GRUB_MEMORY_AVAILABLE); break; case GRUB_EFI_ACPI_RECLAIM_MEMORY: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_EFIEMU_MEMORY_ACPI); + GRUB_MEMORY_ACPI); break; case GRUB_EFI_ACPI_MEMORY_NVS: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_EFIEMU_MEMORY_NVS); + GRUB_MEMORY_NVS); break; } diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index 75f385b56..434b9b5a8 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -64,8 +65,10 @@ grub_machine_init (void) /* Initialize the console as early as possible. */ grub_vga_text_init (); - auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { #if GRUB_CPU_SIZEOF_VOID_P == 4 /* Restrict ourselves to 32-bit memory space. */ @@ -75,7 +78,7 @@ grub_machine_init (void) size = GRUB_ULONG_MAX - addr; #endif - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; /* Avoid the lower memory. */ diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c index d06627a08..8b0b20265 100644 --- a/grub-core/kern/i386/coreboot/mmap.c +++ b/grub-core/kern/i386/coreboot/mmap.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -74,7 +75,7 @@ signature_found: } grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { mem_region_t mem_region; diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index 592073776..cac023ddf 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -17,6 +17,8 @@ */ #include +/* For stack parameters. */ +#include #include #include #include diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 3ecf09598..82087323b 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include diff --git a/grub-core/kern/i386/multiboot_mmap.c b/grub-core/kern/i386/multiboot_mmap.c index 73c82049f..7f4bc3b5c 100644 --- a/grub-core/kern/i386/multiboot_mmap.c +++ b/grub-core/kern/i386/multiboot_mmap.c @@ -22,8 +22,6 @@ #include #include -grub_size_t grub_lower_mem, grub_upper_mem; - /* A pointer to the MBI in its initial location. */ struct multiboot_info *startup_multiboot_info; @@ -56,21 +54,10 @@ grub_machine_mmap_init () } grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length); kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries; - - if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0) - { - grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE; - grub_upper_mem = 0; - } - else - { - grub_lower_mem = kern_multiboot_info.mem_lower * 1024; - grub_upper_mem = kern_multiboot_info.mem_upper * 1024; - } } grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr; diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 57e33569e..815e8e7c7 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -186,8 +186,10 @@ grub_machine_init (void) grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END); #endif - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { /* Avoid the lower memory. */ if (addr < 0x100000) @@ -200,7 +202,7 @@ grub_machine_init (void) } /* Ignore >4GB. */ - if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE) + if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE) { grub_size_t len; diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c index b174bc441..798256fd8 100644 --- a/grub-core/kern/i386/pc/mmap.c +++ b/grub-core/kern/i386/pc/mmap.c @@ -23,6 +23,20 @@ #include #include +struct grub_machine_mmap_entry +{ + grub_uint32_t size; + grub_uint64_t addr; + grub_uint64_t len; +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_RESERVED 2 +#define GRUB_MACHINE_MEMORY_ACPI 3 +#define GRUB_MACHINE_MEMORY_NVS 4 +#define GRUB_MACHINE_MEMORY_BADRAM 5 + grub_uint32_t type; +} __attribute__((packed)); + + /* * grub_get_ext_memsize() : return the extended memory size in KB. * BIOS call "INT 15H, AH=88H" to get extended memory size @@ -110,7 +124,7 @@ grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, } grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { grub_uint32_t cont; struct grub_machine_mmap_entry *entry @@ -125,9 +139,9 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin do { if (hook (entry->addr, entry->len, - /* Multiboot mmaps have been defined to match with the E820 definition. + /* GRUB mmaps have been defined to match with the E820 definition. Therefore, we can just pass type through. */ - entry->type)) + ((entry->type <= GRUB_MACHINE_MEMORY_BADRAM) && (entry->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ? entry->type : GRUB_MEMORY_RESERVED)) break; if (! cont) @@ -144,11 +158,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin if (eisa_mmap) { - if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0) - hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE); + if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, + GRUB_MEMORY_AVAILABLE) == 0) + hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE); } else - hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MACHINE_MEMORY_AVAILABLE); + hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MEMORY_AVAILABLE); } return 0; diff --git a/grub-core/kern/i386/qemu/mmap.c b/grub-core/kern/i386/qemu/mmap.c index f8b4b9b4f..208f36b7e 100644 --- a/grub-core/kern/i386/qemu/mmap.c +++ b/grub-core/kern/i386/qemu/mmap.c @@ -16,12 +16,14 @@ * along with GRUB. If not, see . */ +#include #include #include #include #include #include #include +#include #define QEMU_CMOS_MEMSIZE_HIGH 0x35 #define QEMU_CMOS_MEMSIZE_LOW 0x34 @@ -60,38 +62,38 @@ grub_machine_mmap_init () } grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { if (hook (0x0, (grub_addr_t) _start, - GRUB_MACHINE_MEMORY_AVAILABLE)) + GRUB_MEMORY_AVAILABLE)) return 1; if (hook ((grub_addr_t) _end, 0xa0000 - (grub_addr_t) _end, - GRUB_MACHINE_MEMORY_AVAILABLE)) + GRUB_MEMORY_AVAILABLE)) return 1; if (hook (GRUB_MEMORY_MACHINE_UPPER, 0x100000 - GRUB_MEMORY_MACHINE_UPPER, - GRUB_MACHINE_MEMORY_RESERVED)) + GRUB_MEMORY_RESERVED)) return 1; /* Everything else is free. */ if (hook (0x100000, min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, - GRUB_MACHINE_MEMORY_AVAILABLE)) + GRUB_MEMORY_AVAILABLE)) return 1; /* Protect boot.img, which contains the gdt. It is mapped at the top of memory (it is also mapped below 0x100000, but we already reserved that area). */ if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE, GRUB_BOOT_MACHINE_SIZE, - GRUB_MACHINE_MEMORY_RESERVED)) + GRUB_MEMORY_RESERVED)) return 1; if (above_4g != 0 && hook (0x100000000ULL, above_4g, - GRUB_MACHINE_MEMORY_AVAILABLE)) + GRUB_MEMORY_AVAILABLE)) return 1; return 0; diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 680de9dc4..7834d1df5 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -18,6 +18,8 @@ #include #include + +#include #include #include diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 99ce7179b..682a8b5a4 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -32,6 +32,7 @@ #include #include #include +#include /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) @@ -126,8 +127,10 @@ static void grub_claim_heap (void) { unsigned long total = 0; - auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type); - int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type) + auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type); + int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type) { if (type != 1) return 0; @@ -189,31 +192,6 @@ static void grub_claim_heap (void) grub_machine_mmap_iterate (heap_init); } -#ifdef __i386__ - -grub_uint32_t grub_upper_mem; - -/* We need to call this before grub_claim_memory. */ -static void -grub_get_extended_memory (void) -{ - auto int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type); - int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type) - { - if (type == 1 && addr == 0x100000) - { - grub_upper_mem = len; - return 1; - } - - return 0; - } - - grub_machine_mmap_iterate (find_ext_mem); -} - -#endif - static grub_uint64_t ieee1275_get_time_ms (void); void @@ -225,9 +203,6 @@ grub_machine_init (void) grub_ieee1275_init (); grub_console_init_early (); -#ifdef __i386__ - grub_get_extended_memory (); -#endif grub_claim_heap (); grub_console_init_lately (); grub_ofdisk_init (); diff --git a/grub-core/kern/ieee1275/mmap.c b/grub-core/kern/ieee1275/mmap.c index 6f0652770..942e5a354 100644 --- a/grub-core/kern/ieee1275/mmap.c +++ b/grub-core/kern/ieee1275/mmap.c @@ -16,12 +16,12 @@ * along with GRUB. If not, see . */ -#include +#include #include #include grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { grub_ieee1275_phandle_t root; grub_ieee1275_phandle_t memory; @@ -66,7 +66,7 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin if (size_cells == 2) size = (size << 32) | available[i++]; - if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE)) + if (hook (address, size, GRUB_MEMORY_AVAILABLE)) break; } diff --git a/grub-core/kern/mips/qemu-mips/init.c b/grub-core/kern/mips/qemu-mips/init.c index 866c7a82a..f2bb652a8 100644 --- a/grub-core/kern/mips/qemu-mips/init.c +++ b/grub-core/kern/mips/qemu-mips/init.c @@ -51,11 +51,8 @@ grub_reboot (void) } grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { - hook (0, RAMSIZE, - GRUB_MACHINE_MEMORY_AVAILABLE); + hook (0, RAMSIZE, GRUB_MEMORY_AVAILABLE); return GRUB_ERR_NONE; } diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index 523f90282..6b906d06e 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -57,14 +58,12 @@ grub_get_rtc (void) } grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20, - GRUB_MACHINE_MEMORY_AVAILABLE); + GRUB_MEMORY_AVAILABLE); hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20, - GRUB_MACHINE_MEMORY_AVAILABLE); + GRUB_MEMORY_AVAILABLE); return GRUB_ERR_NONE; } diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c index 947346d46..c09f1e9c5 100644 --- a/grub-core/lib/ieee1275/relocator.c +++ b/grub-core/lib/ieee1275/relocator.c @@ -27,10 +27,10 @@ grub_relocator_firmware_get_max_events (void) int counter = 0; auto int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t len __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))); + grub_memory_type_t type __attribute__ ((unused))); int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t len __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type __attribute__ ((unused))) { counter++; return 0; @@ -47,11 +47,11 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) { int counter = 0; auto int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len, - grub_uint32_t type); + grub_memory_type_t type); int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len, - grub_uint32_t type) + grub_memory_type_t type) { - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 53acda52f..9a6941332 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -1379,11 +1379,13 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, { int found = 0; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t sz, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t sz, + grub_memory_type_t type) { grub_uint64_t candidate; - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; candidate = ALIGN_UP (addr, align); if (candidate < min_addr) diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index d72c8195a..b35b4258c 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -262,37 +262,30 @@ generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf) struct grub_e820_mmap *mmap = buf; struct grub_e820_mmap prev, cur; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { cur.addr = addr; cur.size = size; switch (type) { - case GRUB_MACHINE_MEMORY_AVAILABLE: + case GRUB_MEMORY_AVAILABLE: cur.type = GRUB_E820_RAM; break; -#ifdef GRUB_MACHINE_MEMORY_ACPI - case GRUB_MACHINE_MEMORY_ACPI: + case GRUB_MEMORY_ACPI: cur.type = GRUB_E820_ACPI; break; -#endif -#ifdef GRUB_MACHINE_MEMORY_NVS - case GRUB_MACHINE_MEMORY_NVS: + case GRUB_MEMORY_NVS: cur.type = GRUB_E820_NVS; break; -#endif default: -#ifdef GRUB_MACHINE_MEMORY_CODE - case GRUB_MACHINE_MEMORY_CODE: -#endif -#ifdef GRUB_MACHINE_MEMORY_RESERVED - case GRUB_MACHINE_MEMORY_RESERVED: -#endif + case GRUB_MEMORY_CODE: + case GRUB_MEMORY_RESERVED: cur.type = GRUB_E820_RESERVED; break; } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 9cb26a0c2..99670d4e3 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -312,10 +311,11 @@ find_mmap_size (void) { grub_size_t count = 0, mmap_size; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type __attribute__ ((unused))) { count++; return 0; @@ -379,12 +379,14 @@ allocate_pages (grub_size_t prot_size) /* FIXME: Should request low memory from the heap when this feature is implemented. */ - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { /* We must put real mode code in the traditional space. */ - if (type == GRUB_MACHINE_MEMORY_AVAILABLE + if (type == GRUB_MEMORY_AVAILABLE && addr <= 0x90000) { if (addr < 0x10000) @@ -559,36 +561,32 @@ grub_linux_boot (void) grub_dprintf ("linux", "code32_start = %x\n", (unsigned) params->code32_start); - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { switch (type) { - case GRUB_MACHINE_MEMORY_AVAILABLE: + case GRUB_MEMORY_AVAILABLE: grub_e820_add_region (params->e820_map, &e820_num, addr, size, GRUB_E820_RAM); break; -#ifdef GRUB_MACHINE_MEMORY_ACPI - case GRUB_MACHINE_MEMORY_ACPI: + case GRUB_MEMORY_ACPI: grub_e820_add_region (params->e820_map, &e820_num, addr, size, GRUB_E820_ACPI); break; -#endif -#ifdef GRUB_MACHINE_MEMORY_NVS - case GRUB_MACHINE_MEMORY_NVS: + case GRUB_MEMORY_NVS: grub_e820_add_region (params->e820_map, &e820_num, addr, size, GRUB_E820_NVS); break; -#endif -#ifdef GRUB_MACHINE_MEMORY_CODE - case GRUB_MACHINE_MEMORY_CODE: + case GRUB_MEMORY_CODE: grub_e820_add_region (params->e820_map, &e820_num, addr, size, GRUB_E820_EXEC_CODE); break; -#endif default: grub_e820_add_region (params->e820_map, &e820_num, diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index bf17863cf..10450d68e 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -16,7 +16,6 @@ * along with GRUB. If not, see . */ -#include #include #ifdef GRUB_MACHINE_PCBIOS #include @@ -203,28 +202,26 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) { struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { mmap_entry->addr = addr; mmap_entry->len = size; switch (type) { - case GRUB_MACHINE_MEMORY_AVAILABLE: + case GRUB_MEMORY_AVAILABLE: mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; break; -#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE - case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE: + case GRUB_MEMORY_ACPI: mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; break; -#endif -#ifdef GRUB_MACHINE_MEMORY_NVS - case GRUB_MACHINE_MEMORY_NVS: + case GRUB_MEMORY_NVS: mmap_entry->type = MULTIBOOT_MEMORY_NVS; break; -#endif default: mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index 502031d0e..e455e9e52 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index 0719cfb26..899545ccd 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 018cfdcc5..78b7dd632 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include /* For frequencies. */ diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 1de1def86..7c0fa1b77 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -74,7 +73,7 @@ grub_get_multiboot_mmap_count (void) auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type __attribute__ ((unused))) { count++; return 0; diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index f453dcc6a..8ef928b51 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -16,10 +16,10 @@ * along with GRUB. If not, see . */ -#include #include #ifdef GRUB_MACHINE_PCBIOS #include +#include #endif #include #include @@ -288,28 +288,26 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) { struct multiboot_mmap_entry *mmap_entry = tag->entries; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type) { mmap_entry->addr = addr; mmap_entry->len = size; switch (type) { - case GRUB_MACHINE_MEMORY_AVAILABLE: + case GRUB_MEMORY_AVAILABLE: mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; break; -#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE - case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE: + case GRUB_MEMORY_ACPI: mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; break; -#endif -#ifdef GRUB_MACHINE_MEMORY_NVS - case GRUB_MACHINE_MEMORY_NVS: + case GRUB_MEMORY_NVS: mmap_entry->type = MULTIBOOT_MEMORY_NVS; break; -#endif default: mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c index 948729a5d..99051ea78 100644 --- a/grub-core/loader/sparc64/ieee1275/linux.c +++ b/grub-core/loader/sparc64/ieee1275/linux.c @@ -27,6 +27,7 @@ #include #include #include +#include static grub_dl_t my_mod; @@ -182,8 +183,10 @@ alloc_phys (grub_addr_t size) { grub_addr_t ret = (grub_addr_t) -1; - auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type); - int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type) + auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type); + int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type) { grub_addr_t end = addr + len; diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index 316c997c7..5b82a8717 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -29,9 +29,7 @@ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)) +grub_machine_mmap_iterate (grub_memory_hook_t hook) { grub_efi_uintn_t mmap_size = 0; grub_efi_memory_descriptor_t *map_buf = 0; @@ -69,7 +67,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, { case GRUB_EFI_RUNTIME_SERVICES_CODE: hook (desc->physical_start, desc->num_pages * 4096, - GRUB_MACHINE_MEMORY_CODE); + GRUB_MEMORY_CODE); + break; + + case GRUB_EFI_UNUSABLE_MEMORY: + hook (desc->physical_start, desc->num_pages * 4096, + GRUB_MEMORY_BADRAM); break; default: @@ -78,12 +81,11 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, case GRUB_EFI_RESERVED_MEMORY_TYPE: case GRUB_EFI_RUNTIME_SERVICES_DATA: - case GRUB_EFI_UNUSABLE_MEMORY: case GRUB_EFI_MEMORY_MAPPED_IO: case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE: case GRUB_EFI_PAL_CODE: hook (desc->physical_start, desc->num_pages * 4096, - GRUB_MACHINE_MEMORY_RESERVED); + GRUB_MEMORY_RESERVED); break; case GRUB_EFI_LOADER_CODE: @@ -92,17 +94,17 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, case GRUB_EFI_BOOT_SERVICES_DATA: case GRUB_EFI_CONVENTIONAL_MEMORY: hook (desc->physical_start, desc->num_pages * 4096, - GRUB_MACHINE_MEMORY_AVAILABLE); + GRUB_MEMORY_AVAILABLE); break; case GRUB_EFI_ACPI_RECLAIM_MEMORY: hook (desc->physical_start, desc->num_pages * 4096, - GRUB_MACHINE_MEMORY_ACPI); + GRUB_MEMORY_ACPI); break; case GRUB_EFI_ACPI_MEMORY_NVS: hook (desc->physical_start, desc->num_pages * 4096, - GRUB_MACHINE_MEMORY_NVS); + GRUB_MEMORY_NVS); break; } } @@ -115,29 +117,26 @@ make_efi_memtype (int type) { switch (type) { - case GRUB_MACHINE_MEMORY_CODE: + case GRUB_MEMORY_CODE: return GRUB_EFI_RUNTIME_SERVICES_CODE; /* No way to remove a chunk of memory from EFI mmap. So mark it as unusable. */ - case GRUB_MACHINE_MEMORY_HOLE: - - default: - - case GRUB_MACHINE_MEMORY_RESERVED: + case GRUB_MEMORY_HOLE: + case GRUB_MEMORY_RESERVED: return GRUB_EFI_UNUSABLE_MEMORY; - case GRUB_MACHINE_MEMORY_AVAILABLE: + case GRUB_MEMORY_AVAILABLE: return GRUB_EFI_CONVENTIONAL_MEMORY; - case GRUB_MACHINE_MEMORY_ACPI: - return GRUB_EFI_ACPI_RECLAIM_MEMORY; - - case GRUB_MACHINE_MEMORY_NVS: + case GRUB_MEMORY_ACPI: return GRUB_EFI_ACPI_RECLAIM_MEMORY; + case GRUB_MEMORY_NVS: + return GRUB_EFI_ACPI_MEMORY_NVS; } + return GRUB_EFI_UNUSABLE_MEMORY; } struct overlay diff --git a/grub-core/mmap/i386/mmap.c b/grub-core/mmap/i386/mmap.c index f6e16129e..e9c030b7b 100644 --- a/grub-core/mmap/i386/mmap.c +++ b/grub-core/mmap/i386/mmap.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -33,12 +34,12 @@ grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, grub_uint64_t highestlow = 0; auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t, - grub_uint32_t); + grub_memory_type_t); int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize, - grub_uint32_t memtype) + grub_memory_type_t memtype) { grub_uint64_t end = start + rangesize; - if (memtype != GRUB_MACHINE_MEMORY_AVAILABLE) + if (memtype != GRUB_MEMORY_AVAILABLE) return 0; if (end > 0x100000) end = 0x100000; diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c index 7d5a43fec..8dec083f8 100644 --- a/grub-core/mmap/i386/pc/mmap.c +++ b/grub-core/mmap/i386/pc/mmap.c @@ -57,7 +57,7 @@ preboot (int noreturn __attribute__ ((unused))) auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type); hookmmapcur->addr = addr; @@ -135,7 +135,7 @@ malloc_hook (void) grub_uint32_t); int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type __attribute__ ((unused))) { regcount++; return 0; @@ -172,7 +172,7 @@ malloc_hook (void) reentry = 1; hooktarget = grub_mmap_malign_and_register (16, hooksize, &mmapregion, - GRUB_MACHINE_MEMORY_RESERVED, + GRUB_MEMORY_RESERVED, GRUB_MMAP_MALLOC_LOW); reentry = 0; diff --git a/grub-core/mmap/i386/uppermem.c b/grub-core/mmap/i386/uppermem.c index cd1a45239..2aa430155 100644 --- a/grub-core/mmap/i386/uppermem.c +++ b/grub-core/mmap/i386/uppermem.c @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -26,11 +27,12 @@ grub_mmap_get_lower (void) { grub_uint64_t lower = 0; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (addr == 0) lower = size; @@ -48,11 +50,12 @@ grub_mmap_get_upper (void) { grub_uint64_t upper = 0; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (addr <= 0x100000 && addr + size > 0x100000) upper = addr + size - 0x100000; @@ -69,11 +72,12 @@ grub_mmap_get_post64 (void) { grub_uint64_t post64 = 0; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (addr <= 0x4000000 && addr + size > 0x4000000) post64 = addr + size - 0x4000000; diff --git a/grub-core/mmap/mips/yeeloong/uppermem.c b/grub-core/mmap/mips/yeeloong/uppermem.c index 3c5f814de..723b6a888 100644 --- a/grub-core/mmap/mips/yeeloong/uppermem.c +++ b/grub-core/mmap/mips/yeeloong/uppermem.c @@ -27,11 +27,12 @@ grub_mmap_get_lower (void) { grub_uint64_t lower = 0; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (addr == 0) lower = size; @@ -49,11 +50,12 @@ grub_mmap_get_upper (void) { grub_uint64_t upper = 0; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { - if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + if (type != GRUB_MEMORY_AVAILABLE) return 0; if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size > GRUB_ARCH_HIGHMEMPSTART) diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index a1afc8b06..7c3430e9f 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -17,8 +17,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include #include @@ -34,8 +34,7 @@ static int curhandle = 1; #endif grub_err_t -grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, grub_uint32_t)) +grub_mmap_iterate (grub_memory_hook_t hook) { /* This function resolves overlapping regions and sorts the memory map. @@ -48,27 +47,17 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, 3 - unusable memory 4 - a range deliberately empty */ - int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] = + int priority[] = { -#ifdef GRUB_MACHINE_MEMORY_AVAILABLE - [GRUB_MACHINE_MEMORY_AVAILABLE] = 1, -#endif -#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE - [GRUB_MACHINE_MEMORY_RESERVED] = 3, -#endif -#ifdef GRUB_MACHINE_MEMORY_ACPI - [GRUB_MACHINE_MEMORY_ACPI] = 2, -#endif -#ifdef GRUB_MACHINE_MEMORY_CODE - [GRUB_MACHINE_MEMORY_CODE] = 3, -#endif -#ifdef GRUB_MACHINE_MEMORY_NVS - [GRUB_MACHINE_MEMORY_NVS] = 3, -#endif - [GRUB_MACHINE_MEMORY_HOLE] = 4, + [GRUB_MEMORY_AVAILABLE] = 1, + [GRUB_MEMORY_RESERVED] = 3, + [GRUB_MEMORY_ACPI] = 2, + [GRUB_MEMORY_CODE] = 3, + [GRUB_MEMORY_NVS] = 3, + [GRUB_MEMORY_HOLE] = 4, }; - int i, k, done; + int i, done; /* Scanline events. */ struct grub_mmap_scan @@ -89,7 +78,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, /* Current scanline event. */ int curtype; /* How many regions of given type overlap at current location? */ - int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2]; + int present[ARRAY_SIZE (priority)]; /* Number of mmap chunks. */ int mmap_num; @@ -101,7 +90,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type __attribute__ ((unused))) { mmap_num++; return 0; @@ -111,17 +100,17 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type) + grub_memory_type_t type) { scanline_events[i].pos = addr; scanline_events[i].type = 0; - if (type <= GRUB_MACHINE_MEMORY_MAX_TYPE && priority[type]) + if (type < ARRAY_SIZE (priority) && priority[type]) scanline_events[i].memtype = type; else { grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n", type); - scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED; + scanline_events[i].memtype = GRUB_MEMORY_RESERVED; } i++; @@ -160,12 +149,10 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, { scanline_events[i].pos = cur->start; scanline_events[i].type = 0; - if (cur->type == GRUB_MACHINE_MEMORY_HOLE - || (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE - && priority[cur->type])) + if (cur->type < ARRAY_SIZE (priority) && priority[cur->type]) scanline_events[i].memtype = cur->type; else - scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED; + scanline_events[i].memtype = GRUB_MEMORY_RESERVED; i++; scanline_events[i].pos = cur->end; @@ -201,6 +188,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, lasttype = scanline_events[0].memtype; for (i = 0; i < 2 * mmap_num; i++) { + unsigned k; /* Process event. */ if (scanline_events[i].type) present[scanline_events[i].memtype]--; @@ -209,7 +197,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, /* Determine current region type. */ curtype = -1; - for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++) + for (k = 0; k < ARRAY_SIZE (priority); k++) if (present[k] && (curtype == -1 || priority[k] > priority[curtype])) curtype = k; @@ -217,7 +205,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, if ((curtype == -1 || curtype != lasttype) && lastaddr != scanline_events[i].pos && lasttype != -1 - && lasttype != GRUB_MACHINE_MEMORY_HOLE + && lasttype != GRUB_MEMORY_HOLE && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype)) { grub_free (scanline_events); @@ -324,10 +312,11 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), char * str; grub_uint64_t badaddr, badmask; - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, - grub_uint32_t type __attribute__ ((unused))) + grub_memory_type_t type __attribute__ ((unused))) { grub_uint64_t iterator, low, high, cur; int tail, var; @@ -370,7 +359,7 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), { grub_dprintf ("badram", "%llx (size %llx) is a badram range\n", (unsigned long long) cur, (1ULL << tail)); - grub_mmap_register (cur, (1ULL << tail), GRUB_MACHINE_MEMORY_HOLE); + grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE); } return 0; } diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index f3a804d53..550ee6341 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -16,7 +16,6 @@ * along with GRUB. If not, see . */ -#include #include #include #include @@ -26,6 +25,7 @@ #include #ifdef GRUB_MACHINE_PCBIOS +#include static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; #define GRUB_SERIAL_PORT_NUM 4 #else diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h index 740be3249..b75591176 100644 --- a/include/grub/autoefi.h +++ b/include/grub/autoefi.h @@ -34,17 +34,6 @@ static inline grub_err_t grub_autoefi_prepare (void) { return GRUB_ERR_NONE; }; -# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_MACHINE_MEMORY_AVAILABLE -# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_MACHINE_MEMORY_RESERVED -# ifdef GRUB_MACHINE_MEMORY_ACPI -# define GRUB_AUTOEFI_MEMORY_ACPI GRUB_MACHINE_MEMORY_ACPI -# endif -# ifdef GRUB_MACHINE_MEMORY_NVS -# define GRUB_AUTOEFI_MEMORY_NVS GRUB_MACHINE_MEMORY_NVS -# endif -# ifdef GRUB_MACHINE_MEMORY_CODE -# define GRUB_AUTOEFI_MEMORY_CODE GRUB_MACHINE_MEMORY_CODE -# endif # define SYSTEM_TABLE_SIZEOF(x) (sizeof(grub_efi_system_table->x)) # define SYSTEM_TABLE_VAR(x) ((void *)&(grub_efi_system_table->x)) # define SYSTEM_TABLE_PTR(x) ((void *)(grub_efi_system_table->x)) @@ -61,11 +50,6 @@ static inline grub_err_t grub_autoefi_prepare (void) # define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate # define grub_autoefi_prepare grub_efiemu_prepare # define grub_autoefi_set_virtual_address_map grub_efiemu_set_virtual_address_map -# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_EFIEMU_MEMORY_AVAILABLE -# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_EFIEMU_MEMORY_RESERVED -# define GRUB_AUTOEFI_MEMORY_ACPI GRUB_EFIEMU_MEMORY_ACPI -# define GRUB_AUTOEFI_MEMORY_NVS GRUB_EFIEMU_MEMORY_NVS -# define GRUB_AUTOEFI_MEMORY_CODE GRUB_EFIEMU_MEMORY_CODE # define SYSTEM_TABLE_SIZEOF GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF # define SYSTEM_TABLE_VAR GRUB_EFIEMU_SYSTEM_TABLE_VAR # define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h index 285be8359..133f9504c 100644 --- a/include/grub/efi/memory.h +++ b/include/grub/efi/memory.h @@ -24,16 +24,6 @@ #define GRUB_MMAP_REGISTER_BY_FIRMWARE 1 -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 -#define GRUB_MACHINE_MEMORY_RESERVED 2 -#define GRUB_MACHINE_MEMORY_ACPI 3 -#define GRUB_MACHINE_MEMORY_NVS 4 -#define GRUB_MACHINE_MEMORY_CODE 5 -#define GRUB_MACHINE_MEMORY_MAX_TYPE 5 - /* This one is special: it's used internally but is never reported - by firmware. */ -#define GRUB_MACHINE_MEMORY_HOLE 6 - grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index 56d4ea8ee..8eee98b61 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -233,11 +233,6 @@ grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, int grub_efiemu_sizeof_uintn_t (void); grub_err_t grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper); -#define GRUB_EFIEMU_MEMORY_AVAILABLE 1 -#define GRUB_EFIEMU_MEMORY_RESERVED 2 -#define GRUB_EFIEMU_MEMORY_ACPI 3 -#define GRUB_EFIEMU_MEMORY_NVS 4 -#define GRUB_EFIEMU_MEMORY_CODE 5 /* efiemu main control definitions and functions*/ typedef enum {GRUB_EFIEMU_NOTLOADED, diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 664086a81..0642280b9 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -21,11 +21,11 @@ #define _GRUB_MEMORY_MACHINE_LB_HEADER 1 #include -#include #ifndef ASM_FILE #include #include +#include #endif #define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */ @@ -35,36 +35,21 @@ #ifndef ASM_FILE -struct grub_linuxbios_table_header -{ - char signature[4]; - grub_uint32_t size; -}; -typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; - -struct grub_linuxbios_table_item -{ -#define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00 -#define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01 -#define GRUB_LINUXBIOS_MEMBER_LINK 0x11 - grub_uint32_t tag; - grub_uint32_t size; -}; -typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t; - -struct grub_linuxbios_mem_region -{ - grub_uint64_t addr; - grub_uint64_t size; -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 - grub_uint32_t type; -}; -typedef struct grub_linuxbios_mem_region *mem_region_t; - void grub_machine_mmap_init (void); -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)), + 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 diff --git a/include/grub/i386/ieee1275/memory.h b/include/grub/i386/ieee1275/memory.h index 386ee4a05..8dd6f7c8c 100644 --- a/include/grub/i386/ieee1275/memory.h +++ b/include/grub/i386/ieee1275/memory.h @@ -1 +1 @@ -#include +#include diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h index 4f9a3c916..582226eed 100644 --- a/include/grub/i386/memory.h +++ b/include/grub/i386/memory.h @@ -30,6 +30,14 @@ #ifndef ASM_FILE +#define GRUB_MMAP_MALLOC_LOW 1 + +#include + +grub_uint64_t grub_mmap_get_upper (void); +grub_uint64_t grub_mmap_get_lower (void); +grub_uint64_t grub_mmap_get_post64 (void); + typedef grub_addr_t grub_phys_addr_t; static inline grub_phys_addr_t diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 68f5e8bc9..401c837fa 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -88,51 +88,9 @@ struct grub_machine_bios_data_area grub_uint8_t unused2[0xf0 - 0x18]; }; -struct grub_machine_mmap_entry -{ - grub_uint32_t size; - grub_uint64_t addr; - grub_uint64_t len; -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 -#define GRUB_MACHINE_MEMORY_RESERVED 2 -#define GRUB_MACHINE_MEMORY_ACPI 3 -#define GRUB_MACHINE_MEMORY_NVS 4 -#define GRUB_MACHINE_MEMORY_MAX_TYPE 4 - /* This one is special: it's used internally but is never reported - by firmware. */ -#define GRUB_MACHINE_MEMORY_HOLE 5 - - grub_uint32_t type; -} __attribute__((packed)); - -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) - (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); - -grub_uint64_t grub_mmap_get_post64 (void); -grub_uint64_t grub_mmap_get_upper (void); -grub_uint64_t grub_mmap_get_lower (void); - -#define GRUB_MMAP_MALLOC_LOW 1 - -#ifdef GRUB_MACHINE_PCBIOS grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size, int type, int handle); grub_err_t grub_machine_mmap_unregister (int handle); -#else -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/i386/qemu/memory.h b/include/grub/i386/qemu/memory.h index de559443d..2003e4934 100644 --- a/include/grub/i386/qemu/memory.h +++ b/include/grub/i386/qemu/memory.h @@ -21,7 +21,7 @@ #define _GRUB_MEMORY_MACHINE_HEADER 1 #include -#include +#include #ifndef ASM_FILE #include @@ -37,9 +37,6 @@ void grub_machine_mmap_init (void); -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) - (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); - #endif #endif /* ! _GRUB_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/memory.h b/include/grub/memory.h index 43f90e1dd..d98386565 100644 --- a/include/grub/memory.h +++ b/include/grub/memory.h @@ -22,11 +22,32 @@ #include #include -#include -grub_err_t grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)); +typedef enum grub_memory_type + { + GRUB_MEMORY_AVAILABLE = 1, + GRUB_MEMORY_RESERVED = 2, + GRUB_MEMORY_ACPI = 3, + GRUB_MEMORY_NVS = 4, + GRUB_MEMORY_BADRAM = 5, + GRUB_MEMORY_CODE = 20, + /* This one is special: it's used internally but is never reported + by firmware. */ + GRUB_MEMORY_HOLE = 21 + } grub_memory_type_t; + +typedef int NESTED_FUNC_ATTR (*grub_memory_hook_t) (grub_uint64_t, + grub_uint64_t, + grub_memory_type_t); + +grub_err_t grub_mmap_iterate (grub_memory_hook_t hook); + +#if !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_EFI) +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (grub_memory_hook_t hook); +#else +grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook); +#endif + int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type); grub_err_t grub_mmap_unregister (int handle); @@ -42,7 +63,7 @@ struct grub_mmap_region struct grub_mmap_region *next; grub_uint64_t start; grub_uint64_t end; - int type; + grub_memory_type_t type; int handle; }; diff --git a/include/grub/mips/qemu-mips/memory.h b/include/grub/mips/qemu-mips/memory.h index 87e68674e..99d9ef2be 100644 --- a/include/grub/mips/qemu-mips/memory.h +++ b/include/grub/mips/qemu-mips/memory.h @@ -28,8 +28,6 @@ #define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000 #define GRUB_MACHINE_MEMORY_USABLE 0x81000000 -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 - #ifndef ASM_FILE grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h index e7e995283..9d53b5e0e 100644 --- a/include/grub/mips/yeeloong/memory.h +++ b/include/grub/mips/yeeloong/memory.h @@ -31,13 +31,6 @@ #define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000 #define GRUB_ARCH_HIGHMEMPSTART 0x10000000 -#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; diff --git a/include/grub/powerpc/ieee1275/memory.h b/include/grub/powerpc/ieee1275/memory.h deleted file mode 100644 index f8f2ff08d..000000000 --- a/include/grub/powerpc/ieee1275/memory.h +++ /dev/null @@ -1,26 +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_MEMORY_MACHINE_HEADER -#define GRUB_MEMORY_MACHINE_HEADER 1 - -#include - -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 - -#endif diff --git a/include/grub/sparc64/ieee1275/memory.h b/include/grub/sparc64/ieee1275/memory.h deleted file mode 100644 index 25e31002e..000000000 --- a/include/grub/sparc64/ieee1275/memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 - -#include - -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 - -#endif From 30b4166fdea35a49e1712efe6997de210cd17ca3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Sep 2010 17:23:51 +0200 Subject: [PATCH 0135/1414] 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 5cd837bd47208c9e51b214109d7a57758e045e76 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Sep 2010 20:43:43 +0200 Subject: [PATCH 0136/1414] Add testload --- grub-core/lib/legacy_parse.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index f2d3dec0a..f350aaf09 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -205,7 +205,12 @@ struct legacy_command legacy_commands[] = /* setup unsupported. */ /* terminal unsupported. */ /* NUL_TERMINATE */ /* terminfo unsupported. */ /* NUL_TERMINATE */ - /* testload unsupported. */ + {"testload", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + "Read the entire contents of FILE in several different ways and" + " compares them, to test the filesystem code. " + " If this test succeeds, then a good next" + " step is to try loading a kernel."}, + "Print the contents of the file FILE."}, /* testvbe unsupported. */ /* tftpserver unsupported. */ {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", From 88ae2ce1604483663971083a0980b06d53afef84 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Sep 2010 23:03:25 +0200 Subject: [PATCH 0137/1414] Fix several powerpc-ieee1275 issues and one EFI one while on it --- util/grub-install.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 4ce451d11..a47258a96 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -63,7 +63,7 @@ efi_quiet= if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=biosdisk -elif [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then +elif [ "${platform}" = "ieee1275" ] || [ "${platform}" = "efi" ] ; then disk_module= else disk_module=ata @@ -445,7 +445,7 @@ esac case "${target_cpu}-${platform}" in i386-efi | x86_64-efi) imgext=efi ;; mips-yeeloong | i386-coreboot | i386-multiboot | i386-ieee1275 \ - | powerpc-ieeee1275) imgext=elf ;; + | powerpc-ieee1275) imgext=elf ;; *) imgext=img ;; esac @@ -456,7 +456,7 @@ $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.${imge if [ "${target_cpu}-${platform}" = "mips-yeeloong" ]; then cp ${grubdir}/core.${imgext} /boot/grub.elf elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then - cp ${grubdir}/core.${imgext} /boot/grub + cp ${grubdir}/core.${imgext} /boot/grub/grub elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ]; then $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 fi @@ -492,7 +492,7 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla } # Point boot-device at the new grub install - boot_device="$ofpath:$partno,"`grub-mkrelpath ${grubdir}/core.${imgext} | sed 's,/,\\,g'` + boot_device="$ofpath:$partno,"`grub-mkrelpath ${grubdir}/core.${imgext} | sed 's,/,\\\\,g'` "$nvsetenv" boot-device "$boot_device" || { echo "$nvsetenv failed." echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" From 75d8c629fc17944e9696ff9c34d466c5d3fce1a8 Mon Sep 17 00:00:00 2001 From: "bvk.groups@gmail.com" <> Date: Tue, 7 Sep 2010 11:18:53 +0530 Subject: [PATCH 0138/1414] syntax check before overwriting --- util/grub-mkconfig.in | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 828b54bce..3233043c8 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -314,8 +314,15 @@ for i in ${grub_mkconfig_dir}/* ; do done if test "x${grub_cfg}" != "x" ; then - # none of the children aborted with error, install the new grub.cfg - mv -f ${grub_cfg}.new ${grub_cfg} + if ! grub-script-check ${grub_cfg}.new 2>/dev/null; then + echo "Syntax errors are detected in generated GRUB config file." >&2 + echo "Ensure that there are no errors in /etc/default/grub" >&2 + echo "and /etc/grub.d/* files or please file a bug report with" >&2 + echo "${grub_cfg}.new file attached." >&2 + else + # none of the children aborted with error, install the new grub.cfg + mv -f ${grub_cfg}.new ${grub_cfg} + fi fi echo "done" >&2 From 3b2bdd6f73c0e7bf082f8553503b27c3806eb224 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 8 Sep 2010 01:50:12 +0200 Subject: [PATCH 0139/1414] 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 0140/1414] 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 f438a5be5849137073732cca2ba2ebb113c342f0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 8 Sep 2010 12:54:38 +0100 Subject: [PATCH 0141/1414] Set install_device for EFI before it's needed. --- util/grub-install.in | 177 ++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 87 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index a47258a96..cf2a752ab 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -301,6 +301,95 @@ else exit 1 fi +if [ x"$platform" = xefi ]; then + # Get GRUB_DISTRIBUTOR. + if test -f ${sysconfdir}/default/grub ; then + . ${sysconfdir}/default/grub + fi + + # Find the EFI System Partition. + efidir= + if test -d ${bootdir}/efi; then + install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}/efi` + # Is it a mount point? + if test "x$install_device" != "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}`"; then + efidir=${bootdir}/efi + fi + elif test -n "$rootdir" && test "x$rootdir" != "x/"; then + # The EFI System Partition may have been given directly using + # --root-directory. + install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${rootdir}` + # Is it a mount point? + if test "x$install_device" != "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${rootdir}/..`"; then + efidir=${rootdir} + fi + fi + + if test -n "$efidir"; then + efi_fs=`$grub_probe --target=fs --device-map=${device_map} ${efidir}` + if test "x$efi_fs" = xfat; then :; else + echo "${efidir} doesn't look like an EFI partition." 1>&2 + efidir= + fi + fi + + if test -n "$efidir"; then + # The EFI specification requires that an EFI System Partition must + # contain an "EFI" subdirectory, and that OS loaders are stored in + # subdirectories below EFI. Vendors are expected to pick names that do + # not collide with other vendors. To minimise collisions, we use the + # name of our distributor if possible. + if test $removable = yes; then + # The specification makes stricter requirements of removable + # devices, in order that only one image can be automatically loaded + # from them. The image must always reside under /EFI/BOOT, and it + # must have a specific file name depending on the architecture. + efi_distributor=BOOT + case "$target_cpu" in + i386) + efi_file=BOOTIA32.EFI ;; + x86-64) + efi_file=BOOTX64.EFI ;; + # GRUB does not yet support these architectures, but they're defined + # by the specification so we include them here to ease future + # expansion. + ia64) + efi_file=BOOTIA64.EFI ;; + esac + else + efi_distributor="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut -d' ' -f1)" + if test -z "$efi_distributor"; then + efi_distributor=grub + fi + # It is convenient for each architecture to have a different + # efi_file, so that different versions can be installed in parallel. + case "$target_cpu" in + i386) + efi_file=grubia32.efi ;; + x86-64) + efi_file=grubx64.efi ;; + # GRUB does not yet support these architectures, but they're defined + # by the specification so we include them here to ease future + # expansion. + ia64) + efi_file=grubia64.efi ;; + *) + efi_file=grub.efi ;; + esac + # TODO: We should also use efibootmgr, if available, to add a Boot + # entry for ourselves. + fi + efidir="$efidir/EFI/$efi_distributor" + mkdir -p "$efidir" || exit 1 + else + # We don't know what's going on. Fall back to traditional + # (non-specification-compliant) behaviour. + efidir="$grubdir" + efi_distributor= + efi_file=grub.efi + fi +fi + # Create the GRUB directory if it is not present. mkdir -p "$grubdir" || exit 1 @@ -501,93 +590,8 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla } fi elif [ x"$platform" = xefi ]; then - # Get GRUB_DISTRIBUTOR. - if test -f ${sysconfdir}/default/grub ; then - . ${sysconfdir}/default/grub - fi - - # Find the EFI System Partition. - efidir= - if test -d ${bootdir}/efi; then - install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}/efi` - # Is it a mount point? - if test "x$install_device" != "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}`"; then - efidir=${bootdir}/efi - fi - elif test -n "$rootdir" && test "x$rootdir" != "x/"; then - # The EFI System Partition may have been given directly using - # --root-directory. - install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${rootdir}` - # Is it a mount point? - if test "x$install_device" != "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${rootdir}/..`"; then - efidir=${rootdir} - fi - fi - - if test -n "$efidir"; then - efi_fs=`$grub_probe --target=fs --device-map=${device_map} ${efidir}` - if test "x$efi_fs" = xfat; then :; else - echo "${efidir} doesn't look like an EFI partition." 1>&2 - efidir= - fi - fi - - if test -n "$efidir"; then - # The EFI specification requires that an EFI System Partition must - # contain an "EFI" subdirectory, and that OS loaders are stored in - # subdirectories below EFI. Vendors are expected to pick names that do - # not collide with other vendors. To minimise collisions, we use the - # name of our distributor if possible. - if test $removable = yes; then - # The specification makes stricter requirements of removable - # devices, in order that only one image can be automatically loaded - # from them. The image must always reside under /EFI/BOOT, and it - # must have a specific file name depending on the architecture. - efi_distributor=BOOT - case "$target_cpu" in - i386) - efi_file=BOOTIA32.EFI ;; - x86-64) - efi_file=BOOTX64.EFI ;; - # GRUB does not yet support these architectures, but they're defined - # by the specification so we include them here to ease future - # expansion. - ia64) - efi_file=BOOTIA64.EFI ;; - esac - else - efi_distributor="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut -d' ' -f1)" - if test -z "$efi_distributor"; then - efi_distributor=grub - fi - # It is convenient for each architecture to have a different - # efi_file, so that different versions can be installed in parallel. - case "$target_cpu" in - i386) - efi_file=grubia32.efi ;; - x86-64) - efi_file=grubx64.efi ;; - # GRUB does not yet support these architectures, but they're defined - # by the specification so we include them here to ease future - # expansion. - ia64) - efi_file=grubia64.efi ;; - *) - efi_file=grub.efi ;; - esac - # TODO: We should also use efibootmgr, if available, to add a Boot - # entry for ourselves. - fi - efidir="$efidir/EFI/$efi_distributor" - mkdir -p "$efidir" || exit 1 - else - # We don't know what's going on. Fall back to traditional - # (non-specification-compliant) behaviour. - efidir="$grubdir" - efi_distributor= - efi_file=grub.efi - fi cp ${grubdir}/core.${imgext} ${efidir}/${efi_file} + # Try to make this image bootable using the EFI Boot Manager, if available. if test "$removable" = no && test -n "$efi_distributor" && \ test -n "$efibootmgr"; then @@ -619,7 +623,6 @@ elif [ x"$platform" = xefi ]; then -L "$GRUB_DISTRIBUTOR" -l "\\EFI\\$efi_distributor\\$efi_file" fi fi - fi echo "Installation finished. No error reported." From dc3d901cde7e014fa1241a795cd946d07f961852 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 8 Sep 2010 13:07:21 +0100 Subject: [PATCH 0142/1414] Check for the EFI distributor case-insensitively, since efi_distributor is always forced to lower-case. Reported by: Mario Limonciello. --- 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 cf2a752ab..b0823642a 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -603,7 +603,7 @@ elif [ x"$platform" = xefi ]; then # Delete old entries from the same distributor. for bootnum in `efibootmgr | grep '^Boot[0-9]' | \ - fgrep " $efi_distributor" | cut -b5-8`; do + fgrep -i " $efi_distributor" | cut -b5-8`; do efibootmgr $efi_quiet -b "$bootnum" -B done From fdff6f0be97ff0dcc7a0a74b21b98f6c8107de6b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 8 Sep 2010 14:11:45 +0100 Subject: [PATCH 0143/1414] For EFI, hardcode the partition number in the core image's prefix. --- util/grub-install.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/util/grub-install.in b/util/grub-install.in index b0823642a..0956c0902 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -498,6 +498,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1 # Strip partition number + grub_partition="`echo ${grub_drive} | sed -e 's/^[^,]*,//; s/)$//'`" grub_drive="`echo ${grub_drive} | sed -e s/,[a-z0-9,]*//g`" if [ "$disk_module" = ata ] ; then # generic method (used on coreboot and ata mod) @@ -520,6 +521,10 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" + elif [ "x$platform" = xefi ]; then + # No grub-setup, so we need to hardcode the partition number in the + # core image's prefix. + prefix_drive="(,$grub_partition)" fi else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 From 3fcb41054945f6bd8466a8d60e0f3761b2f478da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Sep 2010 20:39:57 +0200 Subject: [PATCH 0144/1414] Fix a double device name --- grub-core/disk/efi/efidisk.c | 10 ++++++---- grub-core/kern/device.c | 10 ++-------- grub-core/normal/completion.c | 7 +------ 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index f9c6f3153..cb6c38884 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -731,7 +731,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) { /* This is a hard disk partition. */ grub_disk_t parent = 0; - char *partition_name = 0; + const grub_partition_t tpart = NULL; char *device_name; grub_efi_device_path_t *dup_dp, *dup_ldp; grub_efi_hard_drive_device_path_t hd; @@ -770,7 +770,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) if (grub_partition_get_start (part) == hd.partition_start && grub_partition_get_len (part) == hd.partition_size) { - partition_name = grub_partition_get_name (part); + tpart = part; return 1; } @@ -799,13 +799,15 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) grub_memcpy (&hd, ldp, sizeof (hd)); grub_partition_iterate (parent, find_partition); - if (! partition_name) + if (! tpart) { grub_disk_close (parent); return 0; } - device_name = grub_xasprintf ("%s,%s", parent->name, partition_name); + device_name = grub_xasprintf ("%s,%s%d", parent->name, + tpart->partmap->name, + tpart->number + 1); grub_free (partition_name); grub_disk_close (parent); diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 4273fedfe..278ce9d72 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -135,28 +135,22 @@ grub_device_iterate (int (*hook) (const char *name)) int iterate_partition (grub_disk_t disk, const grub_partition_t partition) { - char *partition_name; struct part_ent *p; - partition_name = grub_partition_get_name (partition); - if (! partition_name) - return 1; p = grub_malloc (sizeof (*p)); if (!p) { - grub_free (partition_name); return 1; } - p->name = grub_xasprintf ("%s,%s", disk->name, partition_name); + p->name = grub_xasprintf ("%s,%s%d", disk->name, partition->partmap->name, + partition->number + 1); if (!p->name) { - grub_free (partition_name); grub_free (p); return 1; } - grub_free (partition_name); p->next = ents; ents = p; diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index d127f9baf..3bccb43da 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -100,15 +100,10 @@ static int iterate_partition (grub_disk_t disk, const grub_partition_t p) { const char *disk_name = disk->name; - char *partition_name = grub_partition_get_name (p); char *name; int ret; - if (! partition_name) - return 1; - - name = grub_xasprintf ("%s,%s", disk_name, partition_name); - grub_free (partition_name); + name = grub_xasprintf ("%s,%s%d", disk_name, p->partmap->name, p->number + 1); if (! name) return 1; From 7051df3609797b1c1fa3f3ff1a1b83a3a3efdc15 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Sep 2010 21:02:51 +0200 Subject: [PATCH 0145/1414] Fix an issue with new interface for device names --- grub-core/kern/partition.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index a2f5dd722..bd10774e8 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -188,7 +188,13 @@ grub_partition_iterate (struct grub_disk *disk, if (p.start != 0) { const struct grub_partition_map *partmap; + const char *name; + char *newname; dsk->partition = &p; + name = dsk->name; + dsk->name = newname = grub_xasprintf ("%s,%s%d", dsk->name, + p.partmap->name, + p.number + 1); FOR_PARTITION_MAPS(partmap) { grub_err_t err; @@ -198,6 +204,8 @@ grub_partition_iterate (struct grub_disk *disk, if (ret) break; } + grub_free (newname); + dsk->name = name; } dsk->partition = p.parent; return ret; From f256469360f2bbbdb930f282b411c939fe6c0a38 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Sep 2010 21:03:23 +0200 Subject: [PATCH 0146/1414] Fix minix issue --- grub-core/partmap/msdos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 02105e622..a378bb1cd 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -42,7 +42,7 @@ pc_partition_map_iterate (grub_disk_t disk, if (disk->partition && disk->partition->partmap == &grub_msdos_partition_map) { if (disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_LINUX_MINIX) - delta = disk->partition->offset; + delta = disk->partition->start; else return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); } From 43de930c20205db14057a951d094c858cad9e14a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Sep 2010 21:22:41 +0200 Subject: [PATCH 0147/1414] Change to disk->name being raw name. It makes less hidden issues --- grub-core/disk/efi/efidisk.c | 9 +++++---- grub-core/kern/device.c | 12 +++++++++--- grub-core/kern/disk.c | 10 ++++++---- grub-core/kern/partition.c | 8 -------- grub-core/normal/completion.c | 8 +++++++- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index cb6c38884..9b99620d9 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -805,10 +805,11 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) return 0; } - device_name = grub_xasprintf ("%s,%s%d", parent->name, - tpart->partmap->name, - tpart->number + 1); - grub_free (partition_name); + { + char *partition_name = grub_partition_get_name (tpart); + device_name = grub_xasprintf ("%s,%s", parent->name, partition_name); + grub_free (partition_name); + } grub_disk_close (parent); return device_name; diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 278ce9d72..6a004cbfb 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -136,7 +136,7 @@ grub_device_iterate (int (*hook) (const char *name)) int iterate_partition (grub_disk_t disk, const grub_partition_t partition) { struct part_ent *p; - + char *part_name; p = grub_malloc (sizeof (*p)); if (!p) @@ -144,8 +144,14 @@ grub_device_iterate (int (*hook) (const char *name)) return 1; } - p->name = grub_xasprintf ("%s,%s%d", disk->name, partition->partmap->name, - partition->number + 1); + part_name = grub_partition_get_name (partition); + if (!part_name) + { + grub_free (p); + return 1; + } + p->name = grub_xasprintf ("%s,%s", disk->name, part_name); + grub_free (part_name); if (!p->name) { grub_free (p); diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index ccd5f200f..c9cffafc5 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -248,10 +248,6 @@ grub_disk_open (const char *name) if (! disk) return 0; - disk->name = grub_strdup (name); - if (! disk->name) - goto fail; - p = find_part_sep (name); if (p) { @@ -263,7 +259,13 @@ grub_disk_open (const char *name) grub_memcpy (raw, name, len); raw[len] = '\0'; + disk->name = grub_strdup (raw); } + else + disk->name = grub_strdup (name); + if (! disk->name) + goto fail; + for (dev = grub_disk_dev_list; dev; dev = dev->next) { diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index bd10774e8..a2f5dd722 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -188,13 +188,7 @@ grub_partition_iterate (struct grub_disk *disk, if (p.start != 0) { const struct grub_partition_map *partmap; - const char *name; - char *newname; dsk->partition = &p; - name = dsk->name; - dsk->name = newname = grub_xasprintf ("%s,%s%d", dsk->name, - p.partmap->name, - p.number + 1); FOR_PARTITION_MAPS(partmap) { grub_err_t err; @@ -204,8 +198,6 @@ grub_partition_iterate (struct grub_disk *disk, if (ret) break; } - grub_free (newname); - dsk->name = name; } dsk->partition = p.parent; return ret; diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index 6b5a5b7bb..9098dc6de 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -102,8 +102,14 @@ iterate_partition (grub_disk_t disk, const grub_partition_t p) const char *disk_name = disk->name; char *name; int ret; + char *part_name; - name = grub_xasprintf ("%s,%s%d", disk_name, p->partmap->name, p->number + 1); + part_name = grub_partition_get_name (p); + if (! part_name) + return 1; + + name = grub_xasprintf ("%s,%s", disk_name, part_name); + grub_free (part_name); if (! name) return 1; From f637773235f4439e5493969c2012ddcf7143156e Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 8 Sep 2010 23:41:27 +0200 Subject: [PATCH 0148/1414] 2010-09-08 Robert Millan * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Improve with (optional) parameters to specify device and relative path. * util/grub-install.in: Use is_path_readable_by_grub() to verify readability of a few critical files. * util/grub-mkconfig.in: Use is_path_readable_by_grub() to verify readability of grub.cfg.new. --- ChangeLog | 9 +++++++++ util/grub-install.in | 13 ++++++++++--- util/grub-mkconfig.in | 6 ++++++ util/grub-mkconfig_lib.in | 11 +++++++++-- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2acf132ee..eef306cc9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-08 Robert Millan + + * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Improve + with (optional) parameters to specify device and relative path. + * util/grub-install.in: Use is_path_readable_by_grub() to + verify readability of a few critical files. + * util/grub-mkconfig.in: Use is_path_readable_by_grub() to + verify readability of grub.cfg.new. + 2010-09-08 Colin Watson * grub-core/kern/efi/init.c (grub_efi_set_prefix): If the prefix diff --git a/util/grub-install.in b/util/grub-install.in index 0956c0902..eb7ef48b6 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -1,7 +1,7 @@ #! /bin/sh # Install GRUB on your drive. -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 1999,2000,2001,2002,2003,2004,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 @@ -457,8 +457,7 @@ if test "x$fs_module" = x -a "x$modules" = x; then fi # Then the partition map module. In order to support partition-less media, -# this command is allowed to fail (--target=fs already grants us that the -# filesystem will be accessible). +# this command is allowed to fail. partmap_module= for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do partmap_module="$partmap_module part_$x"; @@ -555,6 +554,14 @@ elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 fi +# Verify readability of a few critical files +for file in grubenv core.${imgext} normal.mod ; do + if is_path_readable_by_grub ${grubdir}/${file} ${grub_device} ${relative_grubdir}/${file} ; then : ; else + echo "GRUB is unable to read ${grubdir}/${file}" >&2 + exit 1 + fi +done + # Perform the platform-dependent install if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then # Now perform the installation. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 6f1d375a7..9ea01e8f6 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -313,6 +313,12 @@ for i in ${grub_mkconfig_dir}/* ; do esac done +# Verify readability of ${grub_cfg}.new +if is_path_readable_by_grub ${grub_cfg}.new ; then : ; else + echo "GRUB is unable to read ${grubdir}/${file}" >&2 + exit 1 +fi + if test "x${grub_cfg}" != "x" ; then # none of the children aborted with error, install the new grub.cfg mv -f ${grub_cfg}.new ${grub_cfg} diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index c6f79fb49..6d4f9f3bb 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -53,16 +53,23 @@ make_system_path_relative_to_its_root () is_path_readable_by_grub () { path=$1 + device=$2 + relpath=$3 # abort if path doesn't exist if test -e $path ; then : ;else return 1 fi + if [ "${device}" = "" ] ; then + device=$(${grub_probe} --target=device $path) + fi + if [ "${relpath}" = "" ] ; then + relpath=$(${grub_mkrelpath} $path) + fi + # abort if file read through GRUB doesn't match file read through system # facilities - device=$(${grub_probe} --target=device $path) - relpath=$(${grub_mkrelpath} $path) if ${grub_fstest} $device cmp $relpath $path > /dev/null 2>&1 ; then : ; else return 1 fi From 638f5f7ea1758160f4b79a0301d25b7c02c604c2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Sep 2010 16:37:00 +0200 Subject: [PATCH 0149/1414] Implement --bootloader-id --- util/grub-install.in | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index eb7ef48b6..5b49adcf8 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -61,6 +61,16 @@ efibootmgr=`which efibootmgr 2>/dev/null || true` removable=no efi_quiet= +# Get GRUB_DISTRIBUTOR. +if test -f ${sysconfdir}/default/grub ; then + . ${sysconfdir}/default/grub +fi + +bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut -d' ' -f1)" +if test -z "$bootloader_id"; then + bootloader_id=grub +fi + if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=biosdisk elif [ "${platform}" = "ieee1275" ] || [ "${platform}" = "efi" ] ; then @@ -111,6 +121,7 @@ fi if [ "${platform}" = "efi" ]; then cat < Date: Sat, 11 Sep 2010 22:18:06 +0200 Subject: [PATCH 0150/1414] Fix few compile errors --- docs/man/grub-menulst2cfg.h2m | 3 +++ util/grub-menulst2cfg.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 docs/man/grub-menulst2cfg.h2m diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m new file mode 100644 index 000000000..0c0570f27 --- /dev/null +++ b/docs/man/grub-menulst2cfg.h2m @@ -0,0 +1,3 @@ +[NAME] +grub-menulst2cfg \- transform legacy menu.lst into grub.cfg + diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index fdbdda388..89b792e9a 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -31,7 +31,7 @@ main (int argc, char **argv) if (argc >= 2 && argv[1][0] == '-') { - fprintf (stderr, "Usage: %s [INFILE [OUTFILE]]\n", argv[0]); + fprintf (stdout, "Usage: %s [INFILE [OUTFILE]]\n", argv[0]); return 0; } @@ -79,7 +79,7 @@ main (int argc, char **argv) fprintf (out, "}\n\n"); if (oldname != entryname) fprintf (out, "menuentry \'%s\' {\n", - grub_legacy_escape (entryname, grub_strlen (entryname))); + grub_legacy_escape (entryname, strlen (entryname))); } if (parsed) From 9fb175ed9a48102543867f8006842628cc41217c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Sep 2010 22:18:41 +0200 Subject: [PATCH 0151/1414] Implement multiboot filename duplication in legacy parser --- grub-core/commands/legacycfg.c | 17 ++++++++++++----- grub-core/lib/legacy_parse.c | 16 ++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index aca6d1e1f..100464e69 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -179,6 +179,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), int i; int no_mem_option = 0; struct grub_command *cmd; + char **cutargs; + int cutargc; for (i = 0; i < 2; i++) { /* FIXME: really support this. */ @@ -233,9 +235,14 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), } } - if (!argc) + if (argc < 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required"); + cutargs = grub_malloc (sizeof (cutargsp[0]) * (argc - 1)); + cutargc = argc - 1; + grub_memcpy (cutargs + 1, args + 2, sizeof (cutargsp[0]) * (argc - 2)); + cutargs[0] = args[0]; + do { /* First try Linux. */ @@ -244,7 +251,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), cmd = grub_command_find ("linux16"); if (cmd) { - if (!(cmd->func) (cmd, argc, args)) + if (!(cmd->func) (cmd, cutargc, cutargs)) { kernel_type = LINUX; return GRUB_ERR_NONE; @@ -275,7 +282,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), cmd = grub_command_find ("kfreebsd"); if (cmd) { - if (!(cmd->func) (cmd, argc, args)) + if (!(cmd->func) (cmd, cutargc, cutargs)) { kernel_type = KFREEBSD; return GRUB_ERR_NONE; @@ -288,7 +295,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), cmd = grub_command_find ("knetbsd"); if (cmd) { - if (!(cmd->func) (cmd, argc, args)) + if (!(cmd->func) (cmd, cutargc, cutargs)) { kernel_type = KNETBSD; return GRUB_ERR_NONE; @@ -301,7 +308,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), cmd = grub_command_find ("kopenbsd"); if (cmd) { - if (!(cmd->func) (cmd, argc, args)) + if (!(cmd->func) (cmd, cutargc, cutargs)) { kernel_type = KOPENBSD; return GRUB_ERR_NONE; diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index f350aaf09..694de097b 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -33,6 +33,7 @@ struct legacy_command TYPE_NOAPM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, TYPE_FILE, + TYPE_FILE_NO_CONSUME, TYPE_PARTITION, TYPE_BOOL, TYPE_INT, @@ -113,7 +114,8 @@ struct legacy_command legacy_commands[] = /* ifconfig unsupported. */ /* impsprobe unsupported. */ /* FIXME: dublicate multiboot filename. */ - {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, + {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE_NO_CONSUME, + TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "Load an initial ramdisk FILE for a Linux format boot image and set the" " appropriate parameters in the Linux setup area in memory."}, @@ -122,9 +124,9 @@ struct legacy_command legacy_commands[] = /* FIXME: really support --no-mem-option. */ /* FIXME: dublicate multiboot filename. */ {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_FILE, - TYPE_REST_VERBATIM}, 0, + TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_FILE_NO_CONSUME, + TYPE_REST_VERBATIM}, 0, "[--no-mem-option] [--type=TYPE] FILE [ARG ...]", "Attempt to load the primary boot image from FILE. The rest of the" " line is passed verbatim as the \"kernel command line\". Any modules" @@ -143,7 +145,8 @@ struct legacy_command legacy_commands[] = " when you chain-load some operating systems, such as DOS, if such an" " OS resides at a non-first drive."}, /* md5crypt unsupported. */ - {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE, TYPE_REST_VERBATIM}, 0, + {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE_NO_CONSUME, + TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "Load a boot module FILE for a Multiboot format boot image (no" " interpretation of the file contents is made, so users of this" @@ -210,7 +213,6 @@ struct legacy_command legacy_commands[] = " compares them, to test the filesystem code. " " If this test succeeds, then a good next" " step is to try loading a kernel."}, - "Print the contents of the file FILE."}, /* testvbe unsupported. */ /* tftpserver unsupported. */ {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", @@ -399,6 +401,8 @@ grub_legacy_parse (const char *buf, char **entryname) ptr++; switch (legacy_commands[cmdnum].argt[i]) { + case TYPE_FILE_NO_CONSUME: + hold_arg = 1; case TYPE_PARTITION: case TYPE_FILE: args[j++] = adjust_file (curarg, curarglen); From 8bc402fbda9048e0a5b2a8509a3427a8842d09c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Sep 2010 22:47:49 +0200 Subject: [PATCH 0152/1414] Remove obsolete FIXME comments --- grub-core/commands/legacycfg.c | 2 -- grub-core/lib/legacy_parse.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index b0253e707..6c0caad98 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -261,7 +261,6 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), } /* Then multiboot. */ - /* FIXME: dublicate multiboot filename. */ if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT) { cmd = grub_command_find ("multiboot"); @@ -339,7 +338,6 @@ grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), } if (kernel_type == MULTIBOOT) { - /* FIXME: dublicate module filename. */ cmd = grub_command_find ("module"); if (!cmd) return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found"); diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 832b6cd1a..585c91b22 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -113,7 +113,6 @@ struct legacy_command legacy_commands[] = " its partition type code."}, /* ifconfig unsupported. */ /* impsprobe unsupported. */ - /* FIXME: dublicate multiboot filename. */ {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", @@ -122,7 +121,6 @@ struct legacy_command legacy_commands[] = /* install unsupported. */ /* ioprobe unsupported. */ /* FIXME: really support --no-mem-option. */ - /* FIXME: dublicate multiboot filename. */ {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, TYPE_FILE_NO_CONSUME, From a37376e72a3c2e4d449d308e38f571a84f732550 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 01:07:41 +0200 Subject: [PATCH 0153/1414] legacy_password implementation --- grub-core/commands/legacycfg.c | 193 ++++++++++++++++++++++++++++++++- grub-core/commands/password.c | 23 ++-- grub-core/lib/legacy_parse.c | 20 +++- include/grub/normal.h | 3 + 4 files changed, 226 insertions(+), 13 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 6c0caad98..f8e91b876 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001, 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 @@ -28,6 +28,8 @@ #include #include #include +#include +#include static grub_err_t legacy_file (const char *filename) @@ -351,7 +353,7 @@ grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), static grub_err_t grub_cmd_legacy_color (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) + int argc, char **args) { if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "color required"); @@ -382,8 +384,188 @@ grub_cmd_legacy_color (struct grub_command *mycmd __attribute__ ((unused)), return grub_errno; } +static grub_err_t +check_password_deny (const char *user __attribute__ ((unused)), + const char *entered __attribute__ ((unused)), + void *password __attribute__ ((unused))) +{ + return GRUB_ACCESS_DENIED; +} + +#define MD5_HASHLEN 16 + +struct legacy_md5_password +{ + grub_uint8_t *salt; + int saltlen; + grub_uint8_t hash[MD5_HASHLEN]; +}; + +static int +check_password_md5_real (const char *entered, + struct legacy_md5_password *pw) +{ + int enteredlen = grub_strlen (entered); + unsigned char alt_result[MD5_HASHLEN]; + unsigned char *digest; + grub_uint8_t ctx[GRUB_MD_MD5->contextsize]; + int i; + + GRUB_MD_MD5->init (ctx); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + memcpy (alt_result, digest, MD5_HASHLEN); + + GRUB_MD_MD5->init (ctx); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */ + for (i = enteredlen; i > 16; i -= 16) + GRUB_MD_MD5->write (ctx, alt_result, 16); + GRUB_MD_MD5->write (ctx, alt_result, i); + + for (i = enteredlen; i > 0; i >>= 1) + GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + + for (i = 0; i < 1000; i++) + { + memcpy (alt_result, digest, 16); + + GRUB_MD_MD5->init (ctx); + if ((i & 1) != 0) + GRUB_MD_MD5->write (ctx, entered, enteredlen); + else + GRUB_MD_MD5->write (ctx, alt_result, 16); + + if (i % 3 != 0) + GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); + + if (i % 7 != 0) + GRUB_MD_MD5->write (ctx, entered, enteredlen); + + if ((i & 1) != 0) + GRUB_MD_MD5->write (ctx, alt_result, 16); + else + GRUB_MD_MD5->write (ctx, entered, enteredlen); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + } + + return (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0); +} + +static grub_err_t +check_password_md5 (const char *user, + const char *entered, + void *password) +{ + if (!check_password_md5_real (entered, password)) + return GRUB_ACCESS_DENIED; + + grub_auth_authenticate (user); + + return GRUB_ERR_NONE; +} + +static inline int +ib64t (char c) +{ + if (c == '.') + return 0; + if (c == '/') + return 1; + if (c >= '0' && c <= '9') + return c - '0' + 2; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 12; + if (c >= 'a' && c <= 'z') + return c - 'a' + 38; + return -1; +} + +static grub_err_t +grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + const char *salt, *saltend; + const char *p; + struct legacy_md5_password *pw = NULL; + int i; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected"); + if (args[0][0] != '-' || args[0][1] != '-') + return grub_normal_set_password ("legacy", args[0]); + if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0) + goto fail; + if (argc == 1) + goto fail; + if (grub_strlen(args[1]) <= 3) + goto fail; + salt = args[1]; + saltend = grub_strchr (salt + 3, '$'); + if (!saltend) + goto fail; + pw = grub_malloc (sizeof (*pw)); + if (!pw) + goto fail; + + p = saltend + 1; + for (i = 0; i < 5; i++) + { + int n; + grub_uint32_t w = 0; + + for (n = 0; n < 4; n++) + { + int ww = ib64t(*p++); + if (ww == -1) + goto fail; + w |= ww << (n * 6); + } + pw->hash[i == 4 ? 5 : 12+i] = w & 0xff; + pw->hash[6+i] = (w >> 8) & 0xff; + pw->hash[i] = (w >> 16) & 0xff; + } + { + int n; + grub_uint32_t w = 0; + for (n = 0; n < 2; n++) + { + int ww = ib64t(*p++); + if (ww == -1) + goto fail; + w |= ww << (6 * n); + } + if (w >= 0x100) + goto fail; + pw->hash[11] = w; + } + + pw->saltlen = saltend - salt; + pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen); + if (!pw->salt) + goto fail; + + return grub_auth_register_authentication ("legacy", check_password_md5, pw); + + fail: + grub_free (pw); + /* This is to imitate minor difference between grub-legacy in GRUB2. + If 2 password commands are executed in a row and second one fails + on GRUB2 the password of first one is used, whereas in grub-legacy + authenthication is denied. In case of no password command was executed + early both versions deny any access. */ + return grub_auth_register_authentication ("legacy", check_password_deny, + NULL); +} + static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; -static grub_command_t cmd_color; +static grub_command_t cmd_color, cmd_password; GRUB_MOD_INIT(legacycfg) { @@ -407,6 +589,10 @@ GRUB_MOD_INIT(legacycfg) grub_cmd_legacy_color, N_("NORMAL [HIGHLIGHT]"), N_("Simulate grub-legacy color command")); + cmd_password = grub_register_command ("legacy_password", + grub_cmd_legacy_password, + N_("[--md5] PASSWD [FILE]"), + N_("Simulate grub-legacy password command")); } GRUB_MOD_FINI(legacycfg) @@ -416,4 +602,5 @@ GRUB_MOD_FINI(legacycfg) grub_unregister_command (cmd_kernel); grub_unregister_command (cmd_initrd); grub_unregister_command (cmd_color); + grub_unregister_command (cmd_password); } diff --git a/grub-core/commands/password.c b/grub-core/commands/password.c index 04285254e..db5951cbb 100644 --- a/grub-core/commands/password.c +++ b/grub-core/commands/password.c @@ -40,26 +40,22 @@ check_password (const char *user, const char *entered, return GRUB_ERR_NONE; } -static grub_err_t -grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) +grub_err_t +grub_normal_set_password (const char *user, const char *password) { grub_err_t err; char *pass; int copylen; - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected"); - pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN); if (!pass) return grub_errno; - copylen = grub_strlen (args[1]); + copylen = grub_strlen (password); if (copylen >= GRUB_AUTH_MAX_PASSLEN) copylen = GRUB_AUTH_MAX_PASSLEN - 1; - grub_memcpy (pass, args[1], copylen); + grub_memcpy (pass, password, copylen); - err = grub_auth_register_authentication (args[0], check_password, pass); + err = grub_auth_register_authentication (user, check_password, pass); if (err) { grub_free (pass); @@ -69,6 +65,15 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +static grub_err_t +grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected"); + return grub_normal_set_password (args[0], args[1]); +} + static grub_command_t cmd; GRUB_MOD_INIT(password) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 585c91b22..34ebd19c5 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -32,6 +32,7 @@ struct legacy_command TYPE_FORCE_OPTION, TYPE_NOAPM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_OPTION, TYPE_FILE, TYPE_FILE_NO_CONSUME, TYPE_PARTITION, @@ -159,7 +160,21 @@ struct legacy_command legacy_commands[] = /* partnew unsupported. */ {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, "PART TYPE", "Change the type of the partition PART to TYPE."}, - /* password unsupported. */ /* NUL_TERMINATE */ + /* FIXME: support config file reloading. */ + /* FIXME: support usage in menuentry. */ + {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi; " + "legacy_password %s '%s' %s", 3, {TYPE_OPTION, TYPE_VERBATIM, + TYPE_FILE}, FLAG_IGNORE_REST, + "[--md5] PASSWD [FILE]", + "If used in the first section of a menu file, disable all" + " interactive editing control (menu entry editor and" + " command line). If the password PASSWD is entered, it loads the" + " FILE as a new config file and restarts the GRUB Stage 2. If you" + " omit the argument FILE, then GRUB just unlocks privileged" + " instructions. You can also use it in the script section, in" + " which case it will ask for the password, before continuing." + " The option --md5 tells GRUB that PASSWD is encrypted with" + " md5crypt."}, /* pause unsupported. */ /* rarp unsupported. */ {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", @@ -323,6 +338,8 @@ is_option (enum arg_type opt, const char *curarg, grub_size_t len) || check_option (curarg, "--type=biglinux", len) || check_option (curarg, "--type=multiboot", len) || check_option (curarg, "--no-mem-option", len); + case TYPE_OPTION: + return (len >= 2 && curarg[0] == '-' && curarg[1] == '-'); default: return 0; } @@ -453,6 +470,7 @@ grub_legacy_parse (const char *buf, char **entryname) case TYPE_FORCE_OPTION: case TYPE_NOAPM_OPTION: case TYPE_TYPE_OR_NOMEM_OPTION: + case TYPE_OPTION: if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen)) { args[j++] = grub_strndup (curarg, curarglen); diff --git a/include/grub/normal.h b/include/grub/normal.h index df7f70142..417560d9f 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -120,4 +120,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, const char *users, const char *hotkey, const char *prefix, const char *sourcecode); +grub_err_t +grub_normal_set_password (const char *user, const char *password); + #endif /* ! GRUB_NORMAL_HEADER */ From 237a43b1c191211d4d64e749ba52c5ede622fce6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 02:30:48 +0200 Subject: [PATCH 0154/1414] Support few more legacy commands --- grub-core/commands/legacycfg.c | 44 +++++++++++++++++++++++++- grub-core/lib/legacy_parse.c | 56 +++++++++++++++++++--------------- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index f8e91b876..aeff78b8a 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -351,6 +351,42 @@ grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), "no kernel with module support is loaded in legacy way"); } +static grub_err_t +grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_command *cmd; + + if (kernel_type == LINUX) + { + cmd = grub_command_find ("initrd16"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "command initrd16 not found"); + + return cmd->func (cmd, argc, args); + } + if (kernel_type == MULTIBOOT) + { + char **newargs; + grub_err_t err; + newargs = grub_malloc ((argc + 1) * sizeof (newargs[0])); + if (!newargs) + return grub_errno; + grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); + newargs[0] = "--nounzip"; + cmd = grub_command_find ("module"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found"); + + err = cmd->func (cmd, argc + 1, newargs); + grub_free (newargs); + return err; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no kernel with module support is loaded in legacy way"); +} + static grub_err_t grub_cmd_legacy_color (struct grub_command *mycmd __attribute__ ((unused)), int argc, char **args) @@ -565,7 +601,7 @@ grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), } static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; -static grub_command_t cmd_color, cmd_password; +static grub_command_t cmd_color, cmd_password, cmd_initrdnounzip; GRUB_MOD_INIT(legacycfg) { @@ -581,6 +617,11 @@ GRUB_MOD_INIT(legacycfg) grub_cmd_legacy_initrd, N_("FILE [ARG ...]"), N_("Simulate grub-legacy initrd command")); + cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip", + grub_cmd_legacy_initrdnounzip, + N_("FILE [ARG ...]"), + N_("Simulate grub-legacy modulenounzip command")); + cmd_configfile = grub_register_command ("legacy_configfile", grub_cmd_legacy_configfile, N_("FILE"), @@ -601,6 +642,7 @@ GRUB_MOD_FINI(legacycfg) grub_unregister_command (cmd_configfile); grub_unregister_command (cmd_kernel); grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_initrdnounzip); grub_unregister_command (cmd_color); grub_unregister_command (cmd_password); } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 34ebd19c5..671d0f3f8 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -53,7 +53,7 @@ struct legacy_command legacy_commands[] = "Print the blocklist notation of the file FILE."}, {"boot", "boot\n", 0, {}, 0, 0, "Boot the OS/chain-loader which has been loaded."}, - /* bootp unsupported. */ + /* FIXME: bootp unsupported. */ {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", "Print the contents of the file FILE."}, {"chainloader", "chainloader %s '%s'\n", 2, {TYPE_FORCE_OPTION, TYPE_FILE}, @@ -87,8 +87,8 @@ struct legacy_command legacy_commands[] = "[NUM | `saved']", "Set the default entry to entry number NUM (if not specified, it is" " 0, the first entry) or the entry number saved by savedefault."}, - /* dhcp unsupported. */ - /* displayapm unsupported. */ + /* FIXME: dhcp unsupported. */ + /* FIXME: displayapm unsupported. */ {"displaymem", "lsmmap\n", 0, {}, 0, 0, "Display what GRUB thinks the system address space map of the" " machine is, including all regions of physical RAM installed."}, @@ -102,25 +102,25 @@ struct legacy_command legacy_commands[] = {"find", "search -sf '%s'\n", 1, {TYPE_FILE}, 0, "FILENAME", "Search for the filename FILENAME in all of partitions and print the list of" " the devices which contain the file."}, - /* fstest unsupported. */ - /* geometry unsupported. */ + /* FIXME: fstest unsupported. */ + /* FIXME: geometry unsupported. */ {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", "Halt your system. If APM is available on it, turn off the power using" " the APM BIOS, unless you specify the option `--no-apm'."}, - /* help unsupported. */ /* NUL_TERMINATE */ - /* hiddenmenu unsupported. */ + /* FIXME: help unsupported. */ /* NUL_TERMINATE */ + /* FIXME: hiddenmenu unsupported. */ {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", "Hide PARTITION by setting the \"hidden\" bit in" " its partition type code."}, - /* ifconfig unsupported. */ - /* impsprobe unsupported. */ + /* FIXME: ifconfig unsupported. */ + /* FIXME: impsprobe unsupported. */ {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "Load an initial ramdisk FILE for a Linux format boot image and set the" " appropriate parameters in the Linux setup area in memory."}, /* install unsupported. */ - /* ioprobe unsupported. */ + /* FIXME: ioprobe unsupported. */ /* FIXME: really support --no-mem-option. */ {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, @@ -134,7 +134,7 @@ struct legacy_command legacy_commands[] = " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" " Linux's mem option automatically."}, - /* lock is unsupported. */ + /* FIXME: lock is unsupported. */ {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0, 0, "Set the active partition on the root disk to GRUB's root device." " This command is limited to _primary_ PC partitions on a hard disk."}, @@ -143,7 +143,8 @@ struct legacy_command legacy_commands[] = "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" " when you chain-load some operating systems, such as DOS, if such an" " OS resides at a non-first drive."}, - /* md5crypt unsupported. */ + /* md5crypt unsupported since GRUB has not enough entropy and this + hash shouldn't be used anymore. */ {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", @@ -152,12 +153,16 @@ struct legacy_command legacy_commands[] = " command must know what the kernel in question expects). The" " rest of the line is passed as the \"module command line\", like" " the `kernel' command."}, - /* modulenounzip unsupported. */ + {"modulenounzip", "legacy_initrd_nounzip '%s' %s\n", 1, + {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, + "FILE [ARG ...]", + "The same as `module', except that automatic decompression is" + " disabled."}, /* FIXME: allow toggle. */ {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0, "[FLAG]", "Toggle pager mode with no argument. If FLAG is given and its value" " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, - /* partnew unsupported. */ + /* FIXME: partnew unsupported. */ {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, "PART TYPE", "Change the type of the partition PART to TYPE."}, /* FIXME: support config file reloading. */ @@ -175,8 +180,8 @@ struct legacy_command legacy_commands[] = " which case it will ask for the password, before continuing." " The option --md5 tells GRUB that PASSWD is encrypted with" " md5crypt."}, - /* pause unsupported. */ - /* rarp unsupported. */ + /* FIXME: pause unsupported. */ + /* FIXME: rarp unsupported. */ {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", "Read a 32-bit value from memory at address ADDR and" " display it in hex format."}, @@ -217,17 +222,17 @@ struct legacy_command legacy_commands[] = " STOP is the length of stop bit(s). The option --device can be used only" " in the grub shell, which specifies the file name of a tty device. The" " default values are COM1, 9600, 8N1."}, - /* setkey unsupported. */ /* NUL_TERMINATE */ - /* setup unsupported. */ - /* terminal unsupported. */ /* NUL_TERMINATE */ - /* terminfo unsupported. */ /* NUL_TERMINATE */ + /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ + /* FIXME: setup unsupported. */ + /* FIXME: terminal unsupported. */ /* NUL_TERMINATE */ + /* FIXME: terminfo unsupported. */ /* NUL_TERMINATE */ {"testload", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", "Read the entire contents of FILE in several different ways and" " compares them, to test the filesystem code. " " If this test succeeds, then a good next" " step is to try loading a kernel."}, - /* testvbe unsupported. */ - /* tftpserver unsupported. */ + /* FIXME: testvbe unsupported. */ + /* FIXME: tftpserver unsupported. */ {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", "Set a timeout, in SEC seconds, before automatically booting the" " default entry (normally the first entry defined)."}, @@ -235,10 +240,13 @@ struct legacy_command legacy_commands[] = {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0, "PARTITION", "Unhide PARTITION by clearing the \"hidden\" bit in its" " partition type code."}, - /* uppermem unsupported. */ + /* FIXME: uppermem unsupported. */ {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0, "UUID", "Find root by UUID"}, - /* vbeprobe unsupported. */ + /* FIXME: support MODE. */ + {"vbeprobe", "vbeinfo", 0, {}, 0, "[MODE]", + "Probe VBE information. If the mode number MODE is specified, show only" + " the information about only the mode."} }; char * From 6c6850ae13bff8975c9682aa59db0c09ad1edde8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 02:55:24 +0200 Subject: [PATCH 0155/1414] Implement hiddenmenu (not tested) --- grub-core/commands/legacycfg.c | 48 ++++++++++++++++++++++++++++------ grub-core/lib/legacy_parse.c | 12 ++++++--- include/grub/legacy_parse.h | 2 +- util/grub-menulst2cfg.c | 13 ++++++++- 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index aeff78b8a..82901b0e7 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -37,6 +37,18 @@ legacy_file (const char *filename) grub_file_t file; char *entryname = NULL, *entrysrc = NULL; grub_menu_t menu; + char *suffix = grub_strdup (""); + + auto grub_err_t getline (char **line, int cont); + grub_err_t getline (char **line, + int cont __attribute__ ((unused))) + { + *line = 0; + return GRUB_ERR_NONE; + } + + if (!suffix) + return grub_errno; file = grub_file_open (filename); if (! file) @@ -68,10 +80,32 @@ legacy_file (const char *filename) { char *oldname = NULL; + int is_suffix; oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname); + parsed = grub_legacy_parse (buf, &entryname, &is_suffix); grub_free (buf); + if (is_suffix) + { + char *t; + + t = suffix; + suffix = grub_realloc (suffix, grub_strlen (suffix) + + grub_strlen (parsed) + 1); + if (!suffix) + { + grub_free (t); + grub_free (entrysrc); + grub_free (parsed); + grub_free (suffix); + return grub_errno; + } + grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, + grub_strlen (parsed) + 1); + grub_free (parsed); + parsed = NULL; + continue; + } if (oldname != entryname && oldname) { const char **args = grub_malloc (sizeof (args[0])); @@ -88,13 +122,6 @@ legacy_file (const char *filename) if (parsed && !entryname) { - auto grub_err_t getline (char **line, int cont); - grub_err_t getline (char **line __attribute__ ((unused)), - int cont __attribute__ ((unused))) - { - return GRUB_ERR_NONE; - } - grub_normal_parse_line (parsed, getline); grub_print_error (); grub_free (parsed); @@ -114,6 +141,7 @@ legacy_file (const char *filename) { grub_free (t); grub_free (parsed); + grub_free (suffix); return grub_errno; } grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, @@ -137,6 +165,10 @@ legacy_file (const char *filename) grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc); } + grub_normal_parse_line (suffix, getline); + grub_print_error (); + grub_free (suffix); + if (menu && menu->size) grub_show_menu (menu, 1); diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 671d0f3f8..3800d6ca5 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -41,7 +41,8 @@ struct legacy_command TYPE_REST_VERBATIM } argt[4]; enum { - FLAG_IGNORE_REST = 1 + FLAG_IGNORE_REST = 1, + FLAG_SUFFIX = 2 } flags; const char *shortdesc; const char *longdesc; @@ -108,7 +109,8 @@ struct legacy_command legacy_commands[] = "Halt your system. If APM is available on it, turn off the power using" " the APM BIOS, unless you specify the option `--no-apm'."}, /* FIXME: help unsupported. */ /* NUL_TERMINATE */ - /* FIXME: hiddenmenu unsupported. */ + {"hiddenmenu", "if sleep -i $timeout; then timeout=0; else timeout=-1; fi\n", + 0, {}, FLAG_SUFFIX, "", "Hide the menu."}, {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", "Hide PARTITION by setting the \"hidden\" bit in" " its partition type code."}, @@ -354,12 +356,14 @@ is_option (enum arg_type opt, const char *curarg, grub_size_t len) } char * -grub_legacy_parse (const char *buf, char **entryname) +grub_legacy_parse (const char *buf, char **entryname, int *suffix) { const char *ptr; const char *cmdname; unsigned i, cmdnum; + *suffix = 0; + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); if (!*ptr || *ptr == '#') return grub_strdup (buf); @@ -392,6 +396,8 @@ grub_legacy_parse (const char *buf, char **entryname) if (cmdnum == ARRAY_SIZE (legacy_commands)) return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); + *suffix = !!(legacy_commands[cmdnum].flags & FLAG_SUFFIX); + for (; grub_isspace (*ptr) || *ptr == '='; ptr++); char *args[ARRAY_SIZE (legacy_commands[0].argt)]; diff --git a/include/grub/legacy_parse.h b/include/grub/legacy_parse.h index fce4e3e40..a6394496f 100644 --- a/include/grub/legacy_parse.h +++ b/include/grub/legacy_parse.h @@ -21,7 +21,7 @@ #include -char *grub_legacy_parse (const char *buf, char **entryname); +char *grub_legacy_parse (const char *buf, char **entryname, int *suffix); char *grub_legacy_escape (const char *in, grub_size_t len); #endif diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 89b792e9a..0184b3fe3 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -28,6 +28,9 @@ main (int argc, char **argv) char *entryname = NULL; char *buf = NULL; size_t bufsize = 0; + char *suffix = xstrdup (""); + int suffixlen = 0; + int is_suffix = 0; if (argc >= 2 && argv[1][0] == '-') { @@ -74,7 +77,14 @@ main (int argc, char **argv) char *oldname = NULL; oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname); + parsed = grub_legacy_parse (buf, &entryname, &is_suffix); + if (is_suffix) + { + suffixlen += strlen (parsed); + suffix = xrealloc (suffix, suffixlen + 1); + strcat (suffix, parsed); + continue; + } if (oldname != entryname && oldname) fprintf (out, "}\n\n"); if (oldname != entryname) @@ -89,6 +99,7 @@ main (int argc, char **argv) if (entryname) fprintf (out, "}\n\n"); + fwrite (out, 1, suffixlen, suffix); if (in != stdin) fclose (in); From 07473cf9175f5fc0d0b78b71f5bc3e3fe703820d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 03:05:19 +0200 Subject: [PATCH 0156/1414] Support pause --- grub-core/lib/legacy_parse.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 3800d6ca5..4e038807c 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -93,7 +93,7 @@ struct legacy_command legacy_commands[] = {"displaymem", "lsmmap\n", 0, {}, 0, 0, "Display what GRUB thinks the system address space map of the" " machine is, including all regions of physical RAM installed."}, - /* embed unsupported. */ + /* NOTE: embed unsupported. */ {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0, "NUM...", "Go into unattended boot mode: if the default boot entry has any" " errors, instead of waiting for the user to do anything, it" @@ -121,7 +121,7 @@ struct legacy_command legacy_commands[] = "FILE [ARG ...]", "Load an initial ramdisk FILE for a Linux format boot image and set the" " appropriate parameters in the Linux setup area in memory."}, - /* install unsupported. */ + /* NOTE: install unsupported. */ /* FIXME: ioprobe unsupported. */ /* FIXME: really support --no-mem-option. */ {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, @@ -145,7 +145,7 @@ struct legacy_command legacy_commands[] = "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" " when you chain-load some operating systems, such as DOS, if such an" " OS resides at a non-first drive."}, - /* md5crypt unsupported since GRUB has not enough entropy and this + /* NOTE: md5crypt unsupported since GRUB has not enough entropy and this hash shouldn't be used anymore. */ {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, @@ -182,7 +182,12 @@ struct legacy_command legacy_commands[] = " which case it will ask for the password, before continuing." " The option --md5 tells GRUB that PASSWD is encrypted with" " md5crypt."}, - /* FIXME: pause unsupported. */ + /* NOTE: GRUB2 has a design principle of not eternally waiting for user + input. 60 seconds should be enough. + */ + {"pause", "echo %s; if ! sleep -i 60; then return; fi", 1, + {TYPE_REST_VERBATIM}, 0, + "[MESSAGE ...]", "Print MESSAGE, then wait until a key is pressed."}, /* FIXME: rarp unsupported. */ {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", "Read a 32-bit value from memory at address ADDR and" @@ -208,7 +213,7 @@ struct legacy_command legacy_commands[] = " GRUB can read, but setting the correct root device is still" " desired. Note that the items mentioned in `root' which" " derived from attempting the mount will NOT work correctly."}, - /* FIXME: support arguments. */ + /* FIXME: support saving NUM and fallback. */ {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0, "[NUM | `fallback']", "Save the current entry as the default boot entry if no argument is" From 43cce9e0955c22cda56eef3d3054aedb1b4892bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 11:01:21 +0200 Subject: [PATCH 0157/1414] Fix uninitialised usage of curarg --- grub-core/lib/legacy_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 4e038807c..797594c15 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -411,10 +411,10 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) { unsigned j = 0; int hold_arg = 0; + const char *curarg = NULL; for (i = 0; i < legacy_commands[cmdnum].argc; i++) { - const char *curarg; - grub_size_t curarglen; + grub_size_t curarglen; if (hold_arg) { ptr = curarg; From 966446589259f507b5f327f3bb7ede0deab4b4db Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 11:09:01 +0200 Subject: [PATCH 0158/1414] Add missing newlines --- grub-core/lib/legacy_parse.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 797594c15..dabc497be 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -169,7 +169,7 @@ struct legacy_command legacy_commands[] = "PART TYPE", "Change the type of the partition PART to TYPE."}, /* FIXME: support config file reloading. */ /* FIXME: support usage in menuentry. */ - {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi; " + {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" "legacy_password %s '%s' %s", 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE}, FLAG_IGNORE_REST, "[--md5] PASSWD [FILE]", @@ -185,7 +185,7 @@ struct legacy_command legacy_commands[] = /* NOTE: GRUB2 has a design principle of not eternally waiting for user input. 60 seconds should be enough. */ - {"pause", "echo %s; if ! sleep -i 60; then return; fi", 1, + {"pause", "echo %s; if ! sleep -i 60; then return; fi\n", 1, {TYPE_REST_VERBATIM}, 0, "[MESSAGE ...]", "Print MESSAGE, then wait until a key is pressed."}, /* FIXME: rarp unsupported. */ @@ -251,7 +251,7 @@ struct legacy_command legacy_commands[] = {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0, "UUID", "Find root by UUID"}, /* FIXME: support MODE. */ - {"vbeprobe", "vbeinfo", 0, {}, 0, "[MODE]", + {"vbeprobe", "vbeinfo\n", 0, {}, 0, "[MODE]", "Probe VBE information. If the mode number MODE is specified, show only" " the information about only the mode."} }; From abda0cade5a5d6af5017a9b06bf27614909b8255 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 13:58:18 +0200 Subject: [PATCH 0159/1414] Enable legacy_parser on emu --- grub-core/Makefile.core.def | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index cbc5b7438..36a6e6564 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1411,6 +1411,7 @@ module = { common = commands/legacycfg.c; common = lib/legacy_parse.c; enable = i386_pc; + enable = emu; }; module = { From 64ad6157ae4f9d68be1b96ad7882544241a3e0f4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 14:01:02 +0200 Subject: [PATCH 0160/1414] Fix bunch of memory problems and implement hdbias --- grub-core/commands/legacycfg.c | 147 +++++++++++++++++++++++++-------- grub-core/lib/legacy_parse.c | 36 ++++++-- util/grub-menulst2cfg.c | 14 +++- 3 files changed, 153 insertions(+), 44 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 82901b0e7..e42ca5878 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include static grub_err_t legacy_file (const char *filename) @@ -67,7 +69,7 @@ legacy_file (const char *filename) while (1) { char *buf = grub_file_getline (file); - char *parsed; + char *parsed = NULL; if (!buf && grub_errno) { @@ -84,7 +86,7 @@ legacy_file (const char *filename) oldname = entryname; parsed = grub_legacy_parse (buf, &entryname, &is_suffix); - grub_free (buf); + buf = NULL; if (is_suffix) { char *t; @@ -100,7 +102,7 @@ legacy_file (const char *filename) grub_free (suffix); return grub_errno; } - grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, + grub_memcpy (suffix + grub_strlen (suffix), parsed, grub_strlen (parsed) + 1); grub_free (parsed); parsed = NULL; @@ -117,6 +119,9 @@ legacy_file (const char *filename) args[0] = oldname; grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); } } @@ -125,6 +130,7 @@ legacy_file (const char *filename) grub_normal_parse_line (parsed, getline); grub_print_error (); grub_free (parsed); + parsed = NULL; } else if (parsed) { @@ -163,11 +169,13 @@ legacy_file (const char *filename) } args[0] = entryname; grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc); + grub_free (args); } grub_normal_parse_line (suffix, getline); grub_print_error (); grub_free (suffix); + grub_free (entrysrc); if (menu && menu->size) grub_show_menu (menu, 1); @@ -215,6 +223,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), struct grub_command *cmd; char **cutargs; int cutargc; + for (i = 0; i < 2; i++) { /* FIXME: really support this. */ @@ -309,46 +318,118 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), grub_errno = GRUB_ERR_NONE; } - /* k*BSD didn't really work well with grub-legacy. */ - if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) + { + int bsd_device = -1; + int bsd_slice = -1; + int bsd_part = -1; { - cmd = grub_command_find ("kfreebsd"); - if (cmd) + grub_device_t dev; + char *hdbiasstr; + int hdbias = 0; + hdbiasstr = grub_env_get ("legacy_hdbias"); + if (hdbiasstr) { - if (!(cmd->func) (cmd, cutargc, cutargs)) - { - kernel_type = KFREEBSD; - return GRUB_ERR_NONE; - } + hdbias = grub_strtoul (hdbiasstr, 0, 0); + grub_errno = GRUB_ERR_NONE; + } + dev = grub_device_open (0); + if (dev && dev->disk + && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID + && dev->disk->dev->id >= 0x80 && dev->disk->dev->id <= 0x90) + { + struct grub_partition *part = dev->disk->partition; + bsd_device = dev->disk->id - 0x80 - hdbias; + if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0 + || grub_strcmp (part->partmap->name, "openbsd") == 0 + || grub_strcmp (part->partmap->name, "bsd") == 0)) + { + bsd_part = part->number; + part = part->parent; + } + if (part && grub_strcmp (part->partmap->name, "msdos") == 0) + bsd_slice = part->number; } - grub_errno = GRUB_ERR_NONE; } - if (kernel_type == GUESS_IT || kernel_type == KNETBSD) + + /* k*BSD didn't really work well with grub-legacy. */ + if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) + { + char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")]; + if (bsd_device != -1) + { + if (bsd_slice != -1 && bsd_part != -1) + grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device, + bsd_slice, 'a' + bsd_part); + else if (bsd_slice != -1) + grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device, + bsd_slice); + else + grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device); + grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf); + } + else + grub_env_unset ("kFreeBSD.vfs.root.mountfrom"); + cmd = grub_command_find ("kfreebsd"); + if (cmd) + { + if (!(cmd->func) (cmd, cutargc, cutargs)) + { + kernel_type = KFREEBSD; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } { - cmd = grub_command_find ("knetbsd"); - if (cmd) + char **bsdargs; + int bsdargc; + char bsddevname[sizeof ("wdXXXXXXXXXXXXY")]; + if (bsd_device == -1) { - if (!(cmd->func) (cmd, cutargc, cutargs)) - { - kernel_type = KNETBSD; - return GRUB_ERR_NONE; - } + bsdargs = cutargs; + bsdargc = cutargc; } - grub_errno = GRUB_ERR_NONE; - } - if (kernel_type == GUESS_IT || kernel_type == KOPENBSD) - { - cmd = grub_command_find ("kopenbsd"); - if (cmd) + else { - if (!(cmd->func) (cmd, cutargc, cutargs)) - { - kernel_type = KOPENBSD; - return GRUB_ERR_NONE; - } + bsdargc = cutargc + 2; + bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); + grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0])); + bsdargs[argc] = "-r"; + bsdargs[argc + 1] = bsddevname; + grub_snprintf (bsddevname, sizeof (bsddevname), + "wd%d%c", bsd_device, + bsd_part != -1 ? bsd_part + 'a' : 'c'); } - grub_errno = GRUB_ERR_NONE; + if (kernel_type == GUESS_IT || kernel_type == KNETBSD) + { + cmd = grub_command_find ("knetbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, bsdargc, bsdargs)) + { + kernel_type = KNETBSD; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + if (kernel_type == GUESS_IT || kernel_type == KOPENBSD) + { + cmd = grub_command_find ("kopenbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, bsdargc, bsdargs)) + { + kernel_type = KOPENBSD; + return GRUB_ERR_NONE; + } + } + grub_errno = GRUB_ERR_NONE; + } + if (bsdargs != cutargs) + grub_free (bsdargs); } + } } while (0); diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index dabc497be..01b836087 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -195,7 +195,9 @@ struct legacy_command legacy_commands[] = {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, /* FIXME: Support HDBIAS. */ /* FIXME: Support printing. */ - {"root", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, "[DEVICE [HDBIAS]]", + {"root", "set root='%s'; set legacy_hdbias='%s'\n", + 2, {TYPE_PARTITION, TYPE_INT}, 0, + "[DEVICE [HDBIAS]]", "Set the current \"root device\" to the device DEVICE, then" " attempt to mount it to get the partition size (for passing the" " partition descriptor in `ES:ESI', used by some chain-loaded" @@ -206,7 +208,8 @@ struct legacy_command legacy_commands[] = " how many BIOS drive numbers are on controllers before the current" " one. For example, if there is an IDE disk and a SCSI disk, and your" " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, - {"rootnoverify", "set root='%s'\n", 1, {TYPE_PARTITION}, 0, + {"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n", + 2, {TYPE_PARTITION, TYPE_INT}, 0, "[DEVICE [HDBIAS]]", "Similar to `root', but don't attempt to mount the partition. This" " is useful for when an OS is outside of the area of the disk that" @@ -265,7 +268,7 @@ grub_legacy_escape (const char *in, grub_size_t len) for (ptr = in; ptr < in + len && *ptr; ptr++) if (*ptr == '\'' || *ptr == '\\') overhead++; - ret = grub_malloc (ptr - in + overhead); + ret = grub_malloc (ptr - in + overhead + 1); if (!ret) return NULL; outptr = ret; @@ -371,7 +374,15 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); if (!*ptr || *ptr == '#') - return grub_strdup (buf); + { + char *ret; + int len = grub_strlen (buf); + ret = grub_malloc (len + 2); + grub_memcpy (ret, buf, len); + ret[len] = '\n'; + ret[len + 1] = 0; + return ret; + } cmdname = ptr; for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); @@ -412,7 +423,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) unsigned j = 0; int hold_arg = 0; const char *curarg = NULL; - for (i = 0; i < legacy_commands[cmdnum].argc; i++) + for (i = 0; i < legacy_commands[cmdnum].argc + hold_arg; i++) { grub_size_t curarglen; if (hold_arg) @@ -495,7 +506,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) args[j++] = grub_strndup (curarg, curarglen); break; } - args[j++] = ""; + args[j++] = grub_strdup (""); hold_arg = 1; break; case TYPE_INT: @@ -536,7 +547,14 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) } } } - - return grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2], - args[3]); + + { + char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], + args[2], args[3]); + grub_free (args[0]); + grub_free (args[1]); + grub_free (args[2]); + grub_free (args[3]); + return ret; + } } diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 0184b3fe3..38a906c0a 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -88,12 +88,18 @@ main (int argc, char **argv) if (oldname != entryname && oldname) fprintf (out, "}\n\n"); if (oldname != entryname) - fprintf (out, "menuentry \'%s\' {\n", - grub_legacy_escape (entryname, strlen (entryname))); + { + char *escaped = grub_legacy_escape (entryname, strlen (entryname)); + fprintf (out, "menuentry \'%s\' {\n", escaped); + grub_free (escaped); + grub_free (oldname); + } } if (parsed) fprintf (out, "%s%s", entryname ? " " : "", parsed); + grub_free (parsed); + parsed = NULL; } if (entryname) @@ -101,6 +107,10 @@ main (int argc, char **argv) fwrite (out, 1, suffixlen, suffix); + grub_free (buf); + grub_free (suffix); + grub_free (entryname); + if (in != stdin) fclose (in); if (out != stdout) From b2b260b9eb009126690c700e00b902d5ba1b7ba8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 14:04:10 +0200 Subject: [PATCH 0161/1414] REmove obsolete FIXME --- grub-core/lib/legacy_parse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 01b836087..44dc31d81 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -193,7 +193,6 @@ struct legacy_command legacy_commands[] = "Read a 32-bit value from memory at address ADDR and" " display it in hex format."}, {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, - /* FIXME: Support HDBIAS. */ /* FIXME: Support printing. */ {"root", "set root='%s'; set legacy_hdbias='%s'\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, From 21d7be66125b6cfe48dbc9110e42a7e436548138 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 14:18:39 +0200 Subject: [PATCH 0162/1414] Support (hd0,1,a legacy partition specification --- grub-core/lib/legacy_parse.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 44dc31d81..2bf372de3 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -288,7 +288,7 @@ adjust_file (const char *in, grub_size_t len) const char *comma, *ptr, *rest; char *ret, *outptr; int overhead = 0; - int part; + int part = -1, subpart = -1; if (in[0] != '(') return grub_legacy_escape (in, len); for (ptr = in + 1; ptr < in + len && *ptr && *ptr != ')' @@ -299,12 +299,17 @@ adjust_file (const char *in, grub_size_t len) if (*comma != ',') return grub_legacy_escape (in, len); part = grub_strtoull (comma + 1, (char **) &rest, 0); + if (rest[0] == ',' && rest[1] >= 'a' && rest[1] <= 'z') + { + subpart = rest[1] - 'a'; + rest += 2; + } for (ptr = rest; ptr < in + len && *ptr; ptr++) if (*ptr == '\'' || *ptr == '\\') overhead++; - /* 30 is enough for any number. */ - ret = grub_malloc (ptr - in + overhead + 30); + /* 35 is enough for any 2 numbers. */ + ret = grub_malloc (ptr - in + overhead + 35); if (!ret) return NULL; @@ -316,7 +321,10 @@ adjust_file (const char *in, grub_size_t len) *outptr++ = *ptr; } - grub_snprintf (outptr, 30, "%d", part + 1); + if (subpart != -1) + grub_snprintf (outptr, 35, "%d,%d", part + 1, subpart + 1); + else + grub_snprintf (outptr, 35, "%d", part + 1); while (*outptr) outptr++; for (ptr = rest; ptr < in + len; ptr++) @@ -378,8 +386,13 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) int len = grub_strlen (buf); ret = grub_malloc (len + 2); grub_memcpy (ret, buf, len); - ret[len] = '\n'; - ret[len + 1] = 0; + if (len && ret[len - 1] == '\n') + ret[len] = 0; + else + { + ret[len] = '\n'; + ret[len + 1] = 0; + } return ret; } From 281d690594631f846ea76585fe154aa79f4d8beb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 15:26:38 +0200 Subject: [PATCH 0163/1414] Add no-argument version of commands and remove legacy_color --- grub-core/commands/legacycfg.c | 49 ++-------------- grub-core/lib/legacy_parse.c | 102 ++++++++++++++++++++++++++------- 2 files changed, 88 insertions(+), 63 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index e42ca5878..ca69a7817 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -500,39 +500,6 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused "no kernel with module support is loaded in legacy way"); } -static grub_err_t -grub_cmd_legacy_color (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) -{ - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "color required"); - grub_env_set ("color_normal", args[0]); - if (argc >= 2) - grub_env_set ("color_highlight", args[1]); - else - { - char *slash = grub_strchr (args[0], '/'); - char *invert; - grub_size_t len; - - len = grub_strlen (args[0]); - if (!slash) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad color specification %s", - args[0]); - invert = grub_malloc (len + 1); - if (!invert) - return grub_errno; - grub_memcpy (invert, slash + 1, len - (slash - args[0]) - 1); - invert[len - (slash - args[0]) - 1] = '/'; - grub_memcpy (invert + len - (slash - args[0]), args[0], slash - args[0]); - invert[len] = 0; - grub_env_set ("color_highlight", invert); - grub_free (invert); - } - - return grub_errno; -} - static grub_err_t check_password_deny (const char *user __attribute__ ((unused)), const char *entered __attribute__ ((unused)), @@ -714,13 +681,18 @@ grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), } static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; -static grub_command_t cmd_color, cmd_password, cmd_initrdnounzip; +static grub_command_t cmd_password, cmd_initrdnounzip; GRUB_MOD_INIT(legacycfg) { cmd_source = grub_register_command ("legacy_source", grub_cmd_legacy_source, N_("FILE"), N_("Parse legacy config")); + cmd_configfile = grub_register_command ("legacy_configfile", + grub_cmd_legacy_configfile, + N_("FILE"), + N_("Parse legacy config")); + cmd_kernel = grub_register_command ("legacy_kernel", grub_cmd_legacy_kernel, N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"), @@ -735,14 +707,6 @@ GRUB_MOD_INIT(legacycfg) N_("FILE [ARG ...]"), N_("Simulate grub-legacy modulenounzip command")); - cmd_configfile = grub_register_command ("legacy_configfile", - grub_cmd_legacy_configfile, - N_("FILE"), - N_("Parse legacy config")); - cmd_color = grub_register_command ("legacy_color", - grub_cmd_legacy_color, - N_("NORMAL [HIGHLIGHT]"), - N_("Simulate grub-legacy color command")); cmd_password = grub_register_command ("legacy_password", grub_cmd_legacy_password, N_("[--md5] PASSWD [FILE]"), @@ -756,6 +720,5 @@ GRUB_MOD_FINI(legacycfg) grub_unregister_command (cmd_kernel); grub_unregister_command (cmd_initrd); grub_unregister_command (cmd_initrdnounzip); - grub_unregister_command (cmd_color); grub_unregister_command (cmd_password); } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 2bf372de3..096975434 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -41,8 +41,11 @@ struct legacy_command TYPE_REST_VERBATIM } argt[4]; enum { - FLAG_IGNORE_REST = 1, - FLAG_SUFFIX = 2 + FLAG_IGNORE_REST = 1, + FLAG_SUFFIX = 2, + FLAG_FALLBACK_AVAILABLE = 4, + FLAG_FALLBACK = 8, + FLAG_COLOR_INVERT = 16, } flags; const char *shortdesc; const char *longdesc; @@ -65,8 +68,9 @@ struct legacy_command legacy_commands[] = "FILE1 FILE2", "Compare the file FILE1 with the FILE2 and inform the different values" " if any."}, - {"color", "legacy_color '%s' '%s'\n", 2, {TYPE_VERBATIM, TYPE_VERBATIM}, - FLAG_IGNORE_REST, "NORMAL [HIGHLIGHT]", + {"color", "set color_normal='%s'; set color_highlight='%s'\n", + 2, {TYPE_VERBATIM, TYPE_VERBATIM}, + FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE, "NORMAL [HIGHLIGHT]", "Change the menu colors. The color NORMAL is used for most" " lines in the menu, and the color HIGHLIGHT is used to highlight the" " line where the cursor points. If you omit HIGHLIGHT, then the" @@ -77,6 +81,9 @@ struct legacy_command legacy_commands[] = " light-green, light-cyan, light-red, light-magenta, yellow and white." " But only the first eight names can be used for BG. You can prefix" " \"blink-\" to FG if you want a blinking foreground color."}, + {"color", "set color_normal='%s'; set color_highlight='%s'\n", + 1, {TYPE_VERBATIM}, + FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_COLOR_INVERT, NULL, NULL}, {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0, "FILE", "Load FILE as the configuration file."}, {"debug", @@ -160,10 +167,15 @@ struct legacy_command legacy_commands[] = "FILE [ARG ...]", "The same as `module', except that automatic decompression is" " disabled."}, - /* FIXME: allow toggle. */ - {"pager", "set pager=%d\n", 1, {TYPE_BOOL}, 0, "[FLAG]", + {"pager", "set pager=%s; if [ \"$pager\" = 0 ]; then " + " echo Internal pager is now off; else echo Internal pager is now on; fi\n", + 1, {TYPE_BOOL}, FLAG_FALLBACK_AVAILABLE, "[FLAG]", "Toggle pager mode with no argument. If FLAG is given and its value" " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, + {"pager", + "if [ \"$pager\" = 1 ]; then pager=0; echo Internal pager is now off;" + "else pager=1; echo Internal pager is now on; fi\n", 0, {}, + FLAG_FALLBACK, NULL, NULL}, /* FIXME: partnew unsupported. */ {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, "PART TYPE", "Change the type of the partition PART to TYPE."}, @@ -193,9 +205,8 @@ struct legacy_command legacy_commands[] = "Read a 32-bit value from memory at address ADDR and" " display it in hex format."}, {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, - /* FIXME: Support printing. */ {"root", "set root='%s'; set legacy_hdbias='%s'\n", - 2, {TYPE_PARTITION, TYPE_INT}, 0, + 2, {TYPE_PARTITION, TYPE_INT}, FLAG_FALLBACK_AVAILABLE, "[DEVICE [HDBIAS]]", "Set the current \"root device\" to the device DEVICE, then" " attempt to mount it to get the partition size (for passing the" @@ -207,6 +218,7 @@ struct legacy_command legacy_commands[] = " how many BIOS drive numbers are on controllers before the current" " one. For example, if there is an IDE disk and a SCSI disk, and your" " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, + {"root", "echo \"$root\"\n", 0, {}, FLAG_FALLBACK, NULL, NULL}, {"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, "[DEVICE [HDBIAS]]", @@ -215,6 +227,7 @@ struct legacy_command legacy_commands[] = " GRUB can read, but setting the correct root device is still" " desired. Note that the items mentioned in `root' which" " derived from attempting the mount will NOT work correctly."}, + {"rootnoverify", "echo \"$root\"\n", 0, {}, FLAG_FALLBACK, NULL, NULL}, /* FIXME: support saving NUM and fallback. */ {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0, "[NUM | `fallback']", @@ -432,7 +445,6 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) grub_memset (args, 0, sizeof (args)); { - unsigned j = 0; int hold_arg = 0; const char *curarg = NULL; for (i = 0; i < legacy_commands[cmdnum].argc + hold_arg; i++) @@ -445,6 +457,8 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) } for (; grub_isspace (*ptr); ptr++); curarg = ptr; + if (!*curarg) + break; for (; *ptr && !grub_isspace (*ptr); ptr++); if (i != legacy_commands[cmdnum].argc - 1 || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) @@ -463,7 +477,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) hold_arg = 1; case TYPE_PARTITION: case TYPE_FILE: - args[j++] = adjust_file (curarg, curarglen); + args[i] = adjust_file (curarg, curarglen); break; case TYPE_REST_VERBATIM: @@ -481,7 +495,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) ptr++; overhead += 3; } - outptr0 = args[j++] = grub_malloc (overhead + (ptr - curarg)); + outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg)); if (!outptr0) return NULL; ptr = curarg; @@ -507,7 +521,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) break; case TYPE_VERBATIM: - args[j++] = grub_legacy_escape (curarg, curarglen); + args[i] = grub_legacy_escape (curarg, curarglen); break; case TYPE_FORCE_OPTION: case TYPE_NOAPM_OPTION: @@ -515,10 +529,10 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) case TYPE_OPTION: if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen)) { - args[j++] = grub_strndup (curarg, curarglen); + args[i] = grub_strndup (curarg, curarglen); break; } - args[j++] = grub_strdup (""); + args[i] = grub_strdup (""); hold_arg = 1; break; case TYPE_INT: @@ -526,8 +540,6 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) const char *brk; int base = 10; brk = curarg; - if (curarglen < 1) - args[j++] = grub_strdup ("0"); if (brk[0] == '0' && brk[1] == 'x') base = 16; else if (brk[0] == '0') @@ -545,21 +557,71 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) break; } if (brk == curarg) - args[j++] = grub_strdup ("0"); + args[i] = grub_strdup ("0"); else - args[j++] = grub_strndup (curarg, brk - curarg); + args[i] = grub_strndup (curarg, brk - curarg); } break; case TYPE_BOOL: if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n') - args[j++] = grub_strdup ("1"); + args[i] = grub_strdup ("1"); else - args[j++] = grub_strdup ("0"); + args[i] = grub_strdup ("0"); break; } } } + while (legacy_commands[cmdnum].argc > 0 + && args[legacy_commands[cmdnum].argc - 1] == NULL + && (legacy_commands[cmdnum].flags & FLAG_FALLBACK_AVAILABLE) + && args[legacy_commands[cmdnum + 1].argc] == NULL) + cmdnum++; + + for (; i < legacy_commands[cmdnum].argc; i++) + switch (legacy_commands[cmdnum].argt[i]) + { + case TYPE_FILE_NO_CONSUME: + case TYPE_PARTITION: + case TYPE_FILE: + case TYPE_REST_VERBATIM: + case TYPE_VERBATIM: + case TYPE_FORCE_OPTION: + case TYPE_NOAPM_OPTION: + case TYPE_TYPE_OR_NOMEM_OPTION: + case TYPE_OPTION: + args[i] = grub_strdup (""); + break; + case TYPE_BOOL: + case TYPE_INT: + args[i] = grub_strdup ("0"); + break; + } + + if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT) + { + char *corig = args[legacy_commands[cmdnum].argc - 1]; + char *slash = grub_strchr (corig, '/'); + char *invert; + grub_size_t len; + + len = grub_strlen (corig); + if (!slash) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "bad color specification %s", + args[0]); + return NULL; + } + invert = grub_malloc (len + 1); + if (!invert) + return NULL; + grub_memcpy (invert, slash + 1, len - (slash - corig) - 1); + invert[len - (slash - args[0]) - 1] = '/'; + grub_memcpy (invert + len - (slash - corig), corig, slash - corig); + invert[len] = 0; + args[legacy_commands[cmdnum].argc] = invert; + } + { char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2], args[3]); From e64334df29ed3394b9c5f3cb7ad46d06d3160b36 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 15:50:52 +0200 Subject: [PATCH 0164/1414] Support mixed inline and suffix commands --- grub-core/commands/legacycfg.c | 18 ++--- grub-core/lib/legacy_parse.c | 128 ++++++++++++++++++--------------- include/grub/legacy_parse.h | 2 +- util/grub-menulst2cfg.c | 26 +++---- 4 files changed, 94 insertions(+), 80 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index ca69a7817..bea608b9e 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -82,31 +82,31 @@ legacy_file (const char *filename) { char *oldname = NULL; - int is_suffix; + char *newsuffix; oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname, &is_suffix); + parsed = grub_legacy_parse (buf, &entryname, &newsuffix); buf = NULL; - if (is_suffix) + if (newsuffix) { char *t; t = suffix; suffix = grub_realloc (suffix, grub_strlen (suffix) - + grub_strlen (parsed) + 1); + + grub_strlen (newsuffix) + 1); if (!suffix) { grub_free (t); grub_free (entrysrc); grub_free (parsed); + grub_free (newsuffix); grub_free (suffix); return grub_errno; } - grub_memcpy (suffix + grub_strlen (suffix), parsed, - grub_strlen (parsed) + 1); - grub_free (parsed); - parsed = NULL; - continue; + grub_memcpy (suffix + grub_strlen (suffix), newsuffix, + grub_strlen (newsuffix) + 1); + grub_free (newsuffix); + newsuffix = NULL; } if (oldname != entryname && oldname) { diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 096975434..692b1b7d4 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -26,6 +26,8 @@ struct legacy_command { const char *name; const char *map; + const char *suffix; + unsigned suffixarg; unsigned argc; enum arg_type { TYPE_VERBATIM, @@ -42,7 +44,6 @@ struct legacy_command } argt[4]; enum { FLAG_IGNORE_REST = 1, - FLAG_SUFFIX = 2, FLAG_FALLBACK_AVAILABLE = 4, FLAG_FALLBACK = 8, FLAG_COLOR_INVERT = 16, @@ -53,22 +54,22 @@ struct legacy_command struct legacy_command legacy_commands[] = { - {"blocklist", "blocklist '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + {"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", "Print the blocklist notation of the file FILE."}, - {"boot", "boot\n", 0, {}, 0, 0, + {"boot", "boot\n", NULL, 0, 0, {}, 0, 0, "Boot the OS/chain-loader which has been loaded."}, /* FIXME: bootp unsupported. */ - {"cat", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + {"cat", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", "Print the contents of the file FILE."}, - {"chainloader", "chainloader %s '%s'\n", 2, {TYPE_FORCE_OPTION, TYPE_FILE}, - 0, "[--force] FILE", + {"chainloader", "chainloader %s '%s'\n", NULL, 0, + 2, {TYPE_FORCE_OPTION, TYPE_FILE}, 0, "[--force] FILE", "Load the chain-loader FILE. If --force is specified, then load it" " forcibly, whether the boot loader signature is present or not."}, - {"cmp", "cmp '%s' '%s'\n", 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, - "FILE1 FILE2", + {"cmp", "cmp '%s' '%s'\n", NULL, 0, + 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, "FILE1 FILE2", "Compare the file FILE1 with the FILE2 and inform the different values" " if any."}, - {"color", "set color_normal='%s'; set color_highlight='%s'\n", + {"color", "set color_normal='%s'; set color_highlight='%s'\n", NULL, 0, 2, {TYPE_VERBATIM, TYPE_VERBATIM}, FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE, "NORMAL [HIGHLIGHT]", "Change the menu colors. The color NORMAL is used for most" @@ -81,60 +82,62 @@ struct legacy_command legacy_commands[] = " light-green, light-cyan, light-red, light-magenta, yellow and white." " But only the first eight names can be used for BG. You can prefix" " \"blink-\" to FG if you want a blinking foreground color."}, - {"color", "set color_normal='%s'; set color_highlight='%s'\n", + {"color", "set color_normal='%s'; set color_highlight='%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_COLOR_INVERT, NULL, NULL}, - {"configfile", "legacy_configfile '%s'\n", 1, {TYPE_FILE}, 0, "FILE", - "Load FILE as the configuration file."}, + {"configfile", "legacy_configfile '%s'\n", NULL, 0, 1, {TYPE_FILE}, + 0, "FILE", "Load FILE as the configuration file."}, {"debug", - "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", + "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", NULL, 0, 0, {}, 0, 0, "Turn on/off the debug mode."}, {"default", "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; " - "set default=\"$saved_entry\"; fi\n", 1, {TYPE_VERBATIM}, 0, + "set default=\"$saved_entry\"; fi\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "[NUM | `saved']", "Set the default entry to entry number NUM (if not specified, it is" " 0, the first entry) or the entry number saved by savedefault."}, /* FIXME: dhcp unsupported. */ /* FIXME: displayapm unsupported. */ - {"displaymem", "lsmmap\n", 0, {}, 0, 0, + {"displaymem", "lsmmap\n", NULL, 0, 0, {}, 0, 0, "Display what GRUB thinks the system address space map of the" " machine is, including all regions of physical RAM installed."}, /* NOTE: embed unsupported. */ - {"fallback", "set fallback='%s'\n", 1, {TYPE_VERBATIM}, 0, "NUM...", + {"fallback", "set fallback='%s'\n", NULL, 0, + 1, {TYPE_VERBATIM}, 0, "NUM...", "Go into unattended boot mode: if the default boot entry has any" " errors, instead of waiting for the user to do anything, it" " immediately starts over using the NUM entry (same numbering as the" " `default' command). This obviously won't help if the machine" " was rebooted by a kernel that GRUB loaded."}, - {"find", "search -sf '%s'\n", 1, {TYPE_FILE}, 0, "FILENAME", + {"find", "search -sf '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILENAME", "Search for the filename FILENAME in all of partitions and print the list of" " the devices which contain the file."}, /* FIXME: fstest unsupported. */ /* FIXME: geometry unsupported. */ - {"halt", "halt %s\n", 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", + {"halt", "halt %s\n", NULL, 0, 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", "Halt your system. If APM is available on it, turn off the power using" " the APM BIOS, unless you specify the option `--no-apm'."}, /* FIXME: help unsupported. */ /* NUL_TERMINATE */ - {"hiddenmenu", "if sleep -i $timeout; then timeout=0; else timeout=-1; fi\n", - 0, {}, FLAG_SUFFIX, "", "Hide the menu."}, - {"hide", "parttool '%s' hidden+\n", 1, {TYPE_PARTITION}, 0, "PARTITION", + {"hiddenmenu", NULL, + "if sleep -i $timeout; then timeout=0; else timeout=-1; fi\n", 0, + 0, {}, 0, "", "Hide the menu."}, + {"hide", "parttool '%s' hidden+\n", NULL, 0, 1, {TYPE_PARTITION}, + 0, "PARTITION", "Hide PARTITION by setting the \"hidden\" bit in" " its partition type code."}, /* FIXME: ifconfig unsupported. */ /* FIXME: impsprobe unsupported. */ - {"initrd", "legacy_initrd '%s' %s\n", 2, {TYPE_FILE_NO_CONSUME, - TYPE_REST_VERBATIM}, 0, + {"initrd", "legacy_initrd '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME, + TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "Load an initial ramdisk FILE for a Linux format boot image and set the" " appropriate parameters in the Linux setup area in memory."}, /* NOTE: install unsupported. */ /* FIXME: ioprobe unsupported. */ /* FIXME: really support --no-mem-option. */ - {"kernel", "legacy_kernel %s %s '%s' %s\n", 4, {TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_FILE_NO_CONSUME, - TYPE_REST_VERBATIM}, 0, + {"kernel", "legacy_kernel %s %s '%s' %s\n", NULL, 0, + 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, + TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, "[--no-mem-option] [--type=TYPE] FILE [ARG ...]", "Attempt to load the primary boot image from FILE. The rest of the" " line is passed verbatim as the \"kernel command line\". Any modules" @@ -144,46 +147,49 @@ struct legacy_command legacy_commands[] = " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" " Linux's mem option automatically."}, /* FIXME: lock is unsupported. */ - {"makeactive", "parttool \"$root\" boot+\n", 0, {}, 0, 0, + {"makeactive", "parttool \"$root\" boot+\n", NULL, 0, 0, {}, 0, 0, "Set the active partition on the root disk to GRUB's root device." " This command is limited to _primary_ PC partitions on a hard disk."}, - {"map", "drivemap '%s' '%s'\n", 2, {TYPE_PARTITION, TYPE_PARTITION}, + {"map", "drivemap '%s' '%s'\n", NULL, 0, + 2, {TYPE_PARTITION, TYPE_PARTITION}, FLAG_IGNORE_REST, "TO_DRIVE FROM_DRIVE", "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" " when you chain-load some operating systems, such as DOS, if such an" " OS resides at a non-first drive."}, /* NOTE: md5crypt unsupported since GRUB has not enough entropy and this hash shouldn't be used anymore. */ - {"module", "legacy_initrd '%s' %s\n", 1, {TYPE_FILE_NO_CONSUME, - TYPE_REST_VERBATIM}, 0, + {"module", "legacy_initrd '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME, + TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "Load a boot module FILE for a Multiboot format boot image (no" " interpretation of the file contents is made, so users of this" " command must know what the kernel in question expects). The" " rest of the line is passed as the \"module command line\", like" " the `kernel' command."}, - {"modulenounzip", "legacy_initrd_nounzip '%s' %s\n", 1, + {"modulenounzip", "legacy_initrd_nounzip '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, "FILE [ARG ...]", "The same as `module', except that automatic decompression is" " disabled."}, {"pager", "set pager=%s; if [ \"$pager\" = 0 ]; then " - " echo Internal pager is now off; else echo Internal pager is now on; fi\n", + " echo Internal pager is now off; else " + "echo Internal pager is now on; fi\n", NULL, 0, 1, {TYPE_BOOL}, FLAG_FALLBACK_AVAILABLE, "[FLAG]", "Toggle pager mode with no argument. If FLAG is given and its value" " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, {"pager", "if [ \"$pager\" = 1 ]; then pager=0; echo Internal pager is now off;" - "else pager=1; echo Internal pager is now on; fi\n", 0, {}, + "else pager=1; echo Internal pager is now on; fi\n", NULL, 0, 0, {}, FLAG_FALLBACK, NULL, NULL}, /* FIXME: partnew unsupported. */ - {"parttype", "parttool '%s' type=%s\n", 2, {TYPE_PARTITION, TYPE_INT}, 0, + {"parttype", "parttool '%s' type=%s\n", NULL, 0, + 2, {TYPE_PARTITION, TYPE_INT}, 0, "PART TYPE", "Change the type of the partition PART to TYPE."}, /* FIXME: support config file reloading. */ /* FIXME: support usage in menuentry. */ {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" - "legacy_password %s '%s' %s", 3, {TYPE_OPTION, TYPE_VERBATIM, - TYPE_FILE}, FLAG_IGNORE_REST, + "legacy_password %s '%s' %s", NULL, 0, 3, {TYPE_OPTION, TYPE_VERBATIM, + TYPE_FILE}, FLAG_IGNORE_REST, "[--md5] PASSWD [FILE]", "If used in the first section of a menu file, disable all" " interactive editing control (menu entry editor and" @@ -197,15 +203,15 @@ struct legacy_command legacy_commands[] = /* NOTE: GRUB2 has a design principle of not eternally waiting for user input. 60 seconds should be enough. */ - {"pause", "echo %s; if ! sleep -i 60; then return; fi\n", 1, + {"pause", "echo %s; if ! sleep -i 60; then return; fi\n", NULL, 0, 1, {TYPE_REST_VERBATIM}, 0, "[MESSAGE ...]", "Print MESSAGE, then wait until a key is pressed."}, /* FIXME: rarp unsupported. */ - {"read", "read_dword %s\n", 1, {TYPE_INT}, 0, "ADDR", + {"read", "read_dword %s\n", NULL, 0, 1, {TYPE_INT}, 0, "ADDR", "Read a 32-bit value from memory at address ADDR and" " display it in hex format."}, - {"reboot", "reboot\n", 0, {}, 0, 0, "Reboot your system."}, - {"root", "set root='%s'; set legacy_hdbias='%s'\n", + {"reboot", "reboot\n", NULL, 0, 0, {}, 0, 0, "Reboot your system."}, + {"root", "set root='%s'; set legacy_hdbias='%s'\n", NULL, 0, 2, {TYPE_PARTITION, TYPE_INT}, FLAG_FALLBACK_AVAILABLE, "[DEVICE [HDBIAS]]", "Set the current \"root device\" to the device DEVICE, then" @@ -218,8 +224,8 @@ struct legacy_command legacy_commands[] = " how many BIOS drive numbers are on controllers before the current" " one. For example, if there is an IDE disk and a SCSI disk, and your" " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, - {"root", "echo \"$root\"\n", 0, {}, FLAG_FALLBACK, NULL, NULL}, - {"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n", + {"root", "echo \"$root\"\n", NULL, 0, 0, {}, FLAG_FALLBACK, NULL, NULL}, + {"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n", NULL, 0, 2, {TYPE_PARTITION, TYPE_INT}, 0, "[DEVICE [HDBIAS]]", "Similar to `root', but don't attempt to mount the partition. This" @@ -227,14 +233,15 @@ struct legacy_command legacy_commands[] = " GRUB can read, but setting the correct root device is still" " desired. Note that the items mentioned in `root' which" " derived from attempting the mount will NOT work correctly."}, - {"rootnoverify", "echo \"$root\"\n", 0, {}, FLAG_FALLBACK, NULL, NULL}, + {"rootnoverify", "echo \"$root\"\n", NULL, 0, + 0, {}, FLAG_FALLBACK, NULL, NULL}, /* FIXME: support saving NUM and fallback. */ - {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", 0, {}, 0, - "[NUM | `fallback']", + {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", NULL, 0, + 0, {}, 0, "[NUM | `fallback']", "Save the current entry as the default boot entry if no argument is" " specified. If a number is specified, this number is saved. If" " `fallback' is used, next fallback entry is saved."}, - {"serial", "serial %s\n", 1, {TYPE_REST_VERBATIM}, 0, + {"serial", "serial %s\n", NULL, 0, 1, {TYPE_REST_VERBATIM}, 0, "[--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] " "[--parity=PARITY] [--stop=STOP] [--device=DEV]", "Initialize a serial device. UNIT is a digit that specifies which serial" @@ -248,25 +255,26 @@ struct legacy_command legacy_commands[] = /* FIXME: setup unsupported. */ /* FIXME: terminal unsupported. */ /* NUL_TERMINATE */ /* FIXME: terminfo unsupported. */ /* NUL_TERMINATE */ - {"testload", "cat '%s'\n", 1, {TYPE_FILE}, 0, "FILE", + {"testload", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", "Read the entire contents of FILE in several different ways and" " compares them, to test the filesystem code. " " If this test succeeds, then a good next" " step is to try loading a kernel."}, /* FIXME: testvbe unsupported. */ /* FIXME: tftpserver unsupported. */ - {"timeout", "set timeout=%s\n", 1, {TYPE_INT}, 0, "SEC", + {"timeout", "set timeout=%s\n", NULL, 0, 1, {TYPE_INT}, 0, "SEC", "Set a timeout, in SEC seconds, before automatically booting the" " default entry (normally the first entry defined)."}, /* title is handled separately. */ - {"unhide", "parttool '%s' hidden-\n", 1, {TYPE_PARTITION}, 0, "PARTITION", + {"unhide", "parttool '%s' hidden-\n", NULL, 0, + 1, {TYPE_PARTITION}, 0, "PARTITION", "Unhide PARTITION by clearing the \"hidden\" bit in its" " partition type code."}, /* FIXME: uppermem unsupported. */ - {"uuid", "search -u '%s'\n", 1, {TYPE_VERBATIM}, 0, "UUID", + {"uuid", "search -u '%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "UUID", "Find root by UUID"}, /* FIXME: support MODE. */ - {"vbeprobe", "vbeinfo\n", 0, {}, 0, "[MODE]", + {"vbeprobe", "vbeinfo\n", NULL, 0, 0, {}, 0, "[MODE]", "Probe VBE information. If the mode number MODE is specified, show only" " the information about only the mode."} }; @@ -384,13 +392,13 @@ is_option (enum arg_type opt, const char *curarg, grub_size_t len) } char * -grub_legacy_parse (const char *buf, char **entryname, int *suffix) +grub_legacy_parse (const char *buf, char **entryname, char **suffix) { const char *ptr; const char *cmdname; unsigned i, cmdnum; - *suffix = 0; + *suffix = NULL; for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); if (!*ptr || *ptr == '#') @@ -437,8 +445,6 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) if (cmdnum == ARRAY_SIZE (legacy_commands)) return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); - *suffix = !!(legacy_commands[cmdnum].flags & FLAG_SUFFIX); - for (; grub_isspace (*ptr) || *ptr == '='; ptr++); char *args[ARRAY_SIZE (legacy_commands[0].argt)]; @@ -447,7 +453,7 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) { int hold_arg = 0; const char *curarg = NULL; - for (i = 0; i < legacy_commands[cmdnum].argc + hold_arg; i++) + for (i = 0; i < legacy_commands[cmdnum].argc; i++) { grub_size_t curarglen; if (hold_arg) @@ -622,6 +628,14 @@ grub_legacy_parse (const char *buf, char **entryname, int *suffix) args[legacy_commands[cmdnum].argc] = invert; } + if (legacy_commands[cmdnum].suffix) + { + *suffix = grub_xasprintf (legacy_commands[cmdnum].suffix, + args[legacy_commands[cmdnum].suffixarg]); + if (*suffix) + return NULL; + } + { char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], args[2], args[3]); diff --git a/include/grub/legacy_parse.h b/include/grub/legacy_parse.h index a6394496f..a5e67a071 100644 --- a/include/grub/legacy_parse.h +++ b/include/grub/legacy_parse.h @@ -21,7 +21,7 @@ #include -char *grub_legacy_parse (const char *buf, char **entryname, int *suffix); +char *grub_legacy_parse (const char *buf, char **entryname, char **suffix); char *grub_legacy_escape (const char *in, grub_size_t len); #endif diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 38a906c0a..512239e89 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -20,6 +20,7 @@ #include #include #include +#include int main (int argc, char **argv) @@ -30,7 +31,6 @@ main (int argc, char **argv) size_t bufsize = 0; char *suffix = xstrdup (""); int suffixlen = 0; - int is_suffix = 0; if (argc >= 2 && argv[1][0] == '-') { @@ -75,15 +75,15 @@ main (int argc, char **argv) { char *oldname = NULL; + char *newsuffix; oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname, &is_suffix); - if (is_suffix) + parsed = grub_legacy_parse (buf, &entryname, &newsuffix); + if (newsuffix) { - suffixlen += strlen (parsed); + suffixlen += strlen (newsuffix); suffix = xrealloc (suffix, suffixlen + 1); - strcat (suffix, parsed); - continue; + strcat (suffix, newsuffix); } if (oldname != entryname && oldname) fprintf (out, "}\n\n"); @@ -91,25 +91,25 @@ main (int argc, char **argv) { char *escaped = grub_legacy_escape (entryname, strlen (entryname)); fprintf (out, "menuentry \'%s\' {\n", escaped); - grub_free (escaped); - grub_free (oldname); + free (escaped); + free (oldname); } } if (parsed) fprintf (out, "%s%s", entryname ? " " : "", parsed); - grub_free (parsed); + free (parsed); parsed = NULL; } if (entryname) fprintf (out, "}\n\n"); - fwrite (out, 1, suffixlen, suffix); + fwrite (suffix, 1, suffixlen, out); - grub_free (buf); - grub_free (suffix); - grub_free (entryname); + free (buf); + free (suffix); + free (entryname); if (in != stdin) fclose (in); From 6492c85a42ce35b170e4477243834cf969048916 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 15:54:39 +0200 Subject: [PATCH 0165/1414] Support config file reloading (not tested) --- grub-core/lib/legacy_parse.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 692b1b7d4..3f28544b3 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -185,12 +185,12 @@ struct legacy_command legacy_commands[] = {"parttype", "parttool '%s' type=%s\n", NULL, 0, 2, {TYPE_PARTITION, TYPE_INT}, 0, "PART TYPE", "Change the type of the partition PART to TYPE."}, - /* FIXME: support config file reloading. */ /* FIXME: support usage in menuentry. */ {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" - "legacy_password %s '%s' %s", NULL, 0, 3, {TYPE_OPTION, TYPE_VERBATIM, - TYPE_FILE}, FLAG_IGNORE_REST, - "[--md5] PASSWD [FILE]", + "legacy_password %s '%s'", + "menuentry \"Superuser menu\" --users \"legacy\" { configfile '%s'; }\n", + 2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE}, + FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE, "[--md5] PASSWD [FILE]", "If used in the first section of a menu file, disable all" " interactive editing control (menu entry editor and" " command line). If the password PASSWD is entered, it loads the" @@ -200,6 +200,9 @@ struct legacy_command legacy_commands[] = " which case it will ask for the password, before continuing." " The option --md5 tells GRUB that PASSWD is encrypted with" " md5crypt."}, + {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" + "legacy_password %s '%s'", NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM}, + FLAG_IGNORE_REST | FLAG_FALLBACK, NULL, NULL}, /* NOTE: GRUB2 has a design principle of not eternally waiting for user input. 60 seconds should be enough. */ From df8957929d631ffd298de7c2ab717c245934fe23 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 16:11:41 +0200 Subject: [PATCH 0166/1414] lock support (not tested) --- grub-core/lib/legacy_parse.c | 9 ++------- grub-core/normal/auth.c | 24 ++++++++++++++++++++++++ grub-core/normal/main.c | 2 ++ include/grub/normal.h | 3 +++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 3f28544b3..868eab4ab 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -146,7 +146,8 @@ struct legacy_command legacy_commands[] = " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" " Linux's mem option automatically."}, - /* FIXME: lock is unsupported. */ + {"lock", "if ! authenticate legacy; then return; fi", NULL, 0, 0, {}, 0, + 0, "Break a command execution unless the user is authenticated."}, {"makeactive", "parttool \"$root\" boot+\n", NULL, 0, 0, {}, 0, 0, "Set the active partition on the root disk to GRUB's root device." " This command is limited to _primary_ PC partitions on a hard disk."}, @@ -435,12 +436,6 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) return NULL; } - if (grub_strncmp ("lock", cmdname, ptr - cmdname) == 0 - && ptr - cmdname == sizeof ("lock") - 1) - { - /* FIXME */ - } - for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 && legacy_commands[cmdnum].name[ptr - cmdname] == 0) diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c index bf1efbfdd..e5216da8c 100644 --- a/grub-core/normal/auth.c +++ b/grub-core/normal/auth.c @@ -248,3 +248,27 @@ grub_auth_check_authentication (const char *userlist) return GRUB_ACCESS_DENIED; } + +static grub_err_t +grub_cmd_authenticate (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + return grub_auth_check_authentication ((argc >= 1) ? args[0] : ""); +} + +static grub_command_t cmd; + +void +grub_normal_auth_init (void) +{ + cmd = grub_register_command ("authenticate", + grub_cmd_authenticate, + N_("[USERLIST]"), N_("Authenticate users")); + +} + +void +grub_normal_auth_fini (void) +{ + grub_unregister_command (cmd); +} diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index c7e83fba0..f2e5eaf51 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -477,6 +477,7 @@ GRUB_MOD_INIT(normal) /* Previously many modules depended on gzio. Be nice to user and load it. */ grub_dl_load ("gzio"); + grub_normal_auth_init (); grub_context_init (); grub_script_init (); grub_menu_init (); @@ -520,6 +521,7 @@ GRUB_MOD_FINI(normal) grub_context_fini (); grub_script_fini (); grub_menu_fini (); + grub_normal_auth_fini (); grub_xputs = grub_xputs_saved; diff --git a/include/grub/normal.h b/include/grub/normal.h index 417560d9f..72912e524 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -123,4 +123,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, grub_err_t grub_normal_set_password (const char *user, const char *password); +void grub_normal_auth_init (void); +void grub_normal_auth_fini (void); + #endif /* ! GRUB_NORMAL_HEADER */ From 898330b0973d88db9aebd15b08705485a1f433d1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 12 Sep 2010 16:15:40 +0200 Subject: [PATCH 0167/1414] MArk setup as not to be implemented --- grub-core/lib/legacy_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 868eab4ab..5b5b4d6e2 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -256,7 +256,7 @@ struct legacy_command legacy_commands[] = " in the grub shell, which specifies the file name of a tty device. The" " default values are COM1, 9600, 8N1."}, /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ - /* FIXME: setup unsupported. */ + /* NOTE: setup unsupported. */ /* FIXME: terminal unsupported. */ /* NUL_TERMINATE */ /* FIXME: terminfo unsupported. */ /* NUL_TERMINATE */ {"testload", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", From 779e9dc48071591aa3205bb6087459902820c746 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 00:44:57 +0200 Subject: [PATCH 0168/1414] Support Solaris DHCP ACK parsing --- grub-core/loader/i386/multiboot_mbi.c | 29 ++++++++++++++++++++++++++- grub-core/net/net.c | 2 -- include/grub/net.h | 4 ++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index bf17863cf..9d6497442 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -32,6 +32,7 @@ #include #include #include +#include /* The bits in the required part of flags field we don't support. */ #define UNSUPPORTED_FLAGS 0x0000fff8 @@ -189,12 +190,24 @@ grub_multiboot_load (grub_file_t file) static grub_size_t grub_multiboot_get_mbi_size (void) { - return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + grub_size_t ret; + struct grub_net_network_level_interface *net; + + ret = sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) + elf_sec_entsize * elf_sec_num + 256 * sizeof (struct multiboot_color); + + FOR_NET_NETWORK_LEVEL_INTERFACES(net) + if (net->dhcp_ack) + { + ret += net->dhcp_acklen; + break; + } + + return ret; } /* Fill previously allocated Multiboot mmap. */ @@ -401,6 +414,20 @@ grub_multiboot_make_mbi (grub_uint32_t *target) mbi->flags |= MULTIBOOT_INFO_BOOTDEV; } + { + struct grub_net_network_level_interface *net; + FOR_NET_NETWORK_LEVEL_INTERFACES(net) + if (net->dhcp_ack) + { + grub_memcpy (ptrorig, net->dhcp_ack, net->dhcp_acklen); + mbi->drives_addr = ptrdest; + mbi->drives_length = net->dhcp_acklen; + ptrorig += net->dhcp_acklen; + ptrdest += net->dhcp_acklen; + break; + } + } + if (elf_sec_num) { mbi->u.elf_sec.addr = ptrdest; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index f1838569b..7c8992f8d 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -49,8 +49,6 @@ grub_net_network_level_interface_unregister (struct grub_net_network_level_inter GRUB_AS_LIST (inter)); } -#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) - static inline void grub_net_route_register (struct grub_net_route *route) { diff --git a/include/grub/net.h b/include/grub/net.h index ec334092d..a0737d574 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -277,4 +277,8 @@ void grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf); +extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; +#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) + + #endif /* ! GRUB_NET_HEADER */ From 21e4963bcc9cd307c54762d1715a0d38d502dd9f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 01:12:47 +0200 Subject: [PATCH 0169/1414] Support net_get_dhcp_option --- grub-core/net/net.c | 128 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 7c8992f8d..5205e1938 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -709,8 +709,130 @@ grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, return inter; } +static char +hexdigit (grub_uint8_t val) +{ + if (val < 10) + return val + '0'; + return val + 'a' - 10; +} + +static grub_err_t +grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_interface *inter; + int num; + grub_uint8_t *ptr; + grub_uint8_t taglength; + + if (argc < 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "4 arguments expected"); + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[1])) + break; + + if (!inter) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unrecognised interface %s"), args[1]); + + if (!inter->dhcp_ack) + return grub_error (GRUB_ERR_IO, N_("no DHCP info found")); + + if (inter->dhcp_acklen <= OFFSET_OF (vendor, inter->dhcp_ack)) + return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); + + num = grub_strtoul (args[2], 0, 0); + if (grub_errno) + return grub_errno; + + ptr = inter->dhcp_ack->vendor; + + if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) + != GRUB_NET_BOOTP_RFC1048_MAGIC) + return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); + ptr = ptr + sizeof (grub_uint32_t); + while (1) + { + grub_uint8_t tagtype; + + if (ptr >= ((grub_uint8_t *) inter->dhcp_ack) + inter->dhcp_acklen) + return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); + + tagtype = *ptr++; + + /* Pad tag. */ + if (tagtype == 0) + continue; + + /* End tag. */ + if (tagtype == 0xff) + return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); + + taglength = *ptr++; + + if (tagtype == num) + break; + ptr += taglength; + } + + if (grub_strcmp (args[3], "string") == 0) + { + char *val = grub_malloc (taglength + 1); + if (!val) + return grub_errno; + grub_memcpy (val, ptr, taglength); + val[taglength] = 0; + if (args[0][0] == '-' && args[0][1] == 0) + grub_printf ("%s\n", val); + else + return grub_env_set (args[0], val); + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[3], "number") == 0) + { + grub_uint64_t val = 0; + int i; + for (i = 0; i < taglength; i++) + val = (val << 8) | ptr[i]; + if (args[0][0] == '-' && args[0][1] == 0) + grub_printf ("%llu\n", (unsigned long long) val); + else + { + char valn[64]; + grub_printf (valn, sizeof (valn), "%lld\n", (unsigned long long) val); + return grub_env_set (args[0], valn); + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[3], "hex") == 0) + { + char *val = grub_malloc (2 * taglength + 1); + int i; + if (!val) + return grub_errno; + for (i = 0; i < taglength; i++) + { + val[2 * i] = hexdigit (ptr[i] >> 4); + val[2 * i + 1] = hexdigit (ptr[i] & 0xf); + } + val[2 * taglength] = 0; + if (args[0][0] == '-' && args[0][1] == 0) + grub_printf ("%s\n", val); + else + return grub_env_set (args[0], val); + return GRUB_ERR_NONE; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "unrecognised format specification %s", args[3]); +} + static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -static grub_command_t cmd_lsroutes, cmd_lscards; +static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp; GRUB_MOD_INIT(net) { @@ -730,6 +852,9 @@ GRUB_MOD_INIT(net) "", N_("list network routes")); cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards, "", N_("list network cards")); + cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, + N_("VAR INTERFACE NUMBER DESCRIPTION"), + N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); grub_net_open = grub_net_open_real; } @@ -742,5 +867,6 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_delroute); grub_unregister_command (cmd_lsroutes); grub_unregister_command (cmd_lscards); + grub_unregister_command (cmd_getdhcp); grub_net_open = NULL; } From 44224d3948d9952cb2928571f8aa914ebf6f040a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 02:16:12 +0200 Subject: [PATCH 0170/1414] Fix UUID command. Reported by: Jordan Uggla --- grub-core/lib/legacy_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 5b5b4d6e2..7ecd1c74f 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -275,8 +275,8 @@ struct legacy_command legacy_commands[] = "Unhide PARTITION by clearing the \"hidden\" bit in its" " partition type code."}, /* FIXME: uppermem unsupported. */ - {"uuid", "search -u '%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "UUID", - "Find root by UUID"}, + {"uuid", "search --set=root --fs-uuid '%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, + 0, "UUID", "Find root by UUID"}, /* FIXME: support MODE. */ {"vbeprobe", "vbeinfo\n", NULL, 0, 0, {}, 0, "[MODE]", "Probe VBE information. If the mode number MODE is specified, show only" From e31bb619117766a74a7d5c7f6b87bdcaea7c55c5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 11:39:53 +0200 Subject: [PATCH 0171/1414] Transform legacy mode numbers into resolution specification --- Makefile.util.def | 2 + grub-core/Makefile.core.def | 1 + grub-core/lib/i386/pc/vesa_modes_table.c | 127 +++++++++++++++ grub-core/lib/legacy_parse.c | 42 ++++- grub-core/loader/i386/linux.c | 190 ++--------------------- 5 files changed, 179 insertions(+), 183 deletions(-) create mode 100644 grub-core/lib/i386/pc/vesa_modes_table.c diff --git a/Makefile.util.def b/Makefile.util.def index febbfd0ed..54ec6ee8a 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -563,6 +563,8 @@ program = { mansection = 1; common = util/grub-menulst2cfg.c; common = grub-core/lib/legacy_parse.c; + common = grub-core/lib/i386/pc/vesa_modes_table.c; + ldadd = libgrub.a; ldflags = '$(LIBDEVMAPPER)'; }; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 36a6e6564..03505ad5a 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1111,6 +1111,7 @@ module = { module = { name = linux; x86 = loader/i386/linux.c; + i386_pc = lib/i386/pc/vesa_modes_table.c; mips = loader/mips/linux.c; powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; diff --git a/grub-core/lib/i386/pc/vesa_modes_table.c b/grub-core/lib/i386/pc/vesa_modes_table.c new file mode 100644 index 000000000..6dc4b7d8d --- /dev/null +++ b/grub-core/lib/i386/pc/vesa_modes_table.c @@ -0,0 +1,127 @@ + +#include + +/* This is the reverse of the table in [linux]/Documentation/fb/vesafb.txt + plus a few more modes based on the table in + http://en.wikipedia.org/wiki/VESA_BIOS_Extensions */ +struct grub_vesa_mode_table_entry +grub_vesa_mode_table[GRUB_VESA_MODE_TABLE_END + - GRUB_VESA_MODE_TABLE_START + 1] = + { + { 640, 400, 8 }, /* 0x300 */ + { 640, 480, 8 }, /* 0x301 */ + { 800, 600, 4 }, /* 0x302 */ + { 800, 600, 8 }, /* 0x303 */ + { 1024, 768, 4 }, /* 0x304 */ + { 1024, 768, 8 }, /* 0x305 */ + { 1280, 1024, 4 }, /* 0x306 */ + { 1280, 1024, 8 }, /* 0x307 */ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 320, 200, 15 }, /* 0x30d */ + { 320, 200, 16 }, /* 0x30e */ + { 320, 200, 24 }, /* 0x30f */ + { 640, 480, 15 }, /* 0x310 */ + { 640, 480, 16 }, /* 0x311 */ + { 640, 480, 24 }, /* 0x312 */ + { 800, 600, 15 }, /* 0x313 */ + { 800, 600, 16 }, /* 0x314 */ + { 800, 600, 24 }, /* 0x315 */ + { 1024, 768, 15 }, /* 0x316 */ + { 1024, 768, 16 }, /* 0x317 */ + { 1024, 768, 24 }, /* 0x318 */ + { 1280, 1024, 15 }, /* 0x319 */ + { 1280, 1024, 16 }, /* 0x31a */ + { 1280, 1024, 24 }, /* 0x31b */ + { 1600, 1200, 8 }, /* 0x31c */ + { 1600, 1200, 15 }, /* 0x31d */ + { 1600, 1200, 16 }, /* 0x31e */ + { 1600, 1200, 24 }, /* 0x31f */ + { 0, 0, 0 }, + { 640, 400, 15 }, /* 0x321 */ + { 640, 400, 16 }, /* 0x322 */ + { 640, 400, 24 }, /* 0x323 */ + { 640, 400, 32 }, /* 0x324 */ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 640, 480, 32 }, /* 0x329 */ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 896, 672, 8 }, /* 0x32f */ + { 896, 672, 15 }, /* 0x330 */ + { 896, 672, 16 }, /* 0x331 */ + { 896, 672, 24 }, /* 0x332 */ + { 896, 672, 32 }, /* 0x333 */ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1600, 1200, 32 }, /* 0x342 */ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 1440, 900, 8 }, /* 0x360 */ + { 1440, 900, 15 }, /* 0x361 */ + { 1440, 900, 16 }, /* 0x362 */ + { 1440, 900, 24 }, /* 0x363 */ + { 1440, 900, 32 }, /* 0x364 */ + { 1152, 720, 8 }, /* 0x365 */ + { 1152, 720, 15 }, /* 0x366 */ + { 1152, 720, 16 }, /* 0x367 */ + { 1152, 720, 24 }, /* 0x368 */ + { 1152, 720, 32 }, /* 0x369 */ + { 1024, 640, 8 }, /* 0x36a */ + { 1024, 640, 15 }, /* 0x36b */ + { 1024, 640, 16 }, /* 0x36c */ + { 1024, 640, 24 }, /* 0x36d */ + { 1024, 640, 32 }, /* 0x36e */ + { 800, 500, 8 }, /* 0x36f */ + { 800, 500, 15 }, /* 0x370 */ + { 800, 500, 16 }, /* 0x371 */ + { 800, 500, 24 }, /* 0x372 */ + { 800, 500, 32 }, /* 0x373 */ + }; diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 7ecd1c74f..959d8367d 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -21,6 +21,7 @@ #include #include #include +#include struct legacy_command { @@ -40,7 +41,8 @@ struct legacy_command TYPE_PARTITION, TYPE_BOOL, TYPE_INT, - TYPE_REST_VERBATIM + TYPE_REST_VERBATIM, + TYPE_VBE_MODE } argt[4]; enum { FLAG_IGNORE_REST = 1, @@ -264,7 +266,8 @@ struct legacy_command legacy_commands[] = " compares them, to test the filesystem code. " " If this test succeeds, then a good next" " step is to try loading a kernel."}, - /* FIXME: testvbe unsupported. */ + {"testvbe", "insmod vbe; videotest '%s'\n", NULL, 0, 1, {TYPE_VBE_MODE}, 0, + "MODE", "Test the VBE mode MODE. Hit any key to return."}, /* FIXME: tftpserver unsupported. */ {"timeout", "set timeout=%s\n", NULL, 0, 1, {TYPE_INT}, 0, "SEC", "Set a timeout, in SEC seconds, before automatically booting the" @@ -278,7 +281,7 @@ struct legacy_command legacy_commands[] = {"uuid", "search --set=root --fs-uuid '%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "UUID", "Find root by UUID"}, /* FIXME: support MODE. */ - {"vbeprobe", "vbeinfo\n", NULL, 0, 0, {}, 0, "[MODE]", + {"vbeprobe", "insmod vbe; videoinfo\n", NULL, 0, 0, {}, 0, "[MODE]", "Probe VBE information. If the mode number MODE is specified, show only" " the information about only the mode."} }; @@ -566,6 +569,34 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) args[i] = grub_strndup (curarg, brk - curarg); } break; + case TYPE_VBE_MODE: + { + unsigned mod; + struct grub_vesa_mode_table_entry *modedesc; + + mod = grub_strtoul (curarg, 0, 0); + if (grub_errno) + { + mod = 0; + grub_errno = GRUB_ERR_NONE; + } + if (mod < GRUB_VESA_MODE_TABLE_START + || mod > GRUB_VESA_MODE_TABLE_END) + { + args[i] = grub_strdup ("auto"); + break; + } + modedesc = &grub_vesa_mode_table[mod - GRUB_VESA_MODE_TABLE_START]; + if (!modedesc->width) + { + args[i] = grub_strdup ("auto"); + break; + } + args[i] = grub_xasprintf ("%ux%ux%u", + modedesc->width, modedesc->height, + modedesc->depth); + break; + } case TYPE_BOOL: if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n') args[i] = grub_strdup ("1"); @@ -599,7 +630,10 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) case TYPE_BOOL: case TYPE_INT: args[i] = grub_strdup ("0"); - break; + break; + case TYPE_VBE_MODE: + args[i] = grub_strdup ("auto"); + break; } if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index cc2d20af3..9d5b7b727 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -35,6 +35,10 @@ #include #include +#ifdef GRUB_MACHINE_PCBIOS +#include +#endif + #ifdef GRUB_MACHINE_EFI #include #define HAS_VGA_TEXT 0 @@ -89,175 +93,6 @@ static struct idt_descriptor idt_desc = }; #endif -#ifdef GRUB_MACHINE_PCBIOS -struct linux_vesafb_res -{ - grub_uint16_t width; - grub_uint16_t height; -}; - -struct linux_vesafb_mode -{ - grub_uint8_t res_index; - grub_uint8_t depth; -}; - -enum vga_modes - { - VGA_320_200, - VGA_640_400, - VGA_640_480, - VGA_800_500, - VGA_800_600, - VGA_896_672, - VGA_1024_640, - VGA_1024_768, - VGA_1152_720, - VGA_1280_1024, - VGA_1440_900, - VGA_1600_1200, - }; - -static struct linux_vesafb_res linux_vesafb_res[] = - { - { 320, 200 }, - { 640, 400 }, - { 640, 480 }, - { 800, 500 }, - { 800, 600 }, - { 896, 672 }, - { 1024, 640 }, - { 1024, 768 }, - { 1152, 720 }, - { 1280, 1024 }, - { 1440, 900 }, - { 1600, 1200 }, - }; - -/* This is the reverse of the table in [linux]/Documentation/fb/vesafb.txt - plus a few more modes based on the table in - http://en.wikipedia.org/wiki/VESA_BIOS_Extensions */ -struct linux_vesafb_mode linux_vesafb_modes[] = - { - { VGA_640_400, 8 }, /* 0x300 */ - { VGA_640_480, 8 }, /* 0x301 */ - { VGA_800_600, 4 }, /* 0x302 */ - { VGA_800_600, 8 }, /* 0x303 */ - { VGA_1024_768, 4 }, /* 0x304 */ - { VGA_1024_768, 8 }, /* 0x305 */ - { VGA_1280_1024, 4 }, /* 0x306 */ - { VGA_1280_1024, 8 }, /* 0x307 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { VGA_320_200, 15 }, /* 0x30d */ - { VGA_320_200, 16 }, /* 0x30e */ - { VGA_320_200, 24 }, /* 0x30f */ - { VGA_640_480, 15 }, /* 0x310 */ - { VGA_640_480, 16 }, /* 0x311 */ - { VGA_640_480, 24 }, /* 0x312 */ - { VGA_800_600, 15 }, /* 0x313 */ - { VGA_800_600, 16 }, /* 0x314 */ - { VGA_800_600, 24 }, /* 0x315 */ - { VGA_1024_768, 15 }, /* 0x316 */ - { VGA_1024_768, 16 }, /* 0x317 */ - { VGA_1024_768, 24 }, /* 0x318 */ - { VGA_1280_1024, 15 }, /* 0x319 */ - { VGA_1280_1024, 16 }, /* 0x31a */ - { VGA_1280_1024, 24 }, /* 0x31b */ - { VGA_1600_1200, 8 }, /* 0x31c */ - { VGA_1600_1200, 15 }, /* 0x31d */ - { VGA_1600_1200, 16 }, /* 0x31e */ - { VGA_1600_1200, 24 }, /* 0x31f */ - { 0, 0 }, - { VGA_640_400, 15 }, /* 0x321 */ - { VGA_640_400, 16 }, /* 0x322 */ - { VGA_640_400, 24 }, /* 0x323 */ - { VGA_640_400, 32 }, /* 0x324 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { VGA_640_480, 32 }, /* 0x329 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { VGA_896_672, 8 }, /* 0x32f */ - { VGA_896_672, 15 }, /* 0x330 */ - { VGA_896_672, 16 }, /* 0x331 */ - { VGA_896_672, 24 }, /* 0x332 */ - { VGA_896_672, 32 }, /* 0x333 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { VGA_1600_1200, 32 }, /* 0x342 */ - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { VGA_1440_900, 8 }, /* 0x360 */ - { VGA_1440_900, 15 }, /* 0x361 */ - { VGA_1440_900, 16 }, /* 0x362 */ - { VGA_1440_900, 24 }, /* 0x363 */ - { VGA_1440_900, 32 }, /* 0x364 */ - { VGA_1152_720, 8 }, /* 0x365 */ - { VGA_1152_720, 15 }, /* 0x366 */ - { VGA_1152_720, 16 }, /* 0x367 */ - { VGA_1152_720, 24 }, /* 0x368 */ - { VGA_1152_720, 32 }, /* 0x369 */ - { VGA_1024_640, 8 }, /* 0x36a */ - { VGA_1024_640, 15 }, /* 0x36b */ - { VGA_1024_640, 16 }, /* 0x36c */ - { VGA_1024_640, 24 }, /* 0x36d */ - { VGA_1024_640, 32 }, /* 0x36e */ - { VGA_800_500, 8 }, /* 0x36f */ - { VGA_800_500, 15 }, /* 0x370 */ - { VGA_800_500, 16 }, /* 0x371 */ - { VGA_800_500, 24 }, /* 0x372 */ - { VGA_800_500, 32 }, /* 0x373 */ - }; -#endif - static inline grub_size_t page_align (grub_size_t size) { @@ -882,7 +717,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Video mode selection support. */ char *val = argv[i] + 4; unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL; - struct linux_vesafb_mode *linux_mode; + struct grub_vesa_mode_table_entry *linux_mode; grub_err_t err; char *buf; @@ -925,9 +760,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), break; default: /* Ignore invalid values. */ - if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START || - vid_mode >= GRUB_LINUX_VID_MODE_VESA_START + - ARRAY_SIZE (linux_vesafb_modes)) + if (vid_mode < GRUB_VESA_MODE_TABLE_START || + vid_mode > GRUB_VESA_MODE_TABLE_END) { grub_env_set ("gfxpayload", "text"); grub_printf ("%s is deprecated. Mode %d isn't recognized. " @@ -941,15 +775,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), is built-in because `vga=' parameter was used. */ params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; - linux_mode - = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START]; + linux_mode = &grub_vesa_mode_table[vid_mode + - GRUB_VESA_MODE_TABLE_START]; buf = grub_xasprintf ("%ux%ux%u,%ux%u", - linux_vesafb_res[linux_mode->res_index].width, - linux_vesafb_res[linux_mode->res_index].height, + linux_mode->width, linux_mode->height, linux_mode->depth, - linux_vesafb_res[linux_mode->res_index].width, - linux_vesafb_res[linux_mode->res_index].height); + linux_mode->width, linux_mode->height); if (! buf) goto fail; From 890c9fa5f2fd0177d1222c2871ca40510904e800 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 11:42:18 +0200 Subject: [PATCH 0172/1414] Implement APM --- grub-core/Makefile.core.def | 6 ++ grub-core/commands/i386/pc/lsapm.c | 113 ++++++++++++++++++++++++ grub-core/lib/legacy_parse.c | 3 +- grub-core/loader/i386/multiboot_mbi.c | 27 +++++- grub-core/loader/multiboot.c | 2 - grub-core/loader/multiboot_mbi2.c | 29 +++++- include/grub/i386/pc/apm.h | 48 ++++++++++ include/grub/i386/pc/int.h | 1 + include/grub/i386/pc/vesa_modes_table.h | 19 ++++ include/multiboot.h | 14 +++ 10 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 grub-core/commands/i386/pc/lsapm.c create mode 100644 include/grub/i386/pc/apm.h create mode 100644 include/grub/i386/pc/vesa_modes_table.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 03505ad5a..584b9754d 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1433,3 +1433,9 @@ module = { name = testload; common = commands/testload.c; }; + +module = { + name = lsapm; + common = commands/i386/pc/lsapm.c; + enable = i386_pc; +}; diff --git a/grub-core/commands/i386/pc/lsapm.c b/grub-core/commands/i386/pc/lsapm.c new file mode 100644 index 000000000..30475d2ec --- /dev/null +++ b/grub-core/commands/i386/pc/lsapm.c @@ -0,0 +1,113 @@ +/* + * 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 + +int +grub_apm_get_info (struct grub_apm_info *info) +{ + struct grub_bios_int_registers regs; + + /* detect APM */ + regs.eax = 0x5300; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x15, ®s); + + if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) + return 0; + info->version = regs.eax & 0xffff; + info->flags = regs.ecx & 0xffff; + + /* disconnect APM first */ + regs.eax = 0x5304; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x15, ®s); + + /* connect APM */ + regs.eax = 0x5303; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x15, ®s); + + if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) + return 0; + + info->cseg = regs.eax & 0xffff; + info->offset = regs.ebx; + info->cseg_16 = regs.ecx & 0xffff; + info->dseg = regs.edx & 0xffff; + info->cseg_len = regs.esi >> 16; + info->cseg_16_len = regs.esi & 0xffff; + info->dseg_len = regs.edi; + + return 1; +} + +static grub_err_t +grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) +{ + struct grub_apm_info info; + if (!grub_apm_get_info (&info)) + return grub_error (GRUB_ERR_IO, "no APM found"); + + grub_printf ("Vesion %u.%u\n" + "32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n" + "16-bit CS = 0x%x, len = 0x%x\n" + "DS = 0x%x, len = 0x%x\n", + info.version >> 8, info.version & 0xff, + info.cseg, info.cseg_len, info.offset, + info.cseg_16, info.cseg_16_len, + info.dseg, info.dseg_len); + grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED + ? "16-bit protected interface supported\n" + : "16-bit protected interface unsupported\n"); + grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED + ? "32-bit protected interface supported\n" + : "32-bit protected interface unsupported\n"); + grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN + ? "CPU Idle slows down processor\n" + : "CPU Idle doesn't slow down processor\n"); + grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED + ? "APM disabled\n" : "APM enabled\n"); + grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED + ? "APM disengaged\n" : "APM engaged\n"); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(lsapm) +{ + cmd = grub_register_command ("lsapm", grub_cmd_lsapm, 0, + N_("Show APM information.")); +} + +GRUB_MOD_FINI(lsapm) +{ + grub_unregister_command (cmd); +} + + diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 959d8367d..024d425e8 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -99,7 +99,8 @@ struct legacy_command legacy_commands[] = "Set the default entry to entry number NUM (if not specified, it is" " 0, the first entry) or the entry number saved by savedefault."}, /* FIXME: dhcp unsupported. */ - /* FIXME: displayapm unsupported. */ + {"displayapm", "lsapm\n", NULL, 0, 0, {}, 0, 0, + "Display APM BIOS information."}, {"displaymem", "lsmmap\n", NULL, 0, 0, {}, 0, 0, "Display what GRUB thinks the system address space map of the" " machine is, including all regions of physical RAM installed."}, diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index bf17863cf..2cce39746 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -20,6 +20,7 @@ #include #ifdef GRUB_MACHINE_PCBIOS #include +#include #endif #include #include @@ -194,7 +195,8 @@ grub_multiboot_get_mbi_size (void) + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) + elf_sec_entsize * elf_sec_num - + 256 * sizeof (struct multiboot_color); + + 256 * sizeof (struct multiboot_color) + + ALIGN_UP (sizeof (struct multiboot_apm_info), 4); } /* Fill previously allocated Multiboot mmap. */ @@ -356,6 +358,29 @@ grub_multiboot_make_mbi (grub_uint32_t *target) ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4); ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4); +#ifdef GRUB_MACHINE_PCBIOS + { + struct grub_apm_info info; + if (grub_apm_get_info (&info)) + { + struct multiboot_apm_info *mbinfo = (void *) ptrorig; + + mbinfo->cseg = info.cseg; + mbinfo->offset = info.offset; + mbinfo->cseg_16 = info.cseg_16; + mbinfo->dseg = info.dseg; + mbinfo->flags = info.flags; + mbinfo->cseg_len = info.cseg_len; + mbinfo->dseg_len = info.dseg_len; + mbinfo->cseg_16_len = info.cseg_16_len; + mbinfo->version = info.version; + + ptrorig += ALIGN_UP (sizeof (struct multiboot_apm_info), 4); + ptrdest += ALIGN_UP (sizeof (struct multiboot_apm_info), 4); + } + } +#endif + if (modcnt) { mbi->flags |= MULTIBOOT_INFO_MODS; diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 8780ec061..d5cb42604 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -21,10 +21,8 @@ * FIXME: The following features from the Multiboot specification still * need to be implemented: * - VBE support - * - symbol table * - drives table * - ROM configuration table - * - APM table */ #include diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index f453dcc6a..2e6801252 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -20,6 +20,7 @@ #include #ifdef GRUB_MACHINE_PCBIOS #include +#include #endif #include #include @@ -279,7 +280,8 @@ grub_multiboot_get_mbi_size (void) + elf_sec_entsize * elf_sec_num + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)) - + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1; + + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1 + + sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1; } /* Fill previously allocated Multiboot mmap. */ @@ -515,6 +517,31 @@ grub_multiboot_make_mbi (grub_uint32_t *target) ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } +#ifdef GRUB_MACHINE_PCBIOS + { + struct grub_apm_info info; + if (grub_apm_get_info (&info)) + { + struct multiboot_tag_apm *tag = (struct multiboot_tag_apm *) ptrorig; + + tag->type = MULTIBOOT_TAG_TYPE_APM; + tag->size = sizeof (struct multiboot_tag_apm); + + tag->cseg = info.cseg; + tag->offset = info.offset; + tag->cseg_16 = info.cseg_16; + tag->dseg = info.dseg; + tag->flags = info.flags; + tag->cseg_len = info.cseg_len; + tag->dseg_len = info.dseg_len; + tag->cseg_16_len = info.cseg_16_len; + tag->version = info.version; + + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + } + } +#endif + { unsigned i; struct module *cur; diff --git a/include/grub/i386/pc/apm.h b/include/grub/i386/pc/apm.h new file mode 100644 index 000000000..6d9e8c61d --- /dev/null +++ b/include/grub/i386/pc/apm.h @@ -0,0 +1,48 @@ +/* + * 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_APM_MACHINE_HEADER +#define GRUB_APM_MACHINE_HEADER 1 + +#include + +struct grub_apm_info +{ + grub_uint16_t cseg; + grub_uint32_t offset; + grub_uint16_t cseg_16; + grub_uint16_t dseg; + grub_uint16_t flags; + grub_uint16_t cseg_len; + grub_uint16_t cseg_16_len; + grub_uint16_t dseg_len; + grub_uint16_t version; +}; + +enum + { + GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED = 1, + GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED = 2, + GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN = 4, + GRUB_APM_FLAGS_DISABLED = 8, + GRUB_APM_FLAGS_DISENGAGED = 16, + }; + +int grub_apm_get_info (struct grub_apm_info *info); + +#endif diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/pc/int.h index e1c463925..de23775d0 100644 --- a/include/grub/i386/pc/int.h +++ b/include/grub/i386/pc/int.h @@ -20,6 +20,7 @@ #define GRUB_INTERRUPT_MACHINE_HEADER 1 #include +#include struct grub_bios_int_registers { diff --git a/include/grub/i386/pc/vesa_modes_table.h b/include/grub/i386/pc/vesa_modes_table.h new file mode 100644 index 000000000..376ca376b --- /dev/null +++ b/include/grub/i386/pc/vesa_modes_table.h @@ -0,0 +1,19 @@ +#ifndef GRUB_VESA_MODE_TABLE_HEADER +#define GRUB_VESA_MODE_TABLE_HEADER 1 + +#include + +#define GRUB_VESA_MODE_TABLE_START 0x300 +#define GRUB_VESA_MODE_TABLE_END 0x373 + +struct grub_vesa_mode_table_entry { + grub_uint16_t width; + grub_uint16_t height; + grub_uint8_t depth; +}; + +extern struct grub_vesa_mode_table_entry +grub_vesa_mode_table[GRUB_VESA_MODE_TABLE_END + - GRUB_VESA_MODE_TABLE_START + 1]; + +#endif diff --git a/include/multiboot.h b/include/multiboot.h index fda863e85..ed71e6b96 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -254,6 +254,20 @@ struct multiboot_mod_list }; typedef struct multiboot_mod_list multiboot_module_t; +/* APM BIOS info. */ +struct multiboot_apm_info +{ + grub_uint16_t version; + grub_uint16_t cseg; + grub_uint32_t offset; + grub_uint16_t cseg_16; + grub_uint16_t dseg; + grub_uint16_t flags; + grub_uint16_t cseg_len; + grub_uint16_t cseg_16_len; + grub_uint16_t dseg_len; +}; + #endif /* ! ASM_FILE */ #endif /* ! MULTIBOOT_HEADER */ From e2830452f05001e1c24e718deec6c71b7dc39e70 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 13:51:02 +0200 Subject: [PATCH 0173/1414] Support legacy_check_password --- grub-core/commands/legacycfg.c | 91 +++++++++++++++++++++++++++------- grub-core/lib/legacy_parse.c | 25 +++++++--- 2 files changed, 93 insertions(+), 23 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index bea608b9e..463297810 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -603,19 +603,14 @@ ib64t (char c) return -1; } -static grub_err_t -grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) +static struct legacy_md5_password * +parse_legacy_md5 (int argc, char **args) { const char *salt, *saltend; - const char *p; struct legacy_md5_password *pw = NULL; int i; + const char *p; - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected"); - if (args[0][0] != '-' || args[0][1] != '-') - return grub_normal_set_password ("legacy", args[0]); if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0) goto fail; if (argc == 1) @@ -667,21 +662,76 @@ grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), if (!pw->salt) goto fail; - return grub_auth_register_authentication ("legacy", check_password_md5, pw); + return pw; fail: grub_free (pw); - /* This is to imitate minor difference between grub-legacy in GRUB2. - If 2 password commands are executed in a row and second one fails - on GRUB2 the password of first one is used, whereas in grub-legacy - authenthication is denied. In case of no password command was executed - early both versions deny any access. */ - return grub_auth_register_authentication ("legacy", check_password_deny, - NULL); + return NULL; +} + +static grub_err_t +grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct legacy_md5_password *pw = NULL; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected"); + if (args[0][0] != '-' || args[0][1] != '-') + return grub_normal_set_password ("legacy", args[0]); + + pw = parse_legacy_md5 (argc, args); + + if (pw) + return grub_auth_register_authentication ("legacy", check_password_md5, pw); + else + /* This is to imitate minor difference between grub-legacy in GRUB2. + If 2 password commands are executed in a row and second one fails + on GRUB2 the password of first one is used, whereas in grub-legacy + authenthication is denied. In case of no password command was executed + early both versions deny any access. */ + return grub_auth_register_authentication ("legacy", check_password_deny, + NULL); +} + +static grub_err_t +grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct legacy_md5_password *pw = NULL; + char entered[GRUB_AUTH_MAX_PASSLEN]; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected"); + grub_printf ("Enter password:"); + if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) + return GRUB_ACCESS_DENIED; + + if (args[0][0] != '-' || args[0][1] != '-') + { + char correct[GRUB_AUTH_MAX_PASSLEN]; + + grub_memset (correct, 0, sizeof (correct)); + grub_strncpy (correct, args[0], sizeof (correct)); + + if (grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) != 0) + return GRUB_ACCESS_DENIED; + return GRUB_ERR_NONE; + } + + pw = parse_legacy_md5 (argc, args); + + if (!pw) + return GRUB_ACCESS_DENIED; + + if (!check_password_md5_real (entered, pw)) + return GRUB_ACCESS_DENIED; + + return GRUB_ERR_NONE; } static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; -static grub_command_t cmd_password, cmd_initrdnounzip; +static grub_command_t cmd_password, cmd_check_password, cmd_initrdnounzip; GRUB_MOD_INIT(legacycfg) { @@ -711,6 +761,12 @@ GRUB_MOD_INIT(legacycfg) grub_cmd_legacy_password, N_("[--md5] PASSWD [FILE]"), N_("Simulate grub-legacy password command")); + + cmd_check_password = grub_register_command ("legacy_check_password", + grub_cmd_legacy_check_password, + N_("[--md5] PASSWD [FILE]"), + N_("Simulate grub-legacy password command in menuentry mode")); + } GRUB_MOD_FINI(legacycfg) @@ -721,4 +777,5 @@ GRUB_MOD_FINI(legacycfg) grub_unregister_command (cmd_initrd); grub_unregister_command (cmd_initrdnounzip); grub_unregister_command (cmd_password); + grub_unregister_command (cmd_check_password); } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 024d425e8..e5014cdc7 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -49,6 +49,8 @@ struct legacy_command FLAG_FALLBACK_AVAILABLE = 4, FLAG_FALLBACK = 8, FLAG_COLOR_INVERT = 16, + FLAG_NO_MENUENTRY = 32, + FLAG_MENUENTRY_ONLY = 64, } flags; const char *shortdesc; const char *longdesc; @@ -189,12 +191,12 @@ struct legacy_command legacy_commands[] = {"parttype", "parttool '%s' type=%s\n", NULL, 0, 2, {TYPE_PARTITION, TYPE_INT}, 0, "PART TYPE", "Change the type of the partition PART to TYPE."}, - /* FIXME: support usage in menuentry. */ {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" - "legacy_password %s '%s'", + "legacy_password %s '%s'\n", "menuentry \"Superuser menu\" --users \"legacy\" { configfile '%s'; }\n", 2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE}, - FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE, "[--md5] PASSWD [FILE]", + FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE | FLAG_NO_MENUENTRY, + "[--md5] PASSWD [FILE]", "If used in the first section of a menu file, disable all" " interactive editing control (menu entry editor and" " command line). If the password PASSWD is entered, it loads the" @@ -205,8 +207,15 @@ struct legacy_command legacy_commands[] = " The option --md5 tells GRUB that PASSWD is encrypted with" " md5crypt."}, {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" - "legacy_password %s '%s'", NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM}, - FLAG_IGNORE_REST | FLAG_FALLBACK, NULL, NULL}, + "legacy_password %s '%s'\n", NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM}, + FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_NO_MENUENTRY, NULL, NULL}, + {"password", "if legacy_check_password %s '%s'; then configfile '%s'; " + "else return; fi\n", NULL, 2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE}, + FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE | FLAG_MENUENTRY_ONLY, + NULL, NULL}, + {"password", "if ! legacy_check_password %s '%s'; then return fi;\n", + NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM}, + FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_MENUENTRY_ONLY, NULL, NULL}, /* NOTE: GRUB2 has a design principle of not eternally waiting for user input. 60 seconds should be enough. */ @@ -442,7 +451,11 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 - && legacy_commands[cmdnum].name[ptr - cmdname] == 0) + && legacy_commands[cmdnum].name[ptr - cmdname] == 0 + && (!(*entryname != NULL && (legacy_commands[cmdnum].flags + & FLAG_NO_MENUENTRY))) + && (!(*entryname == NULL && (legacy_commands[cmdnum].flags + & FLAG_MENUENTRY_ONLY)))) break; if (cmdnum == ARRAY_SIZE (legacy_commands)) return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); From c99dead65448b083befbb9977f19d22c8ea14902 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 14:11:08 +0200 Subject: [PATCH 0174/1414] Support geometry --- grub-core/lib/legacy_parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index e5014cdc7..a0be27d60 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -118,7 +118,9 @@ struct legacy_command legacy_commands[] = "Search for the filename FILENAME in all of partitions and print the list of" " the devices which contain the file."}, /* FIXME: fstest unsupported. */ - /* FIXME: geometry unsupported. */ + /* NOTE: The obsolete C/H/S geometry isn't shown anymore. */ + {"geometry", "insmod regexp; ls -l (%s*)\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "DRIVE", + "Print the information for a drive DRIVE. "}, {"halt", "halt %s\n", NULL, 0, 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", "Halt your system. If APM is available on it, turn off the power using" " the APM BIOS, unless you specify the option `--no-apm'."}, From 3f8fcb6a24414ab86f1ea37501ae6d608a2487b6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 14:37:28 +0200 Subject: [PATCH 0175/1414] Support vbeprobe MODE --- grub-core/commands/videoinfo.c | 46 +++++++++++++++++++++++++++++----- grub-core/lib/legacy_parse.c | 8 +++--- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 15f677e14..10f77915b 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -25,9 +25,17 @@ #include #include +static unsigned height, width, depth; + static int hook (const struct grub_video_mode_info *info) { + if (height && width && (info->width != width || info->height != height)) + return 0; + + if (depth && info->bpp != depth) + return 0; + if (info->mode_number == GRUB_VIDEO_MODE_NUMBER_INVALID) grub_printf (" "); else @@ -71,12 +79,34 @@ hook (const struct grub_video_mode_info *info) static grub_err_t grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) + int argc, char **args) { grub_video_adapter_t adapter; grub_video_driver_id_t id; + height = width = depth = 0; + if (argc) + { + char *ptr; + ptr = args[0]; + width = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (*ptr != 'x') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid mode specification"); + ptr++; + height = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (*ptr == 'x') + { + ptr++; + depth = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + } + } + #ifdef GRUB_MACHINE_PCBIOS if (grub_strcmp (cmd->name, "vbeinfo") == 0) grub_dl_load ("vbe"); @@ -132,11 +162,15 @@ static grub_command_t cmd_vbe; GRUB_MOD_INIT(videoinfo) { - cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, 0, - N_("List available video modes.")); + cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, "[WxH[xD]]", + N_("List available video modes. If " + "resolution is given show only modes" + " matching it.")); #ifdef GRUB_MACHINE_PCBIOS - cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, 0, - N_("List available video modes.")); + cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, "[WxH[xD]]", + N_("List available video modes. If " + "resolution is given show only modes" + " matching it.")); #endif } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index a0be27d60..6ad15dc49 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -292,10 +292,12 @@ struct legacy_command legacy_commands[] = /* FIXME: uppermem unsupported. */ {"uuid", "search --set=root --fs-uuid '%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "UUID", "Find root by UUID"}, - /* FIXME: support MODE. */ - {"vbeprobe", "insmod vbe; videoinfo\n", NULL, 0, 0, {}, 0, "[MODE]", + {"vbeprobe", "insmod vbe; videoinfo '%s'\n", NULL, 0, 1, {TYPE_VBE_MODE}, + FLAG_FALLBACK_AVAILABLE, "[MODE]", "Probe VBE information. If the mode number MODE is specified, show only" - " the information about only the mode."} + " the information about only the mode."}, + {"vbeprobe", "insmod vbe; videoinfo\n", NULL, 0, 0, {}, + FLAG_FALLBACK, NULL, NULL} }; char * From 14437e800868c847980daad364a31a63029d9e8c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 14:45:08 +0200 Subject: [PATCH 0176/1414] Allow install_device to be missing on non-pc and non-sparc --- util/grub-install.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index ecdbfe179..344475b5c 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -83,7 +83,8 @@ fi # Usage: usage # Print the usage. usage () { -if test "x$install_device" = x && test "${target_cpu}-${platform}" != "mips-yeeloong" && test "${target_cpu}-${platform}" != "i386-ieee1275" && test "${target_cpu}-${platform}" != "powerpc-ieee1275"; then +if [ "${target_cpu}-${platform}" = "i386-pc" ] \ + || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ]; then cat <&2 usage exit 1 From 9a9cee4e4347c0480fb9e19ce2732a2132c4e3f9 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 15 Sep 2010 13:00:51 -0300 Subject: [PATCH 0177/1414] Use the correct address types in net.c. implement ntoa ipv4 function. --- commands/net.c | 40 +++++++++++++++++++++++++++---------- include/grub/net.h | 29 +++++++++++++++++++++++---- include/grub/net/protocol.h | 5 +++-- include/grub/net/type_net.h | 8 ++++---- net/ip.c | 38 +++++++++++++++++++++++++++++++++-- 5 files changed, 97 insertions(+), 23 deletions(-) diff --git a/commands/net.c b/commands/net.c index b8ceb36f4..2558a309b 100644 --- a/commands/net.c +++ b/commands/net.c @@ -22,11 +22,8 @@ #include #include -struct grub_net_route *grub_net_routes = NULL; -struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL; -struct grub_net_card *grub_net_cards = NULL; -struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL; +/*Find which protocol understands the given address*/ grub_err_t grub_net_resolve_address (struct grub_net_network_layer_protocol **prot, char *name, @@ -102,7 +99,7 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[1])) + if ( !grub_strcmp (inter->name, args[1])) break; if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); @@ -124,21 +121,36 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), grub_err_t err; grub_net_network_layer_address_t addr; struct grub_net_network_layer_interface *inter; + grub_printf("Enter add addr function.\n"); + + grub_printf("card list address in net.c = %x\n", (int) grub_net_cards); if (argc != 4) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected")); FOR_NET_CARDS (card) - if (grub_strcmp (card->name, args[1])) + { + grub_printf("card address = %x\n", (int) card); + grub_printf("card->name = %s\n",card->name); + grub_printf("args[1] = %s\n",args[1]); + if ( !grub_strcmp (card->name, args[1])) break; + } + + grub_printf("Out of the loop.\n"); + grub_printf("card address = %x\n", (int) card); + if (card == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); + grub_printf("protocols loop.\n"); FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot) - if (grub_strcmp (prot->name, args[2])) + if ( !grub_strcmp (prot->name, args[2])) break; - if (card == NULL) + grub_printf("end protocols loop.\n"); + + if (prot == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); err = grub_net_resolve_address_in_protocol (prot, args[3], &addr); @@ -163,6 +175,12 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), } grub_net_network_layer_interface_register (inter); + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + { + grub_printf("inter->name = %s\n",inter->name); + grub_printf("inter->address = %x\n",(int) (inter->address.ipv4)); + + } return GRUB_ERR_NONE; } @@ -178,7 +196,7 @@ grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), for (prev = &grub_net_routes, route = *prev; route; prev = &((*prev)->next), route = *prev) - if (grub_strcmp (route->name, args[0]) == 0) + if ( !grub_strcmp (route->name, args[0]) == 0) { *prev = route->next; grub_free (route->name); @@ -232,7 +250,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), N_("Unrecognised address %s"), args[1]); } - if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) + if ( !grub_strcmp (args[2], "gw") == 0 && argc >= 4) { grub_err_t err; route->is_gateway = 1; @@ -251,7 +269,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), route->is_gateway = 0; FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[2])) + if ( !grub_strcmp (inter->name, args[2])) break; if (!inter) diff --git a/include/grub/net.h b/include/grub/net.h index abb8a3167..18779dabe 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -31,6 +31,8 @@ struct grub_net_card; struct grub_net_card_driver { + struct grub_net_card_driver *next; + char *name; grub_err_t (*init) (struct grub_net_card *dev); grub_err_t (*fini) (struct grub_net_card *dev); grub_err_t (*send) (struct grub_net_card *dev,struct grub_net_buff *nb); @@ -66,7 +68,7 @@ struct grub_net_network_layer_interface /* Underlying protocol. */ struct grub_net_network_layer_protocol *protocol; struct grub_net_card *card; - union grub_net_network_layer_address address; + grub_net_network_layer_address_t address; void *data; }; @@ -121,7 +123,7 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, return session->protocol->recv (session, buf, size); } -struct grub_net_network_layer_interface *grub_net_network_layer_interfaces; +extern struct grub_net_network_layer_interface *EXPORT_VAR(grub_net_network_layer_interfaces); static inline void grub_net_network_layer_interface_register (struct grub_net_network_layer_interface *inter) @@ -139,7 +141,7 @@ grub_net_network_layer_interface_unregister (struct grub_net_network_layer_inter #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_layer_interfaces; var; var = var->next) -extern struct grub_net_route *grub_net_routes; +extern struct grub_net_route *EXPORT_VAR(grub_net_routes); static inline void grub_net_route_register (struct grub_net_route *route) @@ -157,7 +159,7 @@ grub_net_route_unregister (struct grub_net_route *route) #define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) -extern struct grub_net_card *grub_net_cards; +extern struct grub_net_card *EXPORT_VAR(grub_net_cards); static inline void grub_net_card_register (struct grub_net_card *card) @@ -174,7 +176,26 @@ grub_net_card_unregister (struct grub_net_card *card) } #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) +struct grub_net_card_driver *grub_net_card_drivers; +static inline void +grub_net_card_driver_register (struct grub_net_card_driver *driver) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_card_drivers), + GRUB_AS_LIST (driver)); +} + +static inline void +grub_net_card_driver_unregister (struct grub_net_card_driver *driver) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_card_drivers), + GRUB_AS_LIST (driver)); +} + +void ofdriver_ini(void); +void ofdriver_fini(void); + +#define FOR_NET_CARD_DRIVERS(var) for (var = grub_net_card_drivers; var; var = var->next) #define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_layer_protocols; (var); (var) = (var)->next) diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h index ffc3dd719..ce37404bc 100644 --- a/include/grub/net/protocol.h +++ b/include/grub/net/protocol.h @@ -1,6 +1,7 @@ #ifndef GRUB_PROTOCOL_HEADER #define GRUB_PROTOCOL_HEADER #include +#include #include #include #include @@ -60,7 +61,7 @@ struct grub_net_network_layer_protocol grub_uint16_t type; /* IANA Ethertype */ //grub_network_layer_protocol_id_t id; grub_err_t (*ntoa) (char *name, grub_net_network_layer_address_t *addr); - char * (*aton) (union grub_net_network_layer_address addr); + char * (*aton) (grub_net_network_layer_address_t addr); grub_err_t (*net_ntoa) (char *name, grub_net_network_layer_netaddress_t *addr); char * (*net_aton) (grub_net_network_layer_netaddress_t addr); @@ -87,7 +88,7 @@ struct grub_net_link_layer_protocol grub_uint16_t ethertype); }; -extern struct grub_net_network_layer_protocol *grub_net_network_layer_protocols; +extern struct grub_net_network_layer_protocol *EXPORT_VAR(grub_net_network_layer_protocols); typedef struct grub_net_protocol *grub_net_protocol_t; void grub_net_application_layer_protocol_register (struct grub_net_application_layer_protocol *prot); diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h index a1717d6a7..f159b1de0 100644 --- a/include/grub/net/type_net.h +++ b/include/grub/net/type_net.h @@ -18,16 +18,16 @@ typedef enum }grub_net_protocol_id_t; -typedef union grub_net_network_layer_address +typedef union grub_net_network_layer_netaddress { grub_uint32_t ipv4; -} grub_net_network_layer_netaddress_t; +} grub_net_network_layer_address_t; -typedef union grub_net_network_layer_netaddress +typedef union grub_net_network_layer_address { struct { grub_uint32_t base; int masksize; } ipv4; -} grub_net_network_layer_address_t; +} grub_net_network_layer_netaddress_t; #endif diff --git a/net/ip.c b/net/ip.c index 142f33e70..8237603f2 100644 --- a/net/ip.c +++ b/net/ip.c @@ -68,8 +68,10 @@ send_ip_packet (struct grub_net_network_layer_interface *inf, grub_memcpy(nl_target_addr.addr, &(iph->dest), nl_target_addr.len); rc = arp_resolve(inf, trans_net_inf->inner_layer, &nl_target_addr, &ll_target_addr); grub_free(nl_target_addr.addr); - if (rc != GRUB_ERR_NONE) + if (rc != GRUB_ERR_NONE){ + grub_printf("Error in the ARP resolve.\n"); return rc; + } rc = trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb,ll_target_addr, IP_ETHERTYPE); grub_free(ll_target_addr.addr); @@ -113,13 +115,45 @@ recv_ip_packet (struct grub_net_network_layer_interface *inf, return 0; } + +static grub_err_t +ipv4_ntoa (char *val, grub_net_network_layer_address_t *addr ) +{ + grub_uint8_t *p = (grub_uint8_t *) addr; + unsigned long t; + int i; + + for (i = 0; i < 4; i++) + { + t = grub_strtoul (val, (char **) &val, 0); + if (grub_errno) + return grub_errno; + + if (t & ~0xff) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + + p[i] = (grub_uint8_t) t; + if (i != 3 && *val != '.') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + + val++; + } + + val = val - 1; + if (*val != '\0') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + + return GRUB_ERR_NONE; +} + static struct grub_net_network_layer_protocol grub_ipv4_protocol = { .name = "ipv4", .id = GRUB_NET_IPV4_ID, .type = IP_ETHERTYPE, .send = send_ip_packet, - .recv = recv_ip_packet + .recv = recv_ip_packet, + .ntoa = ipv4_ntoa }; void ipv4_ini(void) From 87fdc7e8d28f20f355240219ea7e7a580e0f7303 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 15 Sep 2010 13:23:23 -0300 Subject: [PATCH 0178/1414] Create Open firmware pseudo driver. Change ofnet.c to disknet.c and remove almost all ieee1275 specific code. Create grub_net_malloc to handle iee1275 memory issues in a temporary solution. --- conf/powerpc-ieee1275.rmk | 6 +- fs/{ieee1275/ofnet.c => netdisk.c} | 142 ++++++++------------------ include/grub/ieee1275/ieee1275.h | 10 +- include/grub/ieee1275/ofnet.h | 29 +----- include/grub/net/disknet.h | 5 + include/grub/net/ethernet.h | 15 ++- include/grub/net/ieee1275/interface.h | 9 -- include/grub/net/mem.h | 9 ++ kern/ieee1275/openfw.c | 64 ++++++++++++ net/drivers/ieee1275/ofdriver.c | 74 ++++++++++++++ net/ethernet.c | 9 +- net/i386/mem.c | 10 ++ net/ieee1275/interface.c | 46 --------- net/ieee1275/mem.c | 32 ++++++ net/protocol.c | 2 + 15 files changed, 272 insertions(+), 190 deletions(-) rename fs/{ieee1275/ofnet.c => netdisk.c} (77%) create mode 100644 include/grub/net/disknet.h create mode 100644 include/grub/net/mem.h create mode 100644 net/drivers/ieee1275/ofdriver.c create mode 100644 net/i386/mem.c delete mode 100644 net/ieee1275/interface.c create mode 100644 net/ieee1275/mem.c diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index f0faef489..a70a1e962 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -5,7 +5,7 @@ kernel_img_HEADERS += ieee1275/ieee1275.h \ command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\ - net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h + net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h net/mem.h # Programs pkglib_PROGRAMS = kernel.img @@ -23,8 +23,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c \ - net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c \ - fs/ieee1275/ofnet.c + net/drivers/ieee1275/ofdriver.c net/interface.c net/protocol.c net/netbuff.c \ + fs/netdisk.c net/ieee1275/mem.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic diff --git a/fs/ieee1275/ofnet.c b/fs/netdisk.c similarity index 77% rename from fs/ieee1275/ofnet.c rename to fs/netdisk.c index cf7eeb5b2..2f6e97d52 100644 --- a/fs/ieee1275/ofnet.c +++ b/fs/netdisk.c @@ -23,26 +23,25 @@ #include #include #include -#include -#include -#include #include #include #include #include #include -#include #include #include #include +#include +#include + +struct grub_net_card *grub_net_cards = NULL; +struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL; +struct grub_net_route *grub_net_routes = NULL; #define BUFFERADDR 0X00000000 #define BUFFERSIZE 0x02000000 #define U64MAXSIZE 18446744073709551615ULL - -//static grub_ieee1275_ihandle_t handle = 0; - static const char * find_sep (const char *name) { @@ -295,29 +294,45 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) return 1; } - // grub_printf("name = %s\n",name); +/*TESt*/ + // grub_printf("name = %s\n",name); + struct grub_net_card *card; + struct grub_ofnetcard_data *ofdata; + FOR_NET_CARDS(card) + { + grub_printf("card address = %x\n", (int) card); + grub_printf ("card name = %s\n", card->name); + ofdata = card->data; + grub_printf("card path = %s\n", (char *) ofdata->path); + grub_printf("card handle = %d\n", ofdata->handle); + } + grub_printf("card list address in disknet.c = %x\n",(int) grub_net_cards); + card = grub_net_cards; + grub_printf("card address = %x\n", (int) card); +/*TESt*/ + struct grub_net_protocol_stack *stack; struct grub_net_buff *pack; struct grub_net_application_transport_interface *app_interface; int file_size; char *datap; int amount = 0; - grub_addr_t found_addr; grub_netdisk_data_t netdisk_data = (grub_netdisk_data_t) file->device->disk->data; + // TODO: replace getting IP and MAC from bootp by routing functions struct grub_net_network_layer_interface net_interface; - struct grub_net_card net_card; struct grub_net_addr ila, lla; - ila.addr = (grub_uint8_t *) &(bootp_pckt->yiaddr); + ila.addr = (grub_uint8_t *) & (bootp_pckt->yiaddr); ila.len = 4; - lla.addr = (grub_uint8_t *) &(bootp_pckt->chaddr); + lla.addr = (grub_uint8_t *) & (bootp_pckt->chaddr); lla.len = 6; - net_card.ila = &ila; - net_card.lla = &lla; - net_interface.card = &net_card; // END TODO + card->ila = &ila; + card->lla = &lla; + net_interface.card = card; + if(! netdisk_data) return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments missing"); @@ -328,37 +343,35 @@ grub_ofnetfs_open (struct grub_file *file , const char *name ) app_interface = (struct grub_net_application_transport_interface *) stack->interface; app_interface->inner_layer->data = (void *) &(netdisk_data->server_ip); + pack = grub_netbuff_alloc (2048); grub_netbuff_reserve (pack,2048); + file_size = app_interface->app_prot->get_file_size(&net_interface,stack,pack,(char *) name); - for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) - { - if (grub_claimmap (found_addr , file_size) != -1) - break; - } - file->data = (void *) found_addr; + file->data = grub_net_malloc (file_size); grub_netbuff_clear(pack); grub_netbuff_reserve (pack,2048); + app_interface->app_prot->open (&net_interface,stack,pack,(char *) name); if (grub_errno != GRUB_ERR_NONE) goto error; do { - grub_netbuff_clear(pack); - grub_netbuff_reserve (pack,2048); app_interface->app_prot->recv (&net_interface,stack,pack); + if (grub_errno != GRUB_ERR_NONE) goto error; + if ((pack->tail - pack->data)) { - // file->data = grub_realloc(file->data,amount + pack->tail - pack->data); datap = (char *)file->data + amount; amount += (pack->tail - pack->data); - grub_memcpy(datap , pack->data, pack->tail - pack->data); + grub_memcpy (datap , pack->data, pack->tail - pack->data); } + grub_netbuff_clear(pack); grub_netbuff_reserve (pack,2048); app_interface->app_prot->send_ack (&net_interface,stack,pack); @@ -394,54 +407,6 @@ static struct grub_fs grub_ofnetfs_fs = .next = 0 }; -static char * -grub_ieee1275_get_devargs (const char *path) -{ - int len; - char *colon = grub_strchr (path, ':'); - len = colon - path; - if (! colon) - return 0; - - return grub_strndup (path,len); -} - -static int -grub_ofnet_detect (void) -{ - - char *devalias; - char bootpath[64]; /* XXX check length */ - grub_ieee1275_phandle_t root; - grub_uint32_t net_type; - - grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); - if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, - sizeof (bootpath), 0)) - { - /* Should never happen. */ - grub_printf ("/chosen/bootpath property missing!\n"); - return 0; - } - devalias = grub_ieee1275_get_aliasdevname (bootpath); - - if (grub_strncmp(devalias ,"net",3)) - return 0; - - grub_net = grub_malloc (sizeof *grub_net ); - grub_net->name = "net"; - grub_net->dev = grub_ieee1275_get_devargs (bootpath); - grub_ieee1275_finddevice ("/", &root); - grub_ieee1275_get_integer_property (root, "ibm,fw-net-compatibility", - &net_type, sizeof net_type, 0); - grub_printf("root = %d\n",root); - grub_printf("net_type= %d\n",net_type); - grub_net->type = net_type; - - return 1; -} - - #define IPMASK 0x000000FF #define IPSIZE 16 #define IPTEMPLATE "%d.%d.%d.%d" @@ -456,34 +421,17 @@ grub_ip2str (grub_uint32_t ip) return str_ip; } + void -grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet) +grub_disknet_init(void) { - netinfo->sip = grub_ip2str(packet->siaddr); - netinfo->cip = grub_ip2str(packet->yiaddr); - netinfo->gat = grub_ip2str(packet->giaddr); - grub_printf("packet->siaddr = %x\n",packet->siaddr); - grub_printf("netinfo-> = %s\n",netinfo->sip); - grub_printf("packet->yiaddr = %x\n",packet->yiaddr); - grub_printf("netinfo-> = %s\n",netinfo->cip); - grub_printf("packet->giaddr = %x\n",packet->giaddr); - grub_printf("netinfo-> = %s\n",netinfo->gat); + + grub_disk_dev_register (&grub_ofnet_dev); + grub_fs_register (&grub_ofnetfs_fs); } + void -grub_ofnet_init(void) -{ - tftp_ini (); - bootp_pckt = grub_getbootp (); - if(grub_ofnet_detect ()) - { - grub_get_netinfo (grub_net, bootp_pckt ); - grub_disk_dev_register (&grub_ofnet_dev); - grub_fs_register (&grub_ofnetfs_fs); - card_open (); - } -} -void -grub_ofnet_fini(void) +grub_disknet_fini(void) { grub_fs_unregister (&grub_ofnetfs_fs); grub_disk_dev_unregister (&grub_ofnet_dev); diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index f4c8b4edf..8fb558fa7 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -24,7 +24,6 @@ #include #include -/* Maps a device alias to a pathname. */ struct grub_ieee1275_devalias { char *name; @@ -65,6 +64,13 @@ struct grub_ieee1275_common_hdr typedef grub_uint32_t grub_ieee1275_ihandle_t; typedef grub_uint32_t grub_ieee1275_phandle_t; +struct grub_ofnetcard_data +{ + char *path; + grub_ieee1275_ihandle_t handle; +}; + +/* Maps a device alias to a pathname. */ extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu); extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *); @@ -186,4 +192,6 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) (struct grub_ieee1275_devalias * alias)); char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); +void EXPORT_FUNC(grub_ofnet_findcards) (void); +void EXPORT_FUNC(grub_ofnet_probecards) (void); #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h index a26c22235..ba4c62630 100644 --- a/include/grub/ieee1275/ofnet.h +++ b/include/grub/ieee1275/ofnet.h @@ -23,32 +23,9 @@ #include #include -extern void grub_ofnet_init(void); -extern void grub_ofnet_fini(void); +void grub_ofnet_init(void); +void grub_ofnet_fini(void); -/* -struct grub_net; - -struct grub_net_dev -{ - / The device name. / - const char *name; - - / FIXME: Just a template. / - int (*probe) (struct grub_net *net, const void *addr); - void (*reset) (struct grub_net *net); - int (*poll) (struct grub_net *net); - void (*transmit) (struct grub_net *net, const void *destip, - unsigned srcsock, unsigned destsock, const void *packet); - void (*disable) (struct grub_net *net); - - / The next net device. / - struct grub_net_dev *next; -}; -typedef struct grub_net_dev *grub_net_dev_t; - -struct grub_fs; -*/ struct grub_ofnet { /* The net name. */ @@ -85,7 +62,7 @@ struct grub_bootp { char file [128]; /* Boot filename */ // grub_uint32_t filesize ; /*File size (testing)*/ unsigned char vend [64]; -}; +}; typedef struct grub_bootp* grub_bootp_t; diff --git a/include/grub/net/disknet.h b/include/grub/net/disknet.h new file mode 100644 index 000000000..59aa2a320 --- /dev/null +++ b/include/grub/net/disknet.h @@ -0,0 +1,5 @@ +#ifndef GRUB_DISKNET_HEADER +#define GRUB_DISKNET_HEADER 1 + void grub_disknet_init(void); + void grub_disknet_fini(void); +#endif /* ! GRUB_NET_HEADER */ diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 9043a5f02..f4a6c22cf 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -10,9 +10,18 @@ struct etherhdr grub_uint16_t type; } __attribute__ ((packed)); -#define PCP (x) x & 0xe000 -#define CFI (x) x & 0x1000 -#define VID (x) x & 0x0fff +#define PCP(x) x & 0xe000 +#define CFI(x) x & 0x1000 +#define VID(x) x & 0x0fff +#define PRINT_ETH_ADDR(name,addr) grub_printf("%s %x:%x:%x:%x:%x:%x\n",\ + name,\ + addr[0],\ + addr[1],\ + addr[2],\ + addr[3],\ + addr[4],\ + addr[5]\ + ) struct llchdr { diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h index 16f624c05..c369e35a6 100644 --- a/include/grub/net/ieee1275/interface.h +++ b/include/grub/net/ieee1275/interface.h @@ -6,14 +6,5 @@ #include #include - -grub_ofnet_t grub_net; - grub_bootp_t bootp_pckt; - -int send_card_buffer (struct grub_net_buff *pack); -int get_card_packet (struct grub_net_buff *pack); -int card_open (void); -int card_close (void); - #endif diff --git a/include/grub/net/mem.h b/include/grub/net/mem.h new file mode 100644 index 000000000..bbdac512b --- /dev/null +++ b/include/grub/net/mem.h @@ -0,0 +1,9 @@ +#ifndef GRUB_NETMM_H +#define GRUB_NETMM_H 1 + +#include +#include + +void *EXPORT_FUNC(grub_net_malloc) (grub_size_t size); + +#endif /* ! GRUB_MM_H */ diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 337fc4b7e..2650ff3d4 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -23,6 +23,10 @@ #include #include #include +#include +#include +#include +#include enum grub_ieee1275_parse_type { @@ -490,3 +494,63 @@ grub_getbootp( void ) return packet; } +void grub_ofnet_findcards (void) +{ + struct grub_net_card *card; + int i = 0; + + auto int search_net_devices (struct grub_ieee1275_devalias *alias); + + int search_net_devices (struct grub_ieee1275_devalias *alias) + { + if ( !grub_strcmp (alias->type,"network") ) + { + + card = grub_malloc (sizeof (struct grub_net_card)); + struct grub_ofnetcard_data *ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); + ofdata->path = grub_strdup (alias->path); + card->data = ofdata; + card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name); + grub_net_card_register (card); + } + return 0; + } + + /*Look at all nodes for devices of the type network*/ + grub_ieee1275_devices_iterate (search_net_devices); + +} + +void grub_ofnet_probecards (void) +{ + struct grub_net_card *card; + struct grub_net_card_driver *driver; + + /*Assign correspondent driver for each device. */ + FOR_NET_CARDS (card) + { + FOR_NET_CARD_DRIVERS (driver) + { + if (driver->init(card) == GRUB_ERR_NONE) + { + card->driver = driver; + continue; + } + } + } +} + +void +grub_ofnet_init(void) +{ + + ofdriver_ini(); + grub_ofnet_findcards(); + grub_ofnet_probecards(); + + /*init tftp stack - will be handled by module subsystem in the future*/ + tftp_ini (); + /*get bootp packet - won't be needed in the future*/ + bootp_pckt = grub_getbootp (); + grub_disknet_init(); +} diff --git a/net/drivers/ieee1275/ofdriver.c b/net/drivers/ieee1275/ofdriver.c new file mode 100644 index 000000000..5f6c3c2f6 --- /dev/null +++ b/net/drivers/ieee1275/ofdriver.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +static +grub_err_t card_open (struct grub_net_card *dev) +{ + + struct grub_ofnetcard_data *data = dev->data; + return grub_ieee1275_open (data->path,&(data->handle)); +} + +static +grub_err_t card_close (struct grub_net_card *dev) +{ + + struct grub_ofnetcard_data *data = dev->data; + + if (data->handle) + grub_ieee1275_close (data->handle); + return GRUB_ERR_NONE; +} + +static +grub_err_t send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +{ + + int actual; + struct grub_ofnetcard_data *data = dev->data; + + return grub_ieee1275_write (data->handle,pack->data,pack->tail - pack->data,&actual); +} + +static +grub_err_t get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) +{ + + int actual, rc; + struct grub_ofnetcard_data *data = dev->data; + grub_netbuff_clear(pack); + + do + { + rc = grub_ieee1275_read (data->handle,pack->data,1500,&actual); + + }while (actual <= 0 || rc < 0); + grub_netbuff_put (pack, actual); + + return GRUB_ERR_NONE; +} + +static struct grub_net_card_driver ofdriver = +{ + .name = "ofnet", + .init = card_open, + .fini = card_close, + .send = send_card_buffer, + .recv = get_card_packet + +}; + +void ofdriver_ini(void) +{ + grub_net_card_driver_register (&ofdriver); +} + +void ofdriver_fini(void) +{ + grub_net_card_driver_unregister (&ofdriver); +} + + + diff --git a/net/ethernet.c b/net/ethernet.c index 14bc41c5b..7b578abab 100644 --- a/net/ethernet.c +++ b/net/ethernet.c @@ -22,10 +22,10 @@ struct grub_net_addr target_addr, grub_uint16_t ethertype) eth = (struct etherhdr *) nb->data; grub_memcpy(eth->dst, target_addr.addr, target_addr.len); grub_memcpy(eth->src, bootp_pckt->chaddr, 6); + eth->type = ethertype; - return send_card_buffer(nb); -// return inf->card->driver->send(inf->card,nb); + return inf->card->driver->send (inf->card,nb); } @@ -42,12 +42,11 @@ grub_uint16_t ethertype) start_time = grub_get_time_ms(); while (1) { - get_card_packet (nb); + inf->card->driver->recv (inf->card,nb); eth = (struct etherhdr *) nb->data; type = eth->type; grub_netbuff_pull(nb,sizeof (*eth)); - // grub_printf("ethernet type 58 %x\n",type); - // grub_printf("ethernet eth->type 58 %x\n",type); + if (eth->type <=1500) { llch = (struct llchdr *) nb->data; diff --git a/net/i386/mem.c b/net/i386/mem.c new file mode 100644 index 000000000..d6c98ea80 --- /dev/null +++ b/net/i386/mem.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + + +void *grub_net_malloc (grub_size_t size) +{ + return grub_malloc (size); +} diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c deleted file mode 100644 index 342044041..000000000 --- a/net/ieee1275/interface.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include - -static grub_ieee1275_ihandle_t handle; -int card_open (void) -{ - - grub_ieee1275_open (grub_net->dev , &handle); - return 0; - -} - -int card_close (void) -{ - - if (handle) - grub_ieee1275_close (handle); - return 0; -} - - -int send_card_buffer (struct grub_net_buff *pack) -{ - - int actual; - grub_ieee1275_write (handle,pack->data,pack->tail - pack->data,&actual); - - return actual; -} - -int get_card_packet (struct grub_net_buff *pack __attribute__ ((unused))) -{ - - int actual, rc; - pack->data = pack->tail = pack->head; - do - { - rc = grub_ieee1275_read (handle,pack->data,1500,&actual); - - }while (actual <= 0 || rc < 0); - grub_netbuff_put (pack, actual); - -// grub_printf("packsize %d\n",pack->tail - pack->data); - return 0;// sizeof (eth) + iph.len; -} diff --git a/net/ieee1275/mem.c b/net/ieee1275/mem.c new file mode 100644 index 000000000..416a04253 --- /dev/null +++ b/net/ieee1275/mem.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#define TRASHOLD_SIZE 5 * 1024 * 1024 + +void *grub_net_malloc (grub_size_t size) +{ + + int found = 0; + grub_addr_t found_addr; + + if (size <= TRASHOLD_SIZE) + return grub_malloc (size); + + for (found_addr = 0x800000; found_addr < + 2000 * 0x100000; found_addr += 0x100000) + { + if (grub_claimmap (found_addr , size) != -1) + { + found = 1; + break; + } + } + + if (!found) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + + return found?(void *) found_addr:NULL; + +} diff --git a/net/protocol.c b/net/protocol.c index 05d4471d2..bdd7f3671 100644 --- a/net/protocol.c +++ b/net/protocol.c @@ -2,6 +2,8 @@ #include #include +struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL; + #define PROTOCOL_REGISTER_FUNCTIONS(layername) \ struct grub_net_##layername##_layer_protocol *grub_net_##layername##_layer_protocols;\ \ From b09cf083a05470d39b9be891f359aa25d2f64f39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 00:30:47 +0200 Subject: [PATCH 0179/1414] Fix compilation issue --- grub-core/loader/i386/multiboot_mbi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 4e6eca2e6..aa2c4a202 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -194,7 +194,7 @@ grub_multiboot_get_mbi_size (void) + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) + elf_sec_entsize * elf_sec_num -#if HAS_VBE +#if GRUB_MACHINE_HAS_VBE + sizeof (struct grub_vbe_info_block) + sizeof (struct grub_vbe_mode_info_block) #endif @@ -243,7 +243,7 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) grub_mmap_iterate (hook); } -#if HAS_VBE +#if GRUB_MACHINE_HAS_VBE static grub_err_t fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, grub_uint32_t ptrdest, int fill_generic) From 0b37526a5ab7dba0de1201af57bb174f9afe9348 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 00:37:30 +0200 Subject: [PATCH 0180/1414] Add VBE PM interface --- grub-core/loader/i386/multiboot_mbi.c | 7 +++---- grub-core/video/i386/pc/vbe.c | 26 ++++++++++++++++++++++++++ include/grub/i386/pc/vbe.h | 3 +++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index aa2c4a202..8411c7ec6 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -289,10 +289,9 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, ptrorig += sizeof (struct grub_vbe_mode_info_block); ptrdest += sizeof (struct grub_vbe_mode_info_block); - /* FIXME: retrieve those. */ - mbi->vbe_interface_seg = 0; - mbi->vbe_interface_off = 0; - mbi->vbe_interface_len = 0; + grub_vbe_bios_get_pm_interface (&mbi->vbe_interface_seg, + &mbi->vbe_interface_off, + &mbi->vbe_interface_len); mbi->flags |= MULTIBOOT_INFO_VBE_INFO; diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 4bb46e4cd..2ddb4ca80 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -248,6 +248,32 @@ grub_vbe_bios_get_display_start (grub_uint32_t *x, return regs.eax & 0xffff; } +/* Call VESA BIOS 0x4f0a. */ +grub_vbe_status_t +grub_vbe_bios_get_pm_interface (grub_uint16_t *segment, grub_uint16_t *offset, + grub_uint16_t *length) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x4f0a; + regs.ebx = 0x0000; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + + if ((regs.eax & 0xffff) != GRUB_VBE_STATUS_OK) + { + *segment = 0; + *offset = 0; + *length = 0; + } + + *segment = regs.es & 0xffff; + *offset = regs.edi & 0xffff; + *length = regs.ecx & 0xffff; + return regs.eax & 0xffff; +} + + grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block) { diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index 9b05c2299..fba3ee642 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -209,6 +209,9 @@ grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode, grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode); grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode, struct grub_vbe_mode_info_block *mode_info); +grub_vbe_status_t +grub_vbe_bios_get_pm_interface (grub_uint16_t *seg, grub_uint16_t *offset, + grub_uint16_t *length); #endif /* ! GRUB_VBE_MACHINE_HEADER */ From f0eee6b26a2a34f0bbe3c8feaa8a0bd230df3039 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 00:54:21 +0200 Subject: [PATCH 0181/1414] implement multiboot2 vbe specification --- grub-core/loader/multiboot_mbi2.c | 73 ++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index f453dcc6a..05faf15e9 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -138,10 +138,10 @@ grub_multiboot_load (grub_file_t file) case MULTIBOOT_TAG_TYPE_BOOTDEV: case MULTIBOOT_TAG_TYPE_MMAP: case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: - break; - case MULTIBOOT_TAG_TYPE_VBE: case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: + break; + case MULTIBOOT_TAG_TYPE_APM: default: grub_free (buffer); @@ -273,12 +273,13 @@ grub_multiboot_get_mbi_size (void) + (sizeof (struct multiboot_tag_string) + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN)) + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd) - + sizeof (struct multiboot_tag_basic_meminfo) + + ALIGN_UP (sizeof (struct multiboot_tag_basic_meminfo), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN) - + sizeof (struct multiboot_tag_elf_sections) - + elf_sec_entsize * elf_sec_num - + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count () - * sizeof (struct multiboot_mmap_entry)) + + ALIGN_UP (sizeof (struct multiboot_tag_elf_sections), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (elf_sec_entsize * elf_sec_num, MULTIBOOT_TAG_ALIGN) + + ALIGN_UP ((sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count () + * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1; } @@ -329,6 +330,54 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) grub_mmap_iterate (hook); } +#if defined (GRUB_MACHINE_PCBIOS) +static void +fill_vbe_tag (struct multiboot_tag_vbe *tag) +{ + grub_vbe_status_t status; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + tag->type = MULTIBOOT_TAG_TYPE_VBE; + tag->size = 0; + + status = grub_vbe_bios_get_controller_info (scratch); + if (status != GRUB_VBE_STATUS_OK) + return; + + grub_memcpy (&tag->vbe_control_info, scratch, + sizeof (struct grub_vbe_info_block)); + + status = grub_vbe_bios_get_mode (scratch); + tag->vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return; + + /* get_mode_info isn't available for mode 3. */ + if (tag->vbe_mode == 3) + { + struct grub_vbe_mode_info_block *mode_info = (void *) &tag->vbe_mode_info; + grub_memset (mode_info, 0, + sizeof (struct grub_vbe_mode_info_block)); + mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; + mode_info->x_resolution = 80; + mode_info->y_resolution = 25; + } + else + { + status = grub_vbe_bios_get_mode_info (tag->vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return; + grub_memcpy (&tag->vbe_mode_info, scratch, + sizeof (struct grub_vbe_mode_info_block)); + } + grub_vbe_bios_get_pm_interface (&tag->vbe_interface_seg, + &tag->vbe_interface_off, + &tag->vbe_interface_len); + + tag->size = sizeof (*tag); +} +#endif + static grub_err_t retrieve_video_parameters (grub_uint8_t **ptrorig) { @@ -417,6 +466,16 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) return GRUB_ERR_NONE; #endif +#if GRUB_MACHINE_HAS_VBE + { + struct multiboot_tag_vbe *tag_vbe = (struct multiboot_tag_vbe *) *ptrorig; + + fill_vbe_tag (tag_vbe); + + *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN); + } +#endif + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); if (err) return err; From be458ae2643316ffb4df4b07028df0d9d5e99b8b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 16 Sep 2010 14:09:37 +0100 Subject: [PATCH 0182/1414] * .bzrignore: Add *.1, *.8, grub-shell, grub-shell-tester, libgrub_a_init.c, and util/bash-completion.d/grub. --- .bzrignore | 6 ++++++ ChangeLog | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/.bzrignore b/.bzrignore index 411daae47..b5c9df6f2 100644 --- a/.bzrignore +++ b/.bzrignore @@ -4,6 +4,8 @@ 30_os-prober 40_custom 41_custom +*.1 +*.8 aclocal.m4 ascii.bitmaps ascii.h @@ -57,11 +59,14 @@ grub-set-default grub-setup grub_setup_init.c grub_setup_init.h +grub-shell +grub-shell-tester *.img include/grub/cpu include/grub/machine install-sh lib/libgcrypt-grub +libgrub_a_init.c *.lst Makefile *.mod @@ -98,3 +103,4 @@ grub-core/Makefile.gcry.am grub-core/Makefile.gcry.def grub-core/*.module grub-core/*.pp +util/bash-completion.d/grub diff --git a/ChangeLog b/ChangeLog index 0696c38b3..5cfe2fa9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-16 Colin Watson + + * .bzrignore: Add *.1, *.8, grub-shell, grub-shell-tester, + libgrub_a_init.c, and util/bash-completion.d/grub. + 2010-09-15 Vladimir Serbinenko * util/grub-setup.c (setup): Fix incorrect container semantics. From e5bfc130a4e32a73120e017593b4259b1c3c0a30 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 16 Sep 2010 14:13:48 +0100 Subject: [PATCH 0183/1414] * docs/grub.texi (serial): Remove obsolete comment about GRUB needing to be compiled with serial support. (ls): Indicate that multiple files are accepted. * grub-core/commands/ls.c (GRUB_MOD_INIT): Update help text to indicate that multiple files are accepted. --- ChangeLog | 8 ++++++++ docs/grub.texi | 5 ++--- grub-core/commands/ls.c | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5cfe2fa9f..648d60f47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-09-16 Colin Watson + + * docs/grub.texi (serial): Remove obsolete comment about GRUB + needing to be compiled with serial support. + (ls): Indicate that multiple files are accepted. + * grub-core/commands/ls.c (GRUB_MOD_INIT): Update help text to + indicate that multiple files are accepted. + 2010-09-16 Colin Watson * .bzrignore: Add *.1, *.8, grub-shell, grub-shell-tester, diff --git a/docs/grub.texi b/docs/grub.texi index af6d42ccb..076adfd6c 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2415,8 +2415,7 @@ The serial port is not used as a communication channel unless the @command{terminal_input} or @command{terminal_output} command is used (@pxref{terminal_input}, @pxref{terminal_output}). -This command is only available if GRUB is compiled with serial -support. See also @ref{Serial terminal}. +See also @ref{Serial terminal}. @end deffn @@ -2907,7 +2906,7 @@ This command is only available on x86 systems. @node ls @subsection ls -@deffn Command ls [arg] +@deffn Command ls [arg @dots{}] List devices or files. With no arguments, print all devices known to GRUB. diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 3bd6607be..481d17db0 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -270,7 +270,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(ls) { cmd = grub_register_extcmd ("ls", grub_cmd_ls, 0, - N_("[-l|-h|-a] [FILE]"), + N_("[-l|-h|-a] [FILE ...]"), N_("List devices and files."), options); } From c514c29712e89b5ef7a3423787820ddeb9a80154 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 16 Sep 2010 14:50:41 +0100 Subject: [PATCH 0184/1414] Explicitly pass -d ${pkglibdir} to grub-mkimage, to make it easier to run grub-install from the build directory. --- util/grub-install.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 0ef4cfe84..955bf0257 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -552,7 +552,7 @@ case "${target_cpu}-${platform}" in esac -$grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.${imgext} --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +$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 @@ -560,7 +560,7 @@ if [ "${target_cpu}-${platform}" = "mips-yeeloong" ]; then elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then cp ${grubdir}/core.${imgext} /boot/grub/grub elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ]; then - $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 + $grub_mkimage ${config_opt} -d ${pkglibdir} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 fi From 108538d8ffd7bd584b305ae51e125523eb8003b6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 16 Sep 2010 14:55:28 +0100 Subject: [PATCH 0185/1414] Support RAID on virtio devices, and others. * grub-core/kern/emu/getroot.c [__MINGW32__] (find_root_device): Rename to ... [__MINGW32__] (grub_find_device): ... this. [! __MINGW32__ && ! __CYGWIN__] (find_root_device): Rename to ... [! __MINGW32__ && ! __CYGWIN__] (grub_find_device): ... this. Use a reasonable default if dir is NULL. [! __MINGW32__ && __CYGWIN__] (find_cygwin_root_device): Rename to ... [! __MINGW32__ && __CYGWIN__] (grub_find_device): ... this. (grub_guess_root_device): Update callers. * include/grub/emu/getroot.h (grub_find_device): Add prototype. * util/raid.c (grub_util_getdiskname): Remove. (grub_util_raid_getmembers): Use grub_find_device rather than grub_util_getdiskname. --- ChangeLog | 20 ++++++++++++++++++++ grub-core/kern/emu/getroot.c | 29 +++++++++++++++++++---------- include/grub/emu/getroot.h | 3 +++ util/raid.c | 28 ++++------------------------ 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 648d60f47..050b74a3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-09-16 Colin Watson + + Support RAID on virtio devices, and others. + + * grub-core/kern/emu/getroot.c [__MINGW32__] (find_root_device): + Rename to ... + [__MINGW32__] (grub_find_device): ... this. + [! __MINGW32__ && ! __CYGWIN__] (find_root_device): Rename to ... + [! __MINGW32__ && ! __CYGWIN__] (grub_find_device): ... this. Use a + reasonable default if dir is NULL. + [! __MINGW32__ && __CYGWIN__] (find_cygwin_root_device): Rename to + ... + [! __MINGW32__ && __CYGWIN__] (grub_find_device): ... this. + (grub_guess_root_device): Update callers. + * include/grub/emu/getroot.h (grub_find_device): Add prototype. + + * util/raid.c (grub_util_getdiskname): Remove. + (grub_util_raid_getmembers): Use grub_find_device rather than + grub_util_getdiskname. + 2010-09-16 Colin Watson * docs/grub.texi (serial): Remove obsolete comment about GRUB diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 32dcb49ca..003fe9333 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -228,8 +228,8 @@ find_root_device_from_libzfs (const char *dir) #ifdef __MINGW32__ -static char * -find_root_device (const char *dir __attribute__ ((unused)), +char * +grub_find_device (const char *dir __attribute__ ((unused)), dev_t dev __attribute__ ((unused))) { return 0; @@ -237,13 +237,22 @@ find_root_device (const char *dir __attribute__ ((unused)), #elif ! defined(__CYGWIN__) -static char * -find_root_device (const char *dir, dev_t dev) +char * +grub_find_device (const char *dir, dev_t dev) { DIR *dp; char *saved_cwd; struct dirent *ent; + if (! dir) + { +#ifdef __CYGWIN__ + return NULL; +#else + dir = "/dev"; +#endif + } + dp = opendir (dir); if (! dp) return 0; @@ -292,7 +301,7 @@ find_root_device (const char *dir, dev_t dev) /* Find it recursively. */ char *res; - res = find_root_device (ent->d_name, dev); + res = grub_find_device (ent->d_name, dev); if (res) { @@ -402,8 +411,8 @@ get_bootsec_serial (const char *os_dev, int mbr) return serial; } -static char * -find_cygwin_root_device (const char *path, dev_t dev) +char * +grub_find_device (const char *path, dev_t dev) { /* No root device for /cygdrive. */ if (dev == (DEV_CYGDRIVE_MAJOR << 16)) @@ -424,7 +433,7 @@ find_cygwin_root_device (const char *path, dev_t dev) /* Cygwin returns the partition serial number in stat.st_dev. This is never identical to the device number of the emulated - /dev/sdXN device, so above find_root_device () does not work. + /dev/sdXN device, so above grub_find_device () does not work. Search the partition with the same serial in boot sector instead. */ char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */ int d; @@ -529,12 +538,12 @@ grub_guess_root_device (const char *dir) #ifdef __CYGWIN__ /* Cygwin specific function. */ - os_dev = find_cygwin_root_device (dir, st.st_dev); + os_dev = grub_find_device (dir, st.st_dev); #else /* This might be truly slow, but is there any better way? */ - os_dev = find_root_device ("/dev", st.st_dev); + os_dev = grub_find_device ("/dev", st.st_dev); #endif #endif /* !__GNU__ */ diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 04a2805c8..581ea8056 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -19,12 +19,15 @@ #ifndef GRUB_UTIL_GETROOT_HEADER #define GRUB_UTIL_GETROOT_HEADER 1 +#include + enum grub_dev_abstraction_types { GRUB_DEV_ABSTRACTION_NONE, GRUB_DEV_ABSTRACTION_LVM, GRUB_DEV_ABSTRACTION_RAID, }; +char *grub_find_device (const char *dir, dev_t dev); char *grub_guess_root_device (const char *dir); int grub_util_get_dev_abstraction (const char *os_dev); char *grub_util_get_grub_dev (const char *os_dev); diff --git a/util/raid.c b/util/raid.c index edf865aa7..dac19a935 100644 --- a/util/raid.c +++ b/util/raid.c @@ -22,40 +22,19 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include -static char * -grub_util_getdiskname (int major, int minor) -{ - char *name = xmalloc (15); - - if (major == LOOP_MAJOR) - sprintf (name, "/dev/loop%d", minor); - else if (major == IDE0_MAJOR) - sprintf (name, "/dev/hd%c", 'a' + minor / 64); - else if (major == IDE1_MAJOR) - sprintf (name, "/dev/hd%c", 'c' + minor / 64); - else if (major == IDE2_MAJOR) - sprintf (name, "/dev/hd%c", 'e' + minor / 64); - else if (major == IDE3_MAJOR) - sprintf (name, "/dev/hd%c", 'g' + minor / 64); - else if (major == SCSI_DISK0_MAJOR) - sprintf (name, "/dev/sd%c", 'a' + minor / 16); - else - grub_util_error ("unknown device number: %d, %d", major, minor); - - return name; -} - char ** grub_util_raid_getmembers (char *name) { @@ -100,7 +79,8 @@ grub_util_raid_getmembers (char *name) if (disk.state & (1 << MD_DISK_ACTIVE)) { - devicelist[j] = grub_util_getdiskname (disk.major, disk.minor); + devicelist[j] = grub_find_device (NULL, + makedev (disk.major, disk.minor)); j++; } } From 10854d0d79ce5bf62f623f51ee9bb041031b21ba Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Thu, 16 Sep 2010 17:07:42 +0200 Subject: [PATCH 0186/1414] * configure.ac: Avoid some annoying error messages if freetype-config program is not found. --- ChangeLog | 5 +++++ configure.ac | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 050b74a3f..2d204338e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-16 Yves Blusseau + + * configure.ac: Avoid some annoying error messages if freetype-config + program is not found. + 2010-09-16 Colin Watson Support RAID on virtio devices, and others. diff --git a/configure.ac b/configure.ac index 10723987b..57df640b8 100644 --- a/configure.ac +++ b/configure.ac @@ -796,12 +796,12 @@ if test x"$grub_mkfont_excuse" = x ; then if test "x$FREETYPE" = x ; then grub_mkfont_excuse=["need freetype2 library"] fi - freetype_cflags=`freetype-config --cflags` - freetype_libs=`freetype-config --libs` fi if test x"$grub_mkfont_excuse" = x ; then # Check for freetype libraries. + freetype_cflags=`freetype-config --cflags` + freetype_libs=`freetype-config --libs` SAVED_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $freetype_cflags" AC_CHECK_HEADERS([ft2build.h], [], From 7756d44436cd5caad6e12846658712f0d21b9e45 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 23:48:32 +0200 Subject: [PATCH 0187/1414] Basic menuentry-retrieveing jail --- grub-core/commands/configfile.c | 35 ++++++++++++---- grub-core/commands/menuentry.c | 3 +- grub-core/commands/search_wrap.c | 2 +- grub-core/commands/test.c | 2 + grub-core/kern/corecmd.c | 9 ++-- grub-core/normal/context.c | 71 +++++++++++++++++++++++++------- grub-core/script/execute.c | 7 +++- include/grub/command.h | 2 + include/grub/env.h | 9 +++- include/grub/err.h | 3 +- include/grub/normal.h | 2 + 11 files changed, 115 insertions(+), 30 deletions(-) diff --git a/grub-core/commands/configfile.c b/grub-core/commands/configfile.c index 469447711..4d54ae682 100644 --- a/grub-core/commands/configfile.c +++ b/grub-core/commands/configfile.c @@ -27,28 +27,34 @@ static grub_err_t grub_cmd_source (grub_command_t cmd, int argc, char **args) { - int new_env; + int new_env, jail; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - new_env = (cmd->name[0] == 'c'); + jail = (cmd->name[0] == 'j'); + new_env = (cmd->name[jail ? 5 : 0] == 'c'); if (new_env) - { - grub_cls (); - grub_env_context_open (1); - } + grub_cls (); + + if (new_env && !jail) + grub_env_context_open (); + if (jail) + grub_env_jail_open (!new_env); grub_normal_execute (args[0], 1, ! new_env); - if (new_env) + if (new_env && !jail) grub_env_context_close (); + if (jail) + grub_env_jail_close (!new_env); return 0; } static grub_command_t cmd_configfile, cmd_source, cmd_dot; +static grub_command_t cmd_jail_source, cmd_jail_configfile; GRUB_MOD_INIT(configfile) { @@ -60,6 +66,19 @@ GRUB_MOD_INIT(configfile) N_("FILE"), N_("Load another config file without changing context.") ); + + cmd_jail_source = + grub_register_command ("jail_source", grub_cmd_source, + N_("FILE"), + N_("Load another config file without changing context but take only menuentries.") + ); + + cmd_jail_configfile = + grub_register_command ("jail_configfile", grub_cmd_source, + N_("FILE"), + N_("Load another config file without changing context but take only menuentries.") + ); + cmd_dot = grub_register_command (".", grub_cmd_source, N_("FILE"), @@ -71,5 +90,7 @@ GRUB_MOD_FINI(configfile) { grub_unregister_command (cmd_configfile); grub_unregister_command (cmd_source); + grub_unregister_command (cmd_jail_configfile); + grub_unregister_command (cmd_jail_source); grub_unregister_command (cmd_dot); } diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 9c4139d7d..3f6f295bc 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -274,7 +274,8 @@ void grub_menu_init (void) { cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry, - GRUB_COMMAND_FLAG_BLOCKS, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_FLAG_UNJAILED, N_("BLOCK"), N_("Define a menuentry."), options); } diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 402421f65..a06399ac6 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -90,7 +90,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(search) { cmd = - grub_register_extcmd ("search", grub_cmd_search, 0, + grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_UNJAILED, N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]" " NAME"), N_("Search devices by file, filesystem label" diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c index 97b7fe6e4..3affab9c5 100644 --- a/grub-core/commands/test.c +++ b/grub-core/commands/test.c @@ -423,8 +423,10 @@ GRUB_MOD_INIT(test) { cmd_1 = grub_register_command ("[", grub_cmd_test, N_("EXPRESSION ]"), N_("Evaluate an expression.")); + cmd_1->flags |= GRUB_COMMAND_FLAG_UNJAILED; cmd_2 = grub_register_command ("test", grub_cmd_test, N_("EXPRESSION"), N_("Evaluate an expression.")); + cmd_2->flags |= GRUB_COMMAND_FLAG_UNJAILED; } GRUB_MOD_FINI(test) diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c index 8675248d3..f1d060cef 100644 --- a/grub-core/kern/corecmd.c +++ b/grub-core/kern/corecmd.c @@ -178,9 +178,12 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), void grub_register_core_commands (void) { - grub_register_command ("set", grub_core_cmd_set, - N_("[ENVVAR=VALUE]"), - N_("Set an environment variable.")); + grub_command_t cmd; + cmd = grub_register_command ("set", grub_core_cmd_set, + N_("[ENVVAR=VALUE]"), + N_("Set an environment variable.")); + if (cmd) + cmd->flags |= GRUB_COMMAND_FLAG_UNJAILED; grub_register_command ("unset", grub_core_cmd_unset, N_("ENVVAR"), N_("Remove an environment variable.")); diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index ec718952d..3b182dde7 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -52,8 +52,8 @@ grub_env_set_menu (grub_menu_t nmenu) current_menu->menu = nmenu; } -grub_err_t -grub_env_context_open (int export) +static grub_err_t +grub_env_new_context (int export_all) { struct grub_env_context *context; int i; @@ -78,23 +78,36 @@ grub_env_context_open (int export) struct grub_env_var *var; for (var = context->prev->vars[i]; var; var = var->next) - { - if (export && var->global) - { - if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) - { - grub_env_context_close (); - return grub_errno; - } - grub_env_export (var->name); - grub_register_variable_hook (var->name, var->read_hook, var->write_hook); - } - } + if (var->global || export_all) + { + if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) + { + grub_env_context_close (); + return grub_errno; + } + grub_env_export (var->name); + grub_register_variable_hook (var->name, var->read_hook, var->write_hook); + } } return GRUB_ERR_NONE; } +grub_err_t +grub_env_context_open (void) +{ + return grub_env_new_context (0); +} + +int grub_jail_level = 0; + +grub_err_t +grub_env_jail_open (int source) +{ + grub_jail_level++; + return grub_env_new_context (source); +} + grub_err_t grub_env_context_close (void) { @@ -132,6 +145,36 @@ grub_env_context_close (void) return GRUB_ERR_NONE; } +grub_err_t +grub_env_jail_close (int source) +{ + grub_menu_t menu, menu2; + grub_menu_entry_t *last; + grub_err_t err; + + if (source) + { + menu = grub_env_get_menu (); + grub_env_unset_menu (); + } + err = grub_env_context_close (); + + if (source) + { + menu2 = grub_env_get_menu (); + + last = &menu2->entry_list; + while (*last) + last = &(*last)->next; + + *last = menu->entry_list; + menu2->size += menu->size; + } + + grub_jail_level--; + return err; +} + grub_err_t grub_env_export (const char *name) { diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index e24c4b1af..8d64962f8 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -611,8 +611,11 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute the GRUB command or function. */ if (grubcmd) { - if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) && - (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD)) + if (grub_jail_level && !(grubcmd->flags & GRUB_COMMAND_FLAG_UNJAILED)) + ret = grub_error (GRUB_ERR_JAIL, "%s isn't allowed to execute in jail", + cmdname); + else if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) && + (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD)) ret = grub_extcmd_dispatcher (grubcmd, argc, args, argv.script); else ret = (grubcmd->func) (grubcmd, argc, args); diff --git a/include/grub/command.h b/include/grub/command.h index 3b7bf0a10..b17b1aa94 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -35,6 +35,8 @@ typedef enum grub_command_flags GRUB_COMMAND_ACCEPT_DASH = 0x80, /* This command accepts only options preceding direct arguments. */ GRUB_COMMAND_OPTIONS_AT_START = 0x100, + /* Can be executed in a jail. */ + GRUB_COMMAND_FLAG_UNJAILED = 0x200 } grub_command_flags_t; struct grub_command; diff --git a/include/grub/env.h b/include/grub/env.h index ae4fd8745..ee0e0546e 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -51,7 +51,7 @@ grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, grub_env_read_hook_t read_hook, grub_env_write_hook_t write_hook); -grub_err_t grub_env_context_open (int export); +grub_err_t grub_env_context_open (void); grub_err_t grub_env_context_close (void); grub_err_t grub_env_export (const char *name); @@ -59,4 +59,11 @@ void grub_env_unset_menu (void); grub_menu_t grub_env_get_menu (void); void grub_env_set_menu (grub_menu_t nmenu); +grub_err_t +grub_env_jail_open (int source); + +grub_err_t +grub_env_jail_close (int source); + + #endif /* ! GRUB_ENV_HEADER */ diff --git a/include/grub/err.h b/include/grub/err.h index d35bba474..18dc91efe 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -54,7 +54,8 @@ typedef enum GRUB_ERR_MENU, GRUB_ERR_TIMEOUT, GRUB_ERR_IO, - GRUB_ERR_ACCESS_DENIED + GRUB_ERR_ACCESS_DENIED, + GRUB_ERR_JAIL } grub_err_t; diff --git a/include/grub/normal.h b/include/grub/normal.h index 51ab46b12..7c99951c6 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -115,4 +115,6 @@ void grub_normal_reset_more (void); void grub_xputs_normal (const char *str); +extern int grub_jail_level; + #endif /* ! GRUB_NORMAL_HEADER */ From 0f7ee3c969360f031f98c00305f0c345fa576645 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Fri, 17 Sep 2010 11:56:04 +0200 Subject: [PATCH 0188/1414] * .bzrignore: *.d removed (old rule), add *.image and symlist.h. --- .bzrignore | 3 ++- ChangeLog | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index b5c9df6f2..5c121e652 100644 --- a/.bzrignore +++ b/.bzrignore @@ -20,7 +20,6 @@ config.log config.status config.sub configure -*.d DISTLIST docs/*.info docs/stamp-vti @@ -62,6 +61,7 @@ grub_setup_init.h grub-shell grub-shell-tester *.img +*.image include/grub/cpu include/grub/machine install-sh @@ -80,6 +80,7 @@ stamp-h stamp-h1 stamp-h.in symlist.c +symlist.h trigtables.c update-grub_lib unidata.c diff --git a/ChangeLog b/ChangeLog index 2d204338e..885ae3be8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-17 Yves Blusseau + + * .bzrignore: *.d removed (old rule), add *.image and symlist.h. + 2010-09-16 Yves Blusseau * configure.ac: Avoid some annoying error messages if freetype-config From a939d135ec53026a4f0b15f00962a4e3a8908b7a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 17 Sep 2010 11:00:37 +0100 Subject: [PATCH 0189/1414] Fix DM-RAID probing with recent versions of device-mapper udev rules. * grub-core/kern/emu/hostdisk.c (read_device_map): Don't canonicalise device paths under /dev/mapper/. (convert_system_partition_to_system_disk): Compare the uncanonicalised path to /dev/mapper/ rather than the canonicalised path, since device nodes under /dev/mapper/ are often symlinks. --- ChangeLog | 11 +++++++++++ grub-core/kern/emu/hostdisk.c | 21 +++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 885ae3be8..7f5ba2d44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-09-17 Colin Watson + + Fix DM-RAID probing with recent versions of device-mapper udev + rules. + + * grub-core/kern/emu/hostdisk.c (read_device_map): Don't + canonicalise device paths under /dev/mapper/. + (convert_system_partition_to_system_disk): Compare the + uncanonicalised path to /dev/mapper/ rather than the canonicalised + path, since device nodes under /dev/mapper/ are often symlinks. + 2010-09-17 Yves Blusseau * .bzrignore: *.d removed (old rule), add *.image and symlist.h. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index edf8dc219..69c5ed921 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -955,13 +955,16 @@ read_device_map (const char *dev_map) #ifdef __linux__ /* On Linux, the devfs uses symbolic links horribly, and that confuses the interface very much, so use realpath to expand - symbolic links. */ - map[drive].device = xmalloc (PATH_MAX); - if (! realpath (p, map[drive].device)) - grub_util_error ("cannot get the real path of `%s'", p); -#else - map[drive].device = xstrdup (p); + symbolic links. Leave /dev/mapper/ alone, though. */ + if (strncmp (p, "/dev/mapper/", 12) != 0) + { + map[drive].device = xmalloc (PATH_MAX); + if (! realpath (p, map[drive].device)) + grub_util_error ("cannot get the real path of `%s'", p); + } + else #endif + map[drive].device = xstrdup (p); } fclose (fp); @@ -1153,8 +1156,10 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) } #ifdef HAVE_DEVICE_MAPPER - /* If this is a DM-RAID device. */ - if ((strncmp ("mapper/", p, 7) == 0)) + /* If this is a DM-RAID device. + Compare os_dev rather than path here, since nodes under + /dev/mapper/ are often symlinks. */ + if ((strncmp ("/dev/mapper/", os_dev, 12) == 0)) { static struct dm_tree *tree = NULL; uint32_t maj, min; From 9c0bad2e15331cc4035e022571cec2e004842083 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 17 Sep 2010 11:43:46 +0100 Subject: [PATCH 0190/1414] * grub-core/kern/emu/hostdisk.c (convert_system_partition_to_system_disk): Fix devmapper memory pool leak. Reported and based on patch by: Modestas Vainius. --- ChangeLog | 7 +++++++ grub-core/kern/emu/hostdisk.c | 36 ++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f5ba2d44..9638bc633 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-09-17 Colin Watson + + * grub-core/kern/emu/hostdisk.c + (convert_system_partition_to_system_disk): Fix devmapper memory pool + leak. + Reported and based on patch by: Modestas Vainius. + 2010-09-17 Colin Watson Fix DM-RAID probing with recent versions of device-mapper udev diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 69c5ed921..a9b94e212 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1161,19 +1161,17 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) /dev/mapper/ are often symlinks. */ if ((strncmp ("/dev/mapper/", os_dev, 12) == 0)) { - static struct dm_tree *tree = NULL; + struct dm_tree *tree; uint32_t maj, min; struct dm_tree_node *node, *child; void *handle; - const char *node_uuid, *mapper_name, *child_uuid, *child_name; - - if (! tree) - tree = dm_tree_create (); + const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name; + tree = dm_tree_create (); if (! tree) { grub_dprintf ("hostdisk", "dm_tree_create failed\n"); - return NULL; + goto devmapper_out; } maj = major (st->st_rdev); @@ -1181,29 +1179,30 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) if (! dm_tree_add_dev (tree, maj, min)) { grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); - return NULL; + goto devmapper_out; } node = dm_tree_find_node (tree, maj, min); if (! node) { grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); - return NULL; + goto devmapper_out; } node_uuid = dm_tree_node_get_uuid (node); if (! node_uuid) { grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); - return NULL; + node = NULL; + goto devmapper_out; } else if (strncmp (node_uuid, "DMRAID-", 7) != 0) { grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); - return NULL; + node = NULL; + goto devmapper_out; } handle = NULL; - mapper_name = NULL; /* Counter-intuitively, device-mapper refers to the disk-like device containing a DM-RAID partition device as a "child" of the partition device. */ @@ -1233,17 +1232,20 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) mapper_name = child_name; devmapper_out: - if (! mapper_name) + if (! mapper_name && node) { /* This is a DM-RAID disk, not a partition. */ mapper_name = dm_tree_node_get_name (node); if (! mapper_name) - { - grub_dprintf ("hostdisk", "%s has no DM name\n", path); - return NULL; - } + grub_dprintf ("hostdisk", "%s has no DM name\n", path); } - return xasprintf ("/dev/mapper/%s", mapper_name); + if (tree) + dm_tree_free (tree); + free (path); + if (mapper_name) + return xasprintf ("/dev/mapper/%s", mapper_name); + else + return NULL; } #endif /* HAVE_DEVICE_MAPPER */ } From bf8d13388dfa31b8961280b027365ce062beafc6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 17 Sep 2010 23:41:06 +0100 Subject: [PATCH 0191/1414] (convert_system_partition_to_system_disk): Initialise node. * grub-core/kern/emu/hostdisk.c --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9638bc633..d34dbd201 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-17 Colin Watson + + * grub-core/kern/emu/hostdisk.c + (convert_system_partition_to_system_disk): Initialise node. + 2010-09-17 Colin Watson * grub-core/kern/emu/hostdisk.c diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index a9b94e212..7d9d1dac1 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1163,7 +1163,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) { struct dm_tree *tree; uint32_t maj, min; - struct dm_tree_node *node, *child; + struct dm_tree_node *node = NULL, *child; void *handle; const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name; From b9c7e9d400b7473006b988a08e19d6bfe76bb795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Sat, 18 Sep 2010 10:56:52 +0200 Subject: [PATCH 0192/1414] Set UHCI low-speed flag --- grub-core/bus/usb/uhci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 755ec70f7..d51aace8c 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -414,7 +414,7 @@ static grub_uhci_td_t grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, grub_transfer_type_t type, unsigned int addr, unsigned int toggle, grub_size_t size, - grub_uint32_t data) + grub_uint32_t data, grub_usb_speed_t speed) { grub_uhci_td_t td; static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; @@ -439,7 +439,8 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, td->linkptr = 1; /* Active! Only retry a transfer 3 times. */ - td->ctrl_status = (1 << 23) | (3 << 27); + td->ctrl_status = (1 << 23) | (3 << 27) | + ((speed == GRUB_USB_SPEED_LOW) ? (1 << 26) : 0); /* If zero bytes are transmitted, size is 0x7FF. Otherwise size is size-1. */ @@ -495,7 +496,8 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev, td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid, transfer->devaddr, tr->toggle, - tr->size, tr->data); + tr->size, tr->data, + transfer->dev->speed); if (! td) { grub_size_t actual = 0; From e70a1b9535ee1af0c84cab327e006948973d463d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Sat, 18 Sep 2010 13:49:15 +0200 Subject: [PATCH 0193/1414] Fix multiple USB issues --- grub-core/bus/usb/ohci.c | 194 ++++++++++++----------------------- grub-core/bus/usb/uhci.c | 48 +++++---- grub-core/bus/usb/usb.c | 2 +- grub-core/bus/usb/usbhub.c | 104 ++++++++++++++++--- grub-core/bus/usb/usbtrans.c | 4 +- include/grub/usb.h | 3 + 6 files changed, 195 insertions(+), 160 deletions(-) diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 7c618a614..b07e30403 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -98,7 +98,6 @@ struct grub_ohci struct grub_pci_dma_chunk *td_chunk; struct grub_ohci *next; grub_ohci_td_t td_free; /* Pointer to first free TD */ - int bad_OHCI; }; static struct grub_ohci *ohci; @@ -149,8 +148,8 @@ typedef enum #define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) #define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16) -#define GRUB_OHCI_CTRL_EDS 16 -#define GRUB_OHCI_BULK_EDS 16 +#define GRUB_OHCI_CTRL_EDS 256 +#define GRUB_OHCI_BULK_EDS 510 #define GRUB_OHCI_TDS 256 #define GRUB_OHCI_ED_ADDR_MASK 0x7ff @@ -442,8 +441,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev, (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) | GRUB_OHCI_RHUB_PORT_ALL_POWERED); +#if 0 /* We don't need it at all, handled via hotplugging */ /* Now we have hot-plugging, we need to wait for stable power only */ grub_millisleep (100); +#endif /* Link to ohci now that initialisation is successful. */ o->next = ohci; @@ -623,7 +624,8 @@ grub_ohci_transaction (grub_ohci_td_t td, break; } - /* Set the token (Always generate interrupt - bits 21-23 = 0). */ + /* Set the token */ + token |= ( 7 << 21); /* Never generate interrupt */ token |= toggle << 24; token |= 1 << 25; @@ -659,7 +661,6 @@ struct grub_ohci_transfer_controller_data grub_ohci_ed_t ed_virt; grub_ohci_td_t td_current_virt; grub_ohci_td_t td_head_virt; - grub_uint64_t bad_OHCI_delay; }; static grub_usb_err_t @@ -756,10 +757,6 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, /* Set index of TD in transfer */ cdata->td_current_virt->tr_index = (grub_uint32_t) i; - - /* No IRQ request in TD if bad_OHCI set */ - if (o->bad_OHCI) - cdata->td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21); /* Remember last used (processed) TD phys. addr. */ cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt); @@ -891,8 +888,8 @@ pre_finish_transfer (grub_usb_controller_t dev, /* Now print debug values - to have full info what happened */ grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n", control, status); - grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n", - intstatus, cdata->tderr_phys, cdata->td_last_phys); + grub_dprintf ("ohci", "intstatus=0x%02x, td_last_phys=0x%02x\n", + intstatus, cdata->td_last_phys); grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n", target, grub_le_to_cpu32 (cdata->ed_virt->td_head), @@ -915,12 +912,6 @@ finish_transfer (grub_usb_controller_t dev, * i.e. it is safe to free all TDs except last not processed * ED HEAD == TAIL == phys. addr. of td_current_virt */ - /* Reset DoneHead - sanity cleanup */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - /* Un-chainig of last TD */ if (cdata->td_current_virt->prev_td_phys) { @@ -929,10 +920,13 @@ finish_transfer (grub_usb_controller_t dev, if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td) td_prev_virt->link_td = 0; + + cdata->td_current_virt->prev_td_phys = 0; } grub_dprintf ("ohci", "OHCI finished, freeing\n"); grub_ohci_free_tds (o, cdata->td_head_virt); + grub_free (cdata); } static grub_usb_err_t @@ -951,28 +945,10 @@ parse_halt (grub_usb_controller_t dev, pre_finish_transfer (dev, transfer); /* First we must get proper tderr_phys value */ - if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */ - { - if (cdata->tderr_phys) /* check if tderr_phys points to TD with error */ - errcode = grub_le_to_cpu32 (grub_ohci_td_phys2virt (o, - cdata->tderr_phys)->token) - >> 28; - if ( !cdata->tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */ - { /* Retired TD with error should be previous TD to ED->td_head */ - cdata->tderr_phys = grub_ohci_td_phys2virt (o, - grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf ) - ->prev_td_phys; - } - } - /* Even if we have "good" OHCI, in some cases - * tderr_phys can be zero, check it */ - else if (!cdata->tderr_phys) - /* Retired TD with error should be previous TD to ED->td_head */ - cdata->tderr_phys - = grub_ohci_td_phys2virt (o, - grub_le_to_cpu32 (cdata->ed_virt->td_head) - & ~0xf)->prev_td_phys; - + /* Retired TD with error should be previous TD to ED->td_head */ + cdata->tderr_phys = grub_ohci_td_phys2virt (o, + grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf ) + ->prev_td_phys; /* Prepare pointer to last processed TD and get error code */ tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys); @@ -1090,16 +1066,12 @@ parse_success (grub_usb_controller_t dev, pre_finish_transfer (dev, transfer); - /* Simple workaround if donehead is not working */ - if (o->bad_OHCI && - (!cdata->tderr_phys || (cdata->tderr_phys != cdata->td_last_phys))) - { - grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n"); - cdata->tderr_phys = cdata->td_last_phys; - /* I hope we can do it as transfer (most probably) finished OK */ - } + /* I hope we can do it as transfer (most probably) finished OK */ + cdata->tderr_phys = cdata->td_last_phys; + /* Prepare pointer to last processed TD */ tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys); + /* Set index of last processed TD */ if (tderr_virt) transfer->last_trans = tderr_virt->tr_index; @@ -1168,25 +1140,6 @@ grub_ohci_check_transfer (grub_usb_controller_t dev, /* Check transfer status */ intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - if (!o->bad_OHCI && (intstatus & 0x2) != 0) - { - /* Remember last successful TD */ - cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; - /* Reset DoneHead */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - /* if TD is last, finish */ - if (cdata->tderr_phys == cdata->td_last_phys) - { - if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1) - return parse_halt (dev, transfer, actual); - else - return parse_success (dev, transfer, actual); - } - return GRUB_USB_ERR_WAIT; - } if ((intstatus & 0x10) != 0) /* Unrecoverable error - only reset can help...! */ @@ -1194,54 +1147,20 @@ grub_ohci_check_transfer (grub_usb_controller_t dev, /* Detected a HALT. */ if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)) - { - /* ED is halted, but donehead event can happened in the meantime */ - intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - if (!o->bad_OHCI && (intstatus & 0x2) != 0) - { - /* Remember last successful TD */ - cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; - /* Reset DoneHead */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - /* if TD is last, finish */ - } - return parse_halt (dev, transfer, actual); - } + return parse_halt (dev, transfer, actual); - /* bad OHCI handling */ + /* Finished ED detection */ if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) == (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */ { - if (o->bad_OHCI) /* Bad OHCI detected previously */ - { - /* Try get last successful TD. */ - cdata->tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; - if (cdata->tderr_phys)/* Reset DoneHead if we were successful */ - { - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - } - /* Check the HALT bit */ - if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1) - return parse_halt (dev, transfer, actual); - else - return parse_success (dev, transfer, actual); - } - else /* Detection of bad OHCI */ - /* We should wait short time (~2ms) before we say that - * it is bad OHCI to prevent some hazard - - * donehead can react in the meantime. This waiting is done - * only once per OHCI driver "live cycle". */ - if (!cdata->bad_OHCI_delay) /* Set delay time */ - cdata->bad_OHCI_delay = grub_get_time_ms () + 2; - else if (grub_get_time_ms () >= cdata->bad_OHCI_delay) - o->bad_OHCI = 1; - return GRUB_USB_ERR_WAIT; + /* Check the HALT bit */ + /* It looks like nonsense - it was tested previously... + * but it can change because OHCI is working + * simultaneously via DMA... */ + if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1) + return parse_halt (dev, transfer, actual); + else + return parse_success (dev, transfer, actual); } return GRUB_USB_ERR_WAIT; @@ -1266,14 +1185,16 @@ grub_ohci_cancel_transfer (grub_usb_controller_t dev, /* Wait for new SOF */ while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); - /* Now we must find last processed TD if bad_OHCI == TRUE */ - if (o->bad_OHCI) - /* Retired TD with error should be previous TD to ED->td_head */ - cdata->tderr_phys - = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head) - & ~0xf)->prev_td_phys; + /* Possible retired TD with error should be previous TD to ED->td_head */ + cdata->tderr_phys + = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head) + & ~0xf)->prev_td_phys; tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys); + + grub_dprintf ("ohci", "Cancel: tderr_phys=0x%08x, tderr_virt=0x%08x\n", + cdata->tderr_phys, (unsigned int)tderr_virt); + if (tderr_virt) transfer->last_trans = tderr_virt->tr_index; else @@ -1290,6 +1211,7 @@ grub_ohci_portstatus (grub_usb_controller_t dev, { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_uint64_t endtime; + int i; grub_dprintf ("ohci", "begin of portstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); @@ -1310,31 +1232,47 @@ grub_ohci_portstatus (grub_usb_controller_t dev, return GRUB_ERR_NONE; } - /* Reset the port */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_SET_PORT_RESET); - grub_millisleep (50); /* For root hub should be nominaly 50ms */ - - /* End the reset signaling. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); - grub_millisleep (10); + /* OHCI does one reset signal 10ms long but USB spec. + * requests 50ms for root hub (no need to be continuous). + * So, we do reset 5 times... */ + for (i = 0; i < 5; i++) + { + /* Reset the port - timing of reset is done by OHCI */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET); - /* Enable the port and wait for it. */ + /* Wait for reset completion */ + endtime = grub_get_time_ms () + 1000; + while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) + & GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE)) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, "OHCI Timed out - reset"); + + /* End the reset signaling - reset the reset status change */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + } + + /* Enable port */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, GRUB_OHCI_SET_PORT_ENABLE); + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + + /* Wait for signal enabled */ endtime = grub_get_time_ms () + 1000; while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) & (1 << 1))) if (grub_get_time_ms () > endtime) return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable"); - grub_millisleep (10); - /* Reset bit Connect Status Change */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, GRUB_OHCI_RESET_CONNECT_CHANGE); + /* "Reset recovery time" (USB spec.) */ + grub_millisleep (10); + grub_dprintf ("ohci", "end of portstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index d51aace8c..2265ebed0 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -50,9 +50,12 @@ enum GRUB_UHCI_REG_PORTSC_SUSPEND = 0x1000, GRUB_UHCI_REG_PORTSC_RW = GRUB_UHCI_REG_PORTSC_PORT_ENABLED | GRUB_UHCI_REG_PORTSC_RESUME | GRUB_UHCI_REG_PORTSC_RESET - | GRUB_UHCI_REG_PORTSC_SUSPEND + | GRUB_UHCI_REG_PORTSC_SUSPEND, + /* These bits should not be written as 1 unless we really need it */ + GRUB_UHCI_PORTSC_RWC = ((1 << 1) | (1 << 3) | (1 << 11) | (3 << 13)) }; +#define /* UHCI Queue Head. */ struct grub_uhci_qh @@ -578,23 +581,23 @@ grub_uhci_check_transfer (grub_usb_controller_t dev, err = GRUB_USB_ERR_STALL; /* Check if an error related to the data buffer occurred. */ - if (errtd->ctrl_status & (1 << 21)) + else if (errtd->ctrl_status & (1 << 21)) err = GRUB_USB_ERR_DATA; /* Check if a babble error occurred. */ - if (errtd->ctrl_status & (1 << 20)) + else if (errtd->ctrl_status & (1 << 20)) err = GRUB_USB_ERR_BABBLE; /* Check if a NAK occurred. */ - if (errtd->ctrl_status & (1 << 19)) + else if (errtd->ctrl_status & (1 << 19)) err = GRUB_USB_ERR_NAK; /* Check if a timeout occurred. */ - if (errtd->ctrl_status & (1 << 18)) + else if (errtd->ctrl_status & (1 << 18)) err = GRUB_USB_ERR_TIMEOUT; /* Check if a bitstuff error occurred. */ - if (errtd->ctrl_status & (1 << 17)) + else if (errtd->ctrl_status & (1 << 17)) err = GRUB_USB_ERR_BITSTUFF; if (err) @@ -685,7 +688,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, endtime = grub_get_time_ms () + 1000; while ((grub_uhci_readreg16 (u, reg) & (1 << 2))) if (grub_get_time_ms () > endtime) - return grub_error (GRUB_ERR_IO, "UHCI Timed out"); + return grub_error (GRUB_ERR_IO, "UHCI Timed out - disable"); status = grub_uhci_readreg16 (u, reg); grub_dprintf ("uhci", ">3detect=0x%02x\n", status); @@ -693,28 +696,37 @@ grub_uhci_portstatus (grub_usb_controller_t dev, } /* Reset the port. */ - grub_uhci_writereg16 (u, reg, 1 << 9); + status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; + grub_uhci_writereg16 (u, reg, status | (1 << 9)); + grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ /* Wait for the reset to complete. XXX: How long exactly? */ grub_millisleep (50); /* For root hub should be nominaly 50ms */ - status = grub_uhci_readreg16 (u, reg); + status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); - grub_dprintf ("uhci", "reset completed\n"); - grub_millisleep (10); + grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ + + /* Note: some debug prints were removed because they affected reset/enable timing. */ + + grub_millisleep (1); /* Probably not needed at all or only few microsecs. */ + + /* Reset bits Connect & Enable Status Change */ + status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; + grub_uhci_writereg16 (u, reg, status | (1 << 3) | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED); + grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ /* Enable the port. */ - grub_uhci_writereg16 (u, reg, 1 << 2); - grub_millisleep (10); - - grub_dprintf ("uhci", "waiting for the port to be enabled\n"); + status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; + grub_uhci_writereg16 (u, reg, status | (1 << 2)); + grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ endtime = grub_get_time_ms () + 1000; while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2))) if (grub_get_time_ms () > endtime) - return grub_error (GRUB_ERR_IO, "UHCI Timed out"); + return grub_error (GRUB_ERR_IO, "UHCI Timed out - enable"); - /* Reset bit Connect Status Change */ - grub_uhci_writereg16 (u, reg, status | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED); + /* Reset recovery time */ + grub_millisleep (10); /* Read final port status */ status = grub_uhci_readreg16 (u, reg); diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c index 2bd805ef2..e17bf0c9d 100644 --- a/grub-core/bus/usb/usb.c +++ b/grub-core/bus/usb/usb.c @@ -262,7 +262,7 @@ void grub_usb_device_attach (grub_usb_device_t dev) if (dev->config[0].interf[i].attached) continue; - + for (desc = attach_hooks; desc; desc = desc->next) if (interf->class == desc->class && desc->hook (dev, 0, i)) dev->config[0].interf[i].attached = 1; diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 0ddba3255..73d233642 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -179,19 +179,45 @@ attach_root_port (struct grub_usb_hub *hub, int portno, { grub_usb_device_t dev; grub_err_t err; + int total, i; + grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE; + int changed=0; +#if 0 +/* Specification does not say about disabling of port when device + * connected. If disabling is really necessary for some devices, + * delete this #if 0 and related #endif */ /* Disable the port. XXX: Why? */ err = hub->controller->dev->portstatus (hub->controller, portno, 0); if (err) return; +#endif + /* Wait for completion of insertion and stable power (USB spec.) + * Should be at least 100ms, some devices requires more... + * There is also another thing - some devices have worse contacts + * and connected signal is unstable for some time - we should handle + * it - but prevent deadlock in case when device is too faulty... */ + for (total = i = 0; (i < 250) && (total < 2000); i++, total++) + { + grub_millisleep (1); + current_speed = hub->controller->dev->detect_dev + (hub->controller, portno, &changed); + if (current_speed == GRUB_USB_SPEED_NONE) + i = 0; + } + grub_dprintf ("usb", "total=%d\n", total); + if (total >= 2000) + return; /* Enable the port. */ err = hub->controller->dev->portstatus (hub->controller, portno, 1); if (err) return; + hub->controller->dev->pending_reset = grub_get_time_ms () + 5000; /* Enable the port and create a device. */ dev = grub_usb_hub_add_dev (hub->controller, speed); + hub->controller->dev->pending_reset = 0; if (! dev) return; @@ -238,11 +264,14 @@ grub_usb_root_hub (grub_usb_controller_t controller) for (i = 0; i < hub->nports; i++) { grub_usb_speed_t speed; - speed = controller->dev->detect_dev (hub->controller, i, - &changed); + if (!controller->dev->pending_reset) + { + speed = controller->dev->detect_dev (hub->controller, i, + &changed); - if (speed != GRUB_USB_SPEED_NONE) - attach_root_port (hub, i, speed); + if (speed != GRUB_USB_SPEED_NONE) + attach_root_port (hub, i, speed); + } } return GRUB_USB_ERR_NONE; @@ -284,6 +313,7 @@ poll_nonroot_hub (grub_usb_device_t dev) unsigned i; grub_uint8_t changed; grub_size_t actual; + int j, total; if (!dev->hub_transfer) return; @@ -308,6 +338,7 @@ poll_nonroot_hub (grub_usb_device_t dev) for (i = 1; i <= dev->nports; i++) { grub_uint32_t status; + grub_uint32_t current_status = 0; if (!(changed & (1 << i))) continue; @@ -319,7 +350,8 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); - grub_printf ("i = %d, status = %08x\n", i, status); + grub_printf ("dev = 0x%0x, i = %d, status = %08x\n", + (unsigned int) dev, i, status); if (err) continue; @@ -346,7 +378,8 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_REQ_CLEAR_FEATURE, GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0); - if (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED) + if (!dev->controller.dev->pending_reset && + (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)) { grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_CLASS @@ -360,8 +393,36 @@ poll_nonroot_hub (grub_usb_device_t dev) /* Connected and status of connection changed ? */ if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) { - /* A device is actually connected to this port. - * Now do reset of port. */ + /* A device is actually connected to this port. */ + /* Wait for completion of insertion and stable power (USB spec.) + * Should be at least 100ms, some devices requires more... + * There is also another thing - some devices have worse contacts + * and connected signal is unstable for some time - we should handle + * it - but prevent deadlock in case when device is too faulty... */ + for (total = j = 0; (j < 250) && (total < 2000); j++, total++) + { + grub_millisleep (1); + /* Get the port status. */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_GET_STATUS, + 0, i, + sizeof (current_status), + (char *) ¤t_status); + if (err) + { + total = 2000; + break; + } + if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)) + j = 0; + } + grub_dprintf ("usb", "(non-root) total=%d\n", total); + if (total >= 2000) + continue; + + /* Now do reset of port. */ grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_TARGET_OTHER), @@ -369,6 +430,15 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_HUB_FEATURE_PORT_RESET, i, 0, 0); rescan = 1; + /* We cannot reset more than one device at the same time ! + * Resetting more devices together results in very bad + * situation: more than one device has default address 0 + * at the same time !!! + * Additionaly, we cannot perform another reset + * anywhere on the same OHCI controller until + * we will finish addressing of reseted device ! */ + dev->controller.dev->pending_reset = grub_get_time_ms () + 5000; + return; } } @@ -401,6 +471,7 @@ poll_nonroot_hub (grub_usb_device_t dev) /* Add the device and assign a device address to it. */ next_dev = grub_usb_hub_add_dev (&dev->controller, speed); + dev->controller.dev->pending_reset = 0; if (! next_dev) continue; @@ -426,12 +497,21 @@ grub_usb_poll_devices (void) /* No, it should be never changed, it should be constant. */ for (i = 0; i < hub->nports; i++) { - grub_usb_speed_t speed; + grub_usb_speed_t speed = GRUB_USB_SPEED_NONE; int changed = 0; - speed = hub->controller->dev->detect_dev (hub->controller, i, - &changed); - + if (!hub->controller->dev->pending_reset) + { + /* Check for possible timeout */ + if (grub_get_time_ms () > hub->controller->dev->pending_reset) + { + /* Something went wrong, reset device was not + * addressed properly, timeout happened */ + hub->controller->dev->pending_reset = 0; + speed = hub->controller->dev->detect_dev (hub->controller, + i, &changed); + } + } if (changed) { detach_device (hub->devices[i]); diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c index 6b9b1a5b9..afd2eb0a5 100644 --- a/grub-core/bus/usb/usbtrans.c +++ b/grub-core/bus/usb/usbtrans.c @@ -33,10 +33,12 @@ grub_usb_execute_and_wait_transfer (grub_usb_device_t dev, grub_usb_err_t err; grub_uint64_t endtime; - endtime = grub_get_time_ms () + timeout; err = dev->controller.dev->setup_transfer (&dev->controller, transfer); if (err) return err; + /* endtime moved behind setup transfer to prevent false timeouts + * while debugging... */ + endtime = grub_get_time_ms () + timeout; while (1) { err = dev->controller.dev->check_transfer (&dev->controller, transfer, diff --git a/include/grub/usb.h b/include/grub/usb.h index f9cdb2765..6f838e4f9 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -116,6 +116,9 @@ struct grub_usb_controller_dev grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed); + /* Per controller flag - port reset pending, don't do another reset */ + grub_uint64_t pending_reset; + /* The next host controller. */ struct grub_usb_controller_dev *next; }; From 685475e59622cce56cc8a3d2b180241fc90e1d05 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 18 Sep 2010 13:49:39 +0200 Subject: [PATCH 0194/1414] Fix yeeloong compilation --- grub-core/Makefile.am | 1 + grub-core/Makefile.core.def | 3 +++ include/grub/loader.h | 12 ++++++------ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 8b8d993b3..504bd4463 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -137,6 +137,7 @@ 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 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h endif if COND_powerpc_ieee1275 diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c0a796ee0..f4a555ebe 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -173,6 +173,8 @@ kernel = { videoinkernel = video/fb/video_fb.c; videoinkernel = video/video.c; + videoinkernel = commands/boot.c; + extra_dist = kern/i386/realmode.S; extra_dist = kern/i386/pc/lzma_decode.S; extra_dist = kern/mips/cache_flush.S; @@ -424,6 +426,7 @@ module = { name = boot; common = commands/boot.c; i386_pc = lib/i386/pc/biosnum.c; + enable = videomodules; }; module = { diff --git a/include/grub/loader.h b/include/grub/loader.h index 319f3c551..c71e8dd10 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -26,16 +26,16 @@ #include /* Check if a loader is loaded. */ -int grub_loader_is_loaded (void); +int EXPORT_FUNC (grub_loader_is_loaded) (void); /* Set loader functions. NORETURN must be set to true, if BOOT won't return to the original state. */ -void grub_loader_set (grub_err_t (*boot) (void), - grub_err_t (*unload) (void), - int noreturn); +void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void), + grub_err_t (*unload) (void), + int noreturn); /* Unset current loader, if any. */ -void grub_loader_unset (void); +void EXPORT_FUNC (grub_loader_unset) (void); /* Call the boot hook in current loader. This may or may not return, depending on the setting by grub_loader_set. */ @@ -56,7 +56,7 @@ typedef enum { } grub_loader_preboot_hook_prio_t; /* Register a preboot hook. */ -void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret), +void *EXPORT_FUNC(grub_loader_register_preboot_hook) (grub_err_t (*preboot_func) (int noret), grub_err_t (*preboot_rest_func) (void), grub_loader_preboot_hook_prio_t prio); From ab629d0c5de4ea6ba8e50300b271b33c2b945c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Sun, 19 Sep 2010 00:34:25 +0200 Subject: [PATCH 0195/1414] Fix incorrect usb report interpretation --- grub-core/term/usb_keyboard.c | 134 ++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 30 deletions(-) diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c index 6b1485e96..8a34ec552 100644 --- a/grub-core/term/usb_keyboard.c +++ b/grub-core/term/usb_keyboard.c @@ -75,6 +75,10 @@ struct grub_usb_keyboard_data int dead; int last_key; grub_uint64_t repeat_time; + grub_uint8_t current_report[8]; + grub_uint8_t last_report[8]; + int index; + int max_index; }; static int grub_usb_keyboard_getkey (struct grub_term_input *term); @@ -192,6 +196,9 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) data->interfno = interfno; data->endp = endp; + /* Configure device */ + grub_usb_set_configuration (usbdev, configno + 1); + /* Place the device in boot mode. */ grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, USB_HID_SET_PROTOCOL, 0, interfno, 0, 0); @@ -270,17 +277,96 @@ send_leds (struct grub_usb_keyboard_data *termdata) grub_errno = GRUB_ERR_NONE; } +static int +parse_keycode (struct grub_usb_keyboard_data *termdata) +{ + int index = termdata->index; + int i, keycode; + + /* Sanity check */ + if (index < 2) + index = 2; + + for ( ; index < termdata->max_index; index++) + { + keycode = termdata->current_report[index]; + + if (keycode == KEY_NO_KEY + || keycode == KEY_ERR_BUFFER + || keycode == KEY_ERR_POST + || keycode == KEY_ERR_UNDEF) + { + /* Don't parse (rest of) this report */ + termdata->index = 0; + if (keycode != KEY_NO_KEY) + /* Don't replace last report with current faulty report + * in future ! */ + grub_memcpy (termdata->current_report, + termdata->last_report, + sizeof (termdata->report)); + return GRUB_TERM_NO_KEY; + } + + /* Try to find current keycode in last report. */ + for (i = 2; i < 8; i++) + if (keycode == termdata->last_report[i]) + break; + if (i < 8) + /* Keycode is in last report, it means it was not released, + * ignore it. */ + continue; + + if (keycode == KEY_CAPS_LOCK) + { + termdata->mods ^= GRUB_TERM_STATUS_CAPS; + send_leds (termdata); + continue; + } + + if (keycode == KEY_NUM_LOCK) + { + termdata->mods ^= GRUB_TERM_STATUS_NUM; + send_leds (termdata); + continue; + } + + termdata->last_key = grub_term_map_key (keycode, + interpret_status (termdata->current_report[0]) + | termdata->mods); + termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL; + + grub_errno = GRUB_ERR_NONE; + + index++; + if (index >= termdata->max_index) + termdata->index = 0; + else + termdata->index = index; + + return termdata->last_key; + } + + /* All keycodes parsed */ + termdata->index = 0; + return GRUB_TERM_NO_KEY; +} + static int grub_usb_keyboard_getkey (struct grub_term_input *term) { grub_usb_err_t err; struct grub_usb_keyboard_data *termdata = term->data; - grub_uint8_t data[sizeof (termdata->report)]; grub_size_t actual; + int keycode = GRUB_TERM_NO_KEY; if (termdata->dead) return GRUB_TERM_NO_KEY; + if (termdata->index) + keycode = parse_keycode (termdata); + if (keycode != GRUB_TERM_NO_KEY) + return keycode; + /* Poll interrupt pipe. */ err = grub_usb_check_transfer (termdata->transfer, &actual); @@ -296,7 +382,14 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) return GRUB_TERM_NO_KEY; } - grub_memcpy (data, termdata->report, sizeof (data)); + if (!err && (actual >= 3)) + grub_memcpy (termdata->last_report, + termdata->current_report, + sizeof (termdata->report)); + + grub_memcpy (termdata->current_report, + termdata->report, + sizeof (termdata->report)); termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev, termdata->endp->endp_addr, @@ -314,42 +407,23 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" " 0x%02x 0x%02x 0x%02x 0x%02x\n", err, actual, - data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7]); + termdata->current_report[0], termdata->current_report[1], + termdata->current_report[2], termdata->current_report[3], + termdata->current_report[4], termdata->current_report[5], + termdata->current_report[6], termdata->current_report[7]); if (err || actual < 1) return GRUB_TERM_NO_KEY; - termdata->status = data[0]; + termdata->status = termdata->current_report[0]; if (actual < 3) return GRUB_TERM_NO_KEY; - if (data[2] == KEY_NO_KEY || data[2] == KEY_ERR_BUFFER - || data[2] == KEY_ERR_POST || data[2] == KEY_ERR_UNDEF) - return GRUB_TERM_NO_KEY; - - if (data[2] == KEY_CAPS_LOCK) - { - termdata->mods ^= GRUB_TERM_STATUS_CAPS; - send_leds (termdata); - return GRUB_TERM_NO_KEY; - } - - if (data[2] == KEY_NUM_LOCK) - { - termdata->mods ^= GRUB_TERM_STATUS_NUM; - send_leds (termdata); - return GRUB_TERM_NO_KEY; - } - - termdata->last_key = grub_term_map_key (data[2], interpret_status (data[0]) - | termdata->mods); - termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL; - - grub_errno = GRUB_ERR_NONE; - - return termdata->last_key; + termdata->index = 2; /* New data received. */ + termdata->max_index = actual; + + return parse_keycode (termdata); } static int From de0bd1d940653833558937f6b2c27e9a973bceab Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 01:08:25 +0200 Subject: [PATCH 0196/1414] Add missing file of previous commit --- docs/man/grub-mklayout.h2m | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 docs/man/grub-mklayout.h2m diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m new file mode 100644 index 000000000..e0ae9dedb --- /dev/null +++ b/docs/man/grub-mklayout.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mklayout \- generate a GRUB keyboard layout file From eaf41b25921efe7cad32a7a2dc62e38da1df0ac0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 01:15:44 +0200 Subject: [PATCH 0197/1414] * grub-core/commands/i386/cmostest.c (+parse_args): New function. (grub_cmd_cmosclean): Likewise. (GRUB_MOD_INIT): Register command cmosclean. * util/grub-mkconfig.in: Export GRUB_BUTTON_CMOS_CLEAN. * util/grub.d/00_header.in: Handle GRUB_BUTTON_CMOS_CLEAN. --- ChangeLog | 8 ++++++ grub-core/commands/i386/cmostest.c | 43 +++++++++++++++++++++++++----- util/grub-mkconfig.in | 1 + util/grub.d/00_header.in | 6 +++++ 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9eb142be..d1ca11650 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-09-19 Vladimir Serbinenko + + * grub-core/commands/i386/cmostest.c (+parse_args): New function. + (grub_cmd_cmosclean): Likewise. + (GRUB_MOD_INIT): Register command cmosclean. + * util/grub-mkconfig.in: Export GRUB_BUTTON_CMOS_CLEAN. + * util/grub.d/00_header.in: Handle GRUB_BUTTON_CMOS_CLEAN. + 2010-09-18 Carles Pina i Estany 2010-09-18 Aleš Nesrsta 2010-09-18 Vladimir Serbinenko diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index 36c35e6c4..994da11b0 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -22,20 +22,32 @@ #include static grub_err_t -grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) +parse_args (int argc, char *argv[], int *byte, int *bit) { - int byte, bit; char *rest; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); - byte = grub_strtoul (argv[0], &rest, 0); + *byte = grub_strtoul (argv[0], &rest, 0); if (*rest != ':') return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); - bit = grub_strtoul (rest + 1, 0, 0); + *bit = grub_strtoul (rest + 1, 0, 0); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int byte, bit; + grub_err_t err; + + err = parse_args (argc, argv, &byte, &bit); + if (err) + return err; if (grub_cmos_read (byte) & (1 << bit)) return GRUB_ERR_NONE; @@ -43,7 +55,22 @@ grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_TEST_FAILURE, "false"); } -static grub_command_t cmd; +static grub_err_t +grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int byte, bit; + grub_err_t err; + + err = parse_args (argc, argv, &byte, &bit); + if (err) + return err; + + grub_cmos_write (byte, grub_cmos_read (byte) & (~(1 << bit))); + return GRUB_ERR_NONE; +} + +static grub_command_t cmd, cmd_clean; GRUB_MOD_INIT(cmostest) @@ -51,9 +78,13 @@ GRUB_MOD_INIT(cmostest) cmd = grub_register_command ("cmostest", grub_cmd_cmostest, "cmostest BYTE:BIT", "Test bit at BYTE:BIT in CMOS."); + cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean, + "cmosclean BYTE:BIT", + "Clean bit at BYTE:BIT in CMOS."); } GRUB_MOD_FINI(cmostest) { grub_unregister_command (cmd); + grub_unregister_command (cmd_clean); } diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index c3b4c3398..3ba9cd63e 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -245,6 +245,7 @@ export GRUB_DEFAULT \ GRUB_HIDDEN_TIMEOUT_BUTTON \ GRUB_TIMEOUT_BUTTON \ GRUB_BUTTON_CMOS_ADDRESS \ + GRUB_BUTTON_CMOS_CLEAN \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 2f39650e9..9ed3fc3a1 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -247,6 +247,12 @@ else make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" fi +if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ] && [ "x$GRUB_BUTTON_CMOS_CLEAN" = "xyes" ]; then + cat < Date: Sun, 19 Sep 2010 15:36:34 +0200 Subject: [PATCH 0198/1414] * Makefile.util.def: Add forgotten $(LIBINTL) library. --- ChangeLog | 4 ++++ Makefile.util.def | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 86f6f204d..3b390d3f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-19 Yves Blusseau + + * Makefile.util.def: Add forgotten $(LIBINTL) library. + 2010-09-19 BVK Chaitanya * util/grub-mkconfig.in: Check the config script for syntax errors diff --git a/Makefile.util.def b/Makefile.util.def index 36df8ca28..191938efd 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -576,5 +576,5 @@ program = { common = grub-core/lib/i386/pc/vesa_modes_table.c; ldadd = libgrub.a; - ldflags = '$(LIBDEVMAPPER)'; + ldflags = '$(LIBINTL) $(LIBDEVMAPPER)'; }; From d6d94820b58fd96c1d35593c50d68278587c9e53 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 22:03:16 +0200 Subject: [PATCH 0199/1414] * grub-core/Makefile.core.def (legacycfg): Add lib/i386/pc/vesa_modes_table.c on emu. --- ChangeLog | 5 +++++ grub-core/Makefile.core.def | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2988a17df..02f773531 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-19 Vladimir Serbinenko + + * grub-core/Makefile.core.def (legacycfg): Add + lib/i386/pc/vesa_modes_table.c on emu. + 2010-09-19 BVK Chaitanya Reduce number of temporary files generated by build system. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 757240343..efd3fec8d 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1434,6 +1434,7 @@ module = { name = legacycfg; common = commands/legacycfg.c; common = lib/legacy_parse.c; + emu = lib/i386/pc/vesa_modes_table.c; enable = i386_pc; enable = emu; }; From 9af6dac30d32fd7174ea297ffdf90efbb3fefdc0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 22:05:48 +0200 Subject: [PATCH 0200/1414] * grub-core/bus/usb/ohci.c (grub_ohci_cancel_transfer): Use %p to print pointer. * grub-core/bus/usb/uhci.c: Remove empty define. (grub_uhci_check_transfer): Add missing cast. * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Use %p to print pointer. * grub-core/term/usb_keyboard.c (grub_usb_keyboard_getkey): Use PRIuGRUB_SIZE. * include/grub/types.h (PRIuGRUB_SIZE): New definition. --- ChangeLog | 12 ++++++++++++ grub-core/bus/usb/ohci.c | 4 ++-- grub-core/bus/usb/uhci.c | 2 +- grub-core/bus/usb/usbhub.c | 4 ++-- grub-core/term/usb_keyboard.c | 3 ++- include/grub/types.h | 3 +++ 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02f773531..3811381ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-09-19 Vladimir Serbinenko + + * grub-core/bus/usb/ohci.c (grub_ohci_cancel_transfer): Use %p to + print pointer. + * grub-core/bus/usb/uhci.c: Remove empty define. + (grub_uhci_check_transfer): Add missing cast. + * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Use %p to + print pointer. + * grub-core/term/usb_keyboard.c (grub_usb_keyboard_getkey): Use + PRIuGRUB_SIZE. + * include/grub/types.h (PRIuGRUB_SIZE): New definition. + 2010-09-19 Vladimir Serbinenko * grub-core/Makefile.core.def (legacycfg): Add diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index b07e30403..bf5aaa7c0 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -1192,8 +1192,8 @@ grub_ohci_cancel_transfer (grub_usb_controller_t dev, tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys); - grub_dprintf ("ohci", "Cancel: tderr_phys=0x%08x, tderr_virt=0x%08x\n", - cdata->tderr_phys, (unsigned int)tderr_virt); + grub_dprintf ("ohci", "Cancel: tderr_phys=0x%x, tderr_virt=%p\n", + cdata->tderr_phys, tderr_virt); if (tderr_virt) transfer->last_trans = tderr_virt->tr_index; diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 4bf84a8f8..711d87d86 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -550,7 +550,7 @@ grub_uhci_check_transfer (grub_usb_controller_t dev, *actual = 0; - errtd = (grub_uhci_td_t) (cdata->qh->elinkptr & ~0x0f); + errtd = (grub_uhci_td_t) (grub_addr_t) (cdata->qh->elinkptr & ~0x0f); grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n", errtd->ctrl_status, errtd->buffer & (~15), errtd); diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 73d233642..2a5cc3be9 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -350,8 +350,8 @@ poll_nonroot_hub (grub_usb_device_t dev) GRUB_USB_REQ_GET_STATUS, 0, i, sizeof (status), (char *) &status); - grub_printf ("dev = 0x%0x, i = %d, status = %08x\n", - (unsigned int) dev, i, status); + grub_printf ("dev = %p, i = %d, status = %08x\n", + dev, i, status); if (err) continue; diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c index 8a34ec552..30ed8f9c2 100644 --- a/grub-core/term/usb_keyboard.c +++ b/grub-core/term/usb_keyboard.c @@ -404,7 +404,8 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) termdata->last_key = -1; grub_dprintf ("usb_keyboard", - "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" + "err = %d, actual = %" PRIuGRUB_SIZE + " report: 0x%02x 0x%02x 0x%02x 0x%02x" " 0x%02x 0x%02x 0x%02x 0x%02x\n", err, actual, termdata->current_report[0], termdata->current_report[1], diff --git a/include/grub/types.h b/include/grub/types.h index 766eddf07..221fef3c0 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -101,8 +101,10 @@ typedef grub_int64_t grub_ssize_t; # if GRUB_CPU_SIZEOF_LONG == 8 # define PRIxGRUB_SIZE "lx" +# define PRIuGRUB_SIZE "lu" # else # define PRIxGRUB_SIZE "llx" +# define PRIuGRUB_SIZE "llu" # endif #else typedef grub_uint32_t grub_addr_t; @@ -110,6 +112,7 @@ typedef grub_uint32_t grub_size_t; typedef grub_int32_t grub_ssize_t; # define PRIxGRUB_SIZE "x" +# define PRIuGRUB_SIZE "u" #endif #if GRUB_CPU_SIZEOF_LONG == 8 From 39feb0e8f9213cda2ebc3379c17e0fc8472ca909 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 22:09:05 +0200 Subject: [PATCH 0201/1414] * grub-core/term/efi/console.c (efi_codes): Fix GRUB_TERM_KEY_* constants usage. * grub-core/kern/emu/console.c (grub_ncurses_getkey): Fix GRUB_TERM_KEY_* constants usage. * grub-core/kern/emu/misc.c (asprintf): Fix vasprintf usage. --- ChangeLog | 8 ++++++++ grub-core/kern/emu/misc.c | 2 +- grub-core/term/efi/console.c | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3811381ee..8af302bf3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-09-19 Vladimir Serbinenko + + * grub-core/term/efi/console.c (efi_codes): Fix GRUB_TERM_KEY_* + constants usage. + * grub-core/kern/emu/console.c (grub_ncurses_getkey): + Fix GRUB_TERM_KEY_* constants usage. + * grub-core/kern/emu/misc.c (asprintf): Fix vasprintf usage. + 2010-09-19 Vladimir Serbinenko * grub-core/bus/usb/ohci.c (grub_ohci_cancel_transfer): Use %p to diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index c710777ea..c75a2f8f6 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -174,7 +174,7 @@ asprintf (char **buf, const char *fmt, ...) va_list ap; va_start (ap, fmt); - status = vasprintf (*buf, fmt, ap); + status = vasprintf (buf, fmt, ap); va_end (ap); return status; diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index c92f6a75e..4872a9a3f 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -103,9 +103,9 @@ grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), const unsigned efi_codes[] = { - 0, GRUB_TERM_UP, GRUB_TERM_DOWN, GRUB_TERM_RIGHT, - GRUB_TERM_LEFT, GRUB_TERM_HOME, GRUB_TERM_END, GRUB_TERM_KEY_INSERT, - GRUB_TERM_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1, + 0, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_RIGHT, + GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END, GRUB_TERM_KEY_INSERT, + GRUB_TERM_KEY_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, 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, 0, 0, '\e' From 0a6fbf23424f1cde37109f1c0f1d28550c649652 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 22:10:44 +0200 Subject: [PATCH 0202/1414] Add lost include/grub/i386/coreboot/lbio.h --- include/grub/i386/coreboot/lbio.h | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 include/grub/i386/coreboot/lbio.h diff --git a/include/grub/i386/coreboot/lbio.h b/include/grub/i386/coreboot/lbio.h new file mode 100644 index 000000000..aa1853933 --- /dev/null +++ b/include/grub/i386/coreboot/lbio.h @@ -0,0 +1,49 @@ +/* memory.h - describe the memory map */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007,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_MACHINE_LBIO_HEADER +#define _GRUB_MACHINE_LBIO_HEADER 1 + +struct grub_linuxbios_table_header +{ + char signature[4]; + grub_uint32_t size; +}; +typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; + +struct grub_linuxbios_table_item +{ +#define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00 +#define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01 +#define GRUB_LINUXBIOS_MEMBER_LINK 0x11 + grub_uint32_t tag; + grub_uint32_t size; +}; +typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t; + +struct grub_linuxbios_mem_region +{ + grub_uint64_t addr; + grub_uint64_t size; +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + grub_uint32_t type; +}; +typedef struct grub_linuxbios_mem_region *mem_region_t; + +#endif From 5d6015ddf6ab0d8667eeeb900aa1e0adcef98a8e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 22:12:25 +0200 Subject: [PATCH 0203/1414] Add lost part of GRUB_TERM_KEY_* commit --- grub-core/kern/emu/console.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/grub-core/kern/emu/console.c b/grub-core/kern/emu/console.c index 0bf1e05f9..e897160dc 100644 --- a/grub-core/kern/emu/console.c +++ b/grub-core/kern/emu/console.c @@ -115,19 +115,19 @@ grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused))) case ERR: return -1; case KEY_LEFT: - c = GRUB_TERM_LEFT; + c = GRUB_TERM_KEY_LEFT; break; case KEY_RIGHT: - c = GRUB_TERM_RIGHT; + c = GRUB_TERM_KEY_RIGHT; break; case KEY_UP: - c = GRUB_TERM_UP; + c = GRUB_TERM_KEY_UP; break; case KEY_DOWN: - c = GRUB_TERM_DOWN; + c = GRUB_TERM_KEY_DOWN; break; case KEY_IC: @@ -135,30 +135,30 @@ grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused))) break; case KEY_DC: - c = GRUB_TERM_DC; + c = GRUB_TERM_KEY_DC; break; case KEY_BACKSPACE: /* XXX: For some reason ncurses on xterm does not return KEY_BACKSPACE. */ case 127: - c = GRUB_TERM_BACKSPACE; + c = '\b'; break; case KEY_HOME: - c = GRUB_TERM_HOME; + c = GRUB_TERM_KEY_HOME; break; case KEY_END: - c = GRUB_TERM_END; + c = GRUB_TERM_KEY_END; break; case KEY_NPAGE: - c = GRUB_TERM_NPAGE; + c = GRUB_TERM_KEY_NPAGE; break; case KEY_PPAGE: - c = GRUB_TERM_PPAGE; + c = GRUB_TERM_KEY_PPAGE; break; } From 742f9232e385716c20f77e6d0cbc8f28d79b59d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Sep 2010 22:22:43 +0200 Subject: [PATCH 0204/1414] Split config.h for util and core. * acinclude.m4 (HAVE_ASM_USCORE): Transformed into a variable. (ADDR32): Likewise. (DATA32): Likewise. (BSS_START_SYMBOL): Likewise. (END_SYMBOL): Likewise. (NEED_ENABLE_EXECUTE_STACK): Likewise. All users updated. (grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK): Removed. * config.h.in: New file. * configure.ac: Use config-util.h as config define file. Rename MACHINE into GRUB_MACHINE. All users updated. (NEED_REGISTER_FRAME_INFO): Transformed into a variable. All users updated. (NESTED_FUNC_ATTR): Likewise. Substitue new variables. (COND_HAVE_ASM_USCORE): New conditional. * grub-core/Makefile.am (ASM_PREFIX): New variable. (kernel_syms.lst): Use ASM_PREFIX. * grub-core/kern/emu/console.c: Include config-util.h. * grub-core/kern/emu/misc.c: Likewise. * grub-core/kern/emu/mm.c: Likewise. * include/grub/emu/misc.h: Likewise. * include/grub/libgcc.h: Likewise. --- .bzrignore | 3 +- ChangeLog | 27 ++++++++++++++++ acinclude.m4 | 61 +++++++----------------------------- config.h.in | 38 ++++++++++++++++++++++ configure.ac | 31 +++++++++--------- grub-core/Makefile.am | 12 +++++-- grub-core/kern/emu/console.c | 3 ++ grub-core/kern/emu/misc.c | 1 + grub-core/kern/emu/mm.c | 2 ++ grub-core/kern/misc.c | 4 +-- include/grub/emu/misc.h | 3 ++ include/grub/libgcc.h | 3 +- include/grub/misc.h | 4 +-- include/grub/offsets.h | 26 +++++++-------- include/grub/symbol.h | 2 +- 15 files changed, 133 insertions(+), 87 deletions(-) create mode 100644 config.h.in diff --git a/.bzrignore b/.bzrignore index 5c121e652..567261417 100644 --- a/.bzrignore +++ b/.bzrignore @@ -15,7 +15,8 @@ build_env.mk config.cache config.guess config.h -config.h.in +config-util.h +config-util.h.in config.log config.status config.sub diff --git a/ChangeLog b/ChangeLog index 8af302bf3..006f32073 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2010-09-19 Vladimir Serbinenko + + Split config.h for util and core. + + * acinclude.m4 (HAVE_ASM_USCORE): Transformed into a variable. + (ADDR32): Likewise. + (DATA32): Likewise. + (BSS_START_SYMBOL): Likewise. + (END_SYMBOL): Likewise. + (NEED_ENABLE_EXECUTE_STACK): Likewise. All users updated. + (grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK): Removed. + * config.h.in: New file. + * configure.ac: Use config-util.h as config define file. + Rename MACHINE into GRUB_MACHINE. All users updated. + (NEED_REGISTER_FRAME_INFO): Transformed into a variable. All users + updated. + (NESTED_FUNC_ATTR): Likewise. + Substitue new variables. + (COND_HAVE_ASM_USCORE): New conditional. + * grub-core/Makefile.am (ASM_PREFIX): New variable. + (kernel_syms.lst): Use ASM_PREFIX. + * grub-core/kern/emu/console.c: Include config-util.h. + * grub-core/kern/emu/misc.c: Likewise. + * grub-core/kern/emu/mm.c: Likewise. + * include/grub/emu/misc.h: Likewise. + * include/grub/libgcc.h: Likewise. + 2010-09-19 Vladimir Serbinenko * grub-core/term/efi/console.c (efi_codes): Fix GRUB_TERM_KEY_* diff --git a/acinclude.m4 b/acinclude.m4 index e8dd3dc7b..7c38155d4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -58,18 +58,15 @@ else fi if $EGREP '(^|[^_[:alnum]])_func' conftest.s >/dev/null 2>&1; then + HAVE_ASM_USCORE=1 grub_cv_asm_uscore=yes else + HAVE_ASM_USCORE=0 grub_cv_asm_uscore=no fi rm -f conftest*]) -if test "x$grub_cv_asm_uscore" = xyes; then - AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore, - [Define if C symbols get an underscore after compilation]) -fi - AC_MSG_RESULT([$grub_cv_asm_uscore]) ]) @@ -237,44 +234,12 @@ else grub_tmp_data32="data32;" fi -AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32, - [Define it to \"addr32\" or \"addr32;\" to make GAS happy]) -AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32, - [Define it to \"data32\" or \"data32;\" to make GAS happy]) +ADDR32=$grub_tmp_addr32 +DATA32=$grub_tmp_data32 AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])]) -dnl Older versions of GAS require that absolute indirect calls/jumps are -dnl not prefixed with `*', while later versions warn if not prefixed. -AC_DEFUN([grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK], -[AC_REQUIRE([AC_PROG_CC]) -AC_MSG_CHECKING(dnl -[whether an absolute indirect call/jump must not be prefixed with an asterisk]) -AC_CACHE_VAL(grub_cv_i386_asm_absolute_without_asterisk, -[cat > conftest.s <<\EOF - lcall *(offset) -offset: - .long 0 - .word 0 -EOF - -if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then - grub_cv_i386_asm_absolute_without_asterisk=no -else - grub_cv_i386_asm_absolute_without_asterisk=yes -fi - -rm -f conftest*]) - -if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then - AC_DEFINE([ABSOLUTE_WITHOUT_ASTERISK], 1, - [Define it if GAS requires that absolute indirect calls/jumps are not prefixed with an asterisk]) -fi - -AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])]) - - dnl Check what symbol is defined as a bss start symbol. dnl Written by Michael Hohmoth and Yoshinori K. Okuji. AC_DEFUN([grub_CHECK_BSS_START_SYMBOL], @@ -306,14 +271,12 @@ AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol, AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol]) -AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata]) - if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then - AC_DEFINE([BSS_START_SYMBOL], [__bss_start]) + BSS_START_SYMBOL=__bss_start elif test "x$grub_cv_check_edata_symbol" = xyes; then - AC_DEFINE([BSS_START_SYMBOL], [edata]) + BSS_START_SYMBOL=edata elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then - AC_DEFINE([BSS_START_SYMBOL], [_edata]) + BSS_START_SYMBOL=_edata else AC_MSG_ERROR([none of __bss_start, edata or _edata is defined]) fi @@ -341,12 +304,10 @@ AC_CACHE_VAL(grub_cv_check_uscore_end_symbol, AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol]) -AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end]) - if test "x$grub_cv_check_end_symbol" = xyes; then - AC_DEFINE([END_SYMBOL], [end]) + END_SYMBOL=end elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then - AC_DEFINE([END_SYMBOL], [_end]) + END_SYMBOL=_end else AC_MSG_ERROR([neither end nor _end is defined]) fi @@ -369,10 +330,10 @@ else AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) fi if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then - AC_DEFINE([NEED_ENABLE_EXECUTE_STACK], 1, - [Define to 1 if GCC generates calls to __enable_execute_stack()]) + NEED_ENABLE_EXECUTE_STACK=1 AC_MSG_RESULT([yes]) else + NEED_ENABLE_EXECUTE_STACK=0 AC_MSG_RESULT([no]) fi rm -f conftest* diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..4ac9ab5d6 --- /dev/null +++ b/config.h.in @@ -0,0 +1,38 @@ +#if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) +#include +#define NESTED_FUNC_ATTR +#else +/* Define if C symbols get an underscore after compilation. */ +#define HAVE_ASM_USCORE @HAVE_ASM_USCORE@ +/* Define it to \"addr32\" or \"addr32;\" to make GAS happy. */ +#define ADDR32 @ADDR32@ +/* Define it to \"data32\" or \"data32;\" to make GAS happy. */ +#define DATA32 @DATA32@ +/* Define it to one of __bss_start, edata and _edata. */ +#define BSS_START_SYMBOL @BSS_START_SYMBOL@ +/* Define it to either end or _end. */ +#define END_SYMBOL @END_SYMBOL@ +/* Name of package. */ +#define PACKAGE "@PACKAGE@" +/* Version number of package. */ +#define VERSION "@VERSION@" +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "@PACKAGE_STRING@" +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@PACKAGE_VERSION@" +/* Define to the full name of this package. */ +#define PACKAGE_NAME "@PACKAGE_NAME@" +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" +/* Define to 1 if GCC generates calls to __enable_execute_stack(). */ +#define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@ +/* Define to 1 if GCC generates calls to __register_frame_info(). */ +#define NEED_REGISTER_FRAME_INFO @NEED_REGISTER_FRAME_INFO@ + +#if defined(__i386__) +#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) +#else +#define NESTED_FUNC_ATTR +#endif + +#endif diff --git a/configure.ac b/configure.ac index 57df640b8..75fa43d53 100644 --- a/configure.ac +++ b/configure.ac @@ -44,7 +44,7 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE() AC_PREREQ(2.60) AC_CONFIG_SRCDIR([include/grub/dl.h]) -AC_CONFIG_HEADER([config.h]) +AC_CONFIG_HEADER([config-util.h]) # Program name transformations AC_ARG_PROGRAM @@ -164,7 +164,7 @@ case "$target_cpu" in mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;; esac -machine_CPPFLAGS="$machine_CPPFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" HOST_CPPFLAGS="$HOST_CPPFLAGS $machine_CPPFLAGS" TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS" @@ -431,10 +431,9 @@ AC_MSG_CHECKING([for command to convert module to ELF format]) case "${host_os}" in cygwin) TARGET_OBJ2ELF='$(grub_utildir)/grub-pe2elf'; # FIXME: put proper test here - AC_DEFINE([NEED_REGISTER_FRAME_INFO], 1, - [Define to 1 if GCC generates calls to __register_frame_info()]) + NEED_REGISTER_FRAME_INFO=1 ;; - *) ;; + *) NEED_REGISTER_FRAME_INFO=0 ;; esac AC_MSG_RESULT([$TARGET_OBJ2ELF]) @@ -590,17 +589,8 @@ if test "x$target_cpu" = xi386; then CFLAGS="$TARGET_CFLAGS" grub_I386_ASM_PREFIX_REQUIREMENT grub_I386_ASM_ADDR32 - grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK -else - AC_DEFINE([NESTED_FUNC_ATTR], [], [Catch gcc bug]) fi -AH_BOTTOM([#if defined(__i386__) && !defined(GRUB_UTIL) -#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) -#else -#define NESTED_FUNC_ATTR -#endif]) - AC_ARG_ENABLE([efiemu], [AS_HELP_STRING([--enable-efiemu], [build and install the efiemu runtimes (default=guessed)])]) @@ -872,6 +862,16 @@ AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu], AS_IF([test x$TARGET_APPLE_CC = x1], [AC_SUBST([USE_APPLE_CC_FIXES], yes)]) +AC_SUBST(HAVE_ASM_USCORE) +AC_SUBST(ADDR32) +AC_SUBST(DATA32) +AC_SUBST(BSS_START_SYMBOL) +AC_SUBST(END_SYMBOL) +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) +AC_SUBST(NEED_ENABLE_EXECUTE_STACK) +AC_SUBST(NEED_REGISTER_FRAME_INFO) + # # Automake conditionals # @@ -906,6 +906,8 @@ AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) +AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) + # Output files. grub_CHECK_LINK_DIR if test x"$link_dir" = xyes ; then @@ -929,6 +931,7 @@ AC_CONFIG_FILES([po/Makefile]) AC_CONFIG_FILES([docs/Makefile]) AC_CONFIG_FILES([util/bash-completion.d/Makefile]) AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) +AC_CONFIG_FILES([config.h]) AC_OUTPUT [ diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 0c47d78a5..addc83417 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -173,13 +173,19 @@ symlist.c: symlist.h gensymlist.sh CLEANFILES += symlist.c BUILT_SOURCES += symlist.c +if COND_HAVE_ASM_USCORE +ASM_PREFIX=1 +else +ASM_PREFIX= +endif + noinst_DATA += kernel_syms.lst + kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input - if grep "^#define HAVE_ASM_USCORE" $(top_builddir)/config.h; then u="_"; else u=""; fi; \ cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined '"$$u"'kernel \1/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined '"$$u"' kernel \1/;p;}' \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined '"$(ASM_PREFIX)"'kernel \1/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined '"$(ASM_PREFIX)"' kernel \1/;p;}' \ | sort -u >$@ rm -f kernel_syms.input CLEANFILES += kernel_syms.lst diff --git a/grub-core/kern/emu/console.c b/grub-core/kern/emu/console.c index e897160dc..7fd1fc0c9 100644 --- a/grub-core/kern/emu/console.c +++ b/grub-core/kern/emu/console.c @@ -18,6 +18,7 @@ */ #include +#include /* For compatibility. */ #ifndef A_NORMAL @@ -37,6 +38,8 @@ # include #elif defined(HAVE_CURSES_H) # include +#else +#error What the hell? #endif static int grub_console_attr = A_NORMAL; diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index c75a2f8f6..4630d335d 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -16,6 +16,7 @@ * along with GRUB. If not, see . */ +#include #include #include diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c index 0e9e9f3a8..6a70efb4c 100644 --- a/grub-core/kern/emu/mm.c +++ b/grub-core/kern/emu/mm.c @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 6e0eaf6a4..37ce8decd 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -999,7 +999,7 @@ grub_abort (void) void abort (void) __attribute__ ((alias ("grub_abort"))); #endif -#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU) +#if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU) /* Some gcc versions generate a call to this function in trampolines for nested functions. */ void __enable_execute_stack (void *addr __attribute__ ((unused))) @@ -1007,7 +1007,7 @@ void __enable_execute_stack (void *addr __attribute__ ((unused))) } #endif -#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL) +#if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL) void __register_frame_info (void) { } diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 972bc4efc..51cad596a 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -19,6 +19,9 @@ #ifndef GRUB_EMU_MISC_H #define GRUB_EMU_MISC_H 1 +#include +#include + #include #include #include diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h index d0adae8c1..8c4c19d8c 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -16,7 +16,8 @@ * along with GRUB. If not, see . */ -#include +/* We need to include config-util.h.in for HAVE_*. */ +#include /* On x86 these functions aren't really needed. Save some space. */ #if !defined (__i386__) && !defined (__x86_64__) diff --git a/include/grub/misc.h b/include/grub/misc.h index 774dc5843..27f15e44a 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -270,11 +270,11 @@ void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r); -#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) +#if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) void EXPORT_FUNC(__enable_execute_stack) (void *addr); #endif -#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL) +#if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL) void EXPORT_FUNC (__register_frame_info) (void); void EXPORT_FUNC (__deregister_frame_info) (void); #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 47eb6c9bd..91a41ef95 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -150,22 +150,22 @@ rewrite grub-mkimage to generate valid ELF files. */ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 -#ifdef MACHINE +#ifdef GRUB_MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) -#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_ALIGN) -#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_GAP) -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) +#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_ALIGN) +#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_GAP) +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _TOTAL_MODULE_SIZE) +#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_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) -#define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX_END) -#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) -#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_BSD_PART) -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_DOS_PART) +#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) +#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) +#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) +#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _RAW_SIZE) +#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_BSD_PART) +#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_DOS_PART) #endif #ifndef ASM_FILE diff --git a/include/grub/symbol.h b/include/grub/symbol.h index 63ed19436..c6adb7ee3 100644 --- a/include/grub/symbol.h +++ b/include/grub/symbol.h @@ -25,7 +25,7 @@ #define LOCAL(sym) L_ ## sym /* Add an underscore to a C symbol in assembler code if needed. */ -#ifdef HAVE_ASM_USCORE +#if HAVE_ASM_USCORE # define EXT_C(sym) _ ## sym #else # define EXT_C(sym) sym From e0337366d11bf30dd3c077b8dc97760558a0ce1c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 00:06:45 +0200 Subject: [PATCH 0205/1414] * grub-core/boot/i386/pc/boot.S: Ignore %dl if it's not in a sane range. --- ChangeLog | 4 ++++ grub-core/boot/i386/pc/boot.S | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 006f32073..1bde1bc8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-20 Vladimir Serbinenko + + * grub-core/boot/i386/pc/boot.S: Ignore %dl if it's not in a sane range. + 2010-09-19 Vladimir Serbinenko Split config.h for util and core. diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index 6b16a913a..320918566 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -112,12 +112,16 @@ LOCAL(after_BPB): */ . = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK boot_drive_check: - jmp 1f /* grub-setup may overwrite this jump */ + jmp 3f /* grub-setup may overwrite this jump */ testb $0x80, %dl - jnz 1f + jz 2f +3: + /* Ignore %dl different from 0-0x0f and 0x80-0x8f. */ + testb $0x70, %dl + jz 1f +2: movb $0x80, %dl 1: - /* * ljmp to the next instruction because some bogus BIOSes * jump to 07C0:0000 instead of 0000:7C00. From c55f50180dad2935a67392662c62bcbf052e727d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 20 Sep 2010 01:40:58 +0200 Subject: [PATCH 0206/1414] Remove crc.mod and move crc command to hashsum.mod. Remove lib/crc.c - users updated to use gcrypt implementation. * grub-core/commands/crc.c: Removed. * grub-core/Makefile.core.def (crc): Module removed. * grub-core/commands/hashsum.c (aliases[]): Add crc alias. * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Register crc command. * grub-core/commands/hashsum.c (GRUB_MOD_FINI): Unregister crc command. * grub-core/lib/crc.c: Removed. * include/grub/lib/crc.h: Removed. * Makefile.util.def (crc): Remove lib/crc.c * grub-core/Makefile.core.def (libgrub.a): Remove grub-core/lib/crc.c. * util/grub-fstest.c (cmd_crd): Use libgcrypt crc implementation. * Makefile.util.def (libgrub.a): Add grub-core/lib/libgcrypt-grub/cipher/crc.c. * Makefile.util.def (grub-fstest): Add CFLAGS_GCRY to cflags. * Makefile.util.def (grub-fstest): Add CPPFLAGS_GCRY to cppflags. * grub-core/efiemu/prepare.c (grub_efiemu_crc): Use libgcrypt crc implementation. --- ChangeLog | 20 ++++++++++ Makefile.util.def | 4 +- grub-core/Makefile.core.def | 6 --- grub-core/commands/crc.c | 72 ---------------------------------- grub-core/commands/hashsum.c | 10 ++++- grub-core/efiemu/prepare.c | 25 +++++++----- grub-core/lib/crc.c | 75 ------------------------------------ include/grub/lib/crc.h | 25 ------------ util/grub-fstest.c | 11 ++++-- 9 files changed, 55 insertions(+), 193 deletions(-) delete mode 100644 grub-core/commands/crc.c delete mode 100644 grub-core/lib/crc.c delete mode 100644 include/grub/lib/crc.h diff --git a/ChangeLog b/ChangeLog index 1bde1bc8f..0207c9d2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-09-20 Szymon Janc + + Remove crc.mod and move crc command to hashsum.mod. + Remove lib/crc.c - users updated to use gcrypt implementation. + + * grub-core/commands/crc.c: Removed. + * grub-core/Makefile.core.def (crc): Module removed. + * grub-core/commands/hashsum.c (aliases[]): Add crc alias. + * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Register crc command. + * grub-core/commands/hashsum.c (GRUB_MOD_FINI): Unregister crc command. + * grub-core/lib/crc.c: Removed. + * include/grub/lib/crc.h: Removed. + * Makefile.util.def (crc): Remove lib/crc.c + * grub-core/Makefile.core.def (libgrub.a): Remove grub-core/lib/crc.c. + * util/grub-fstest.c (cmd_crd): Use libgcrypt crc implementation. + * Makefile.util.def (libgrub.a): Add grub-core/lib/libgcrypt-grub/cipher/crc.c. + * Makefile.util.def (grub-fstest): Add CFLAGS_GCRY to cflags. + * Makefile.util.def (grub-fstest): Add CPPFLAGS_GCRY to cppflags. + * grub-core/efiemu/prepare.c (grub_efiemu_crc): Use libgcrypt crc implementation. + 2010-09-20 Vladimir Serbinenko * grub-core/boot/i386/pc/boot.S: Ignore %dl if it's not in a sane range. diff --git a/Makefile.util.def b/Makefile.util.def index 191938efd..34b3648b1 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -72,11 +72,11 @@ library = { common = grub-core/kern/list.c; common = grub-core/kern/partition.c; common = grub-core/lib/arg.c; - common = grub-core/lib/crc.c; common = grub-core/lib/crypto.c; common = grub-core/lib/envblk.c; common = grub-core/lib/hexdump.c; common = grub-core/lib/libgcrypt-grub/cipher/sha512.c; + common = grub-core/lib/libgcrypt-grub/cipher/crc.c; common = grub-core/lib/LzFind.c; common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/pbkdf2.c; @@ -186,6 +186,8 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + cflags = '$(CFLAGS_GCRY)'; + cppflags = '$(CPPFLAGS_GCRY)'; }; program = { diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index efd3fec8d..8e6b82ca5 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -486,12 +486,6 @@ module = { enable = x86; }; -module = { - name = crc; - common = commands/crc.c; - common = lib/crc.c; -}; - module = { name = date; common = commands/date.c; diff --git a/grub-core/commands/crc.c b/grub-core/commands/crc.c deleted file mode 100644 index f165e1aaf..000000000 --- a/grub-core/commands/crc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* crc.c - command to calculate the crc32 checksum of a file */ -/* - * GRUB -- GRand Unified Bootloader - * 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 - * 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 - -static grub_err_t -grub_cmd_crc (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) - -{ - grub_file_t file; - char buf[GRUB_DISK_SECTOR_SIZE]; - grub_ssize_t size; - grub_uint32_t crc; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - - grub_file_filter_disable_compression (); - file = grub_file_open (args[0]); - if (! file) - return 0; - - crc = 0; - while ((size = grub_file_read (file, buf, sizeof (buf))) > 0) - crc = grub_getcrc32 (crc, buf, size); - - if (grub_errno) - goto fail; - - grub_printf ("%08x\n", crc); - - fail: - grub_file_close (file); - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(crc) -{ - cmd = grub_register_command ("crc", grub_cmd_crc, - N_("FILE"), - N_("Calculate the crc32 checksum of a file.")); -} - -GRUB_MOD_FINI(crc) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index e926c0435..df297b585 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -41,6 +41,7 @@ struct { const char *name; const char *hashname; } aliases[] = {"sha256sum", "sha256"}, {"sha512sum", "sha512"}, {"md5sum", "md5"}, + {"crc", "crc32"}, }; static inline int @@ -248,7 +249,7 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt, return GRUB_ERR_NONE; } -static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512; +static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512 , cmd_crc; GRUB_MOD_INIT(hashsum) { @@ -272,6 +273,12 @@ GRUB_MOD_INIT(hashsum) "[FILE1 [FILE2 ...]]"), N_("Compute or check hash checksum."), options); + + cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); } GRUB_MOD_FINI(hashsum) @@ -280,4 +287,5 @@ GRUB_MOD_FINI(hashsum) grub_unregister_extcmd (cmd_md5); grub_unregister_extcmd (cmd_sha256); grub_unregister_extcmd (cmd_sha512); + grub_unregister_extcmd (cmd_crc); } diff --git a/grub-core/efiemu/prepare.c b/grub-core/efiemu/prepare.c index 620260049..171e092c9 100644 --- a/grub-core/efiemu/prepare.c +++ b/grub-core/efiemu/prepare.c @@ -20,9 +20,9 @@ #include #include -#include +#include #include -#include +#include grub_err_t SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, @@ -123,6 +123,7 @@ SUFFIX (grub_efiemu_crc) (void) int handle; grub_off_t off; struct SUFFIX (grub_efiemu_runtime_services) *runtime_services; + grub_uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; /* compute CRC32 of runtime_services */ err = grub_efiemu_resolve_symbol ("efiemu_runtime_services", @@ -132,19 +133,25 @@ SUFFIX (grub_efiemu_crc) (void) runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *) ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); - runtime_services->hdr.crc32 = 0; - runtime_services->hdr.crc32 = grub_getcrc32 - (0, runtime_services, runtime_services->hdr.header_size); + + GRUB_MD_CRC32->init(crc32_context); + GRUB_MD_CRC32->write(crc32_context, runtime_services, runtime_services->hdr.header_size); + GRUB_MD_CRC32->final(crc32_context); + + runtime_services->hdr.crc32 = + grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context)); err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off); if (err) return err; /* compute CRC32 of system table */ - SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0; - SUFFIX (grub_efiemu_system_table)->hdr.crc32 - = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table), - SUFFIX (grub_efiemu_system_table)->hdr.header_size); + GRUB_MD_CRC32->init(crc32_context); + GRUB_MD_CRC32->write(crc32_context, SUFFIX (grub_efiemu_system_table), + SUFFIX (grub_efiemu_system_table)->hdr.header_size); + GRUB_MD_CRC32->final(crc32_context); + SUFFIX (grub_efiemu_system_table)->hdr.crc32 = + grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context)); grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n", SUFFIX (grub_efiemu_system_table), runtime_services); diff --git a/grub-core/lib/crc.c b/grub-core/lib/crc.c deleted file mode 100644 index bc0d8aa8d..000000000 --- a/grub-core/lib/crc.c +++ /dev/null @@ -1,75 +0,0 @@ -/* crc.c - crc function */ -/* - * 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 - -static grub_uint32_t crc32_table [256]; - -static void -init_crc32_table (void) -{ - auto grub_uint32_t reflect (grub_uint32_t ref, int len); - grub_uint32_t reflect (grub_uint32_t ref, int len) - { - grub_uint32_t result = 0; - int i; - - for (i = 1; i <= len; i++) - { - if (ref & 1) - result |= 1 << (len - i); - ref >>= 1; - } - - return result; - } - - grub_uint32_t polynomial = 0x04c11db7; - int i, j; - - for(i = 0; i < 256; i++) - { - crc32_table[i] = reflect(i, 8) << 24; - for (j = 0; j < 8; j++) - crc32_table[i] = (crc32_table[i] << 1) ^ - (crc32_table[i] & (1 << 31) ? polynomial : 0); - crc32_table[i] = reflect(crc32_table[i], 32); - } -} - -grub_uint32_t -grub_getcrc32 (grub_uint32_t crc, void *buf, int size) -{ - int i; - grub_uint8_t *data = buf; - - if (! crc32_table[1]) - init_crc32_table (); - - crc^= 0xffffffff; - - for (i = 0; i < size; i++) - { - crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data]; - data++; - } - - return crc ^ 0xffffffff; -} diff --git a/include/grub/lib/crc.h b/include/grub/lib/crc.h deleted file mode 100644 index ff7284dc8..000000000 --- a/include/grub/lib/crc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* crc.h - prototypes for crc */ -/* - * 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_CRC_H -#define GRUB_CRC_H 1 - -grub_uint32_t grub_getcrc32 (grub_uint32_t crc, void *buf, int size); - -#endif /* ! GRUB_CRC_H */ diff --git a/util/grub-fstest.c b/util/grub-fstest.c index eb7981d3a..bcc9ea942 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -239,19 +239,22 @@ cmd_hex (char *pathname) static void cmd_crc (char *pathname) { - grub_uint32_t crc = 0; + grub_uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + GRUB_MD_CRC32->init(crc32_context); auto int crc_hook (grub_off_t ofs, char *buf, int len); int crc_hook (grub_off_t ofs, char *buf, int len) { (void) ofs; - crc = grub_getcrc32 (crc, buf, len); + GRUB_MD_CRC32->write(crc32_context, buf, len); return 0; } read_file (pathname, crc_hook); - printf ("%08x\n", crc); + GRUB_MD_CRC32->final(crc32_context); + printf ("%08x\n", + grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context))); } static void From 79c93b429ee87b66ec3b8f0850b930520c804882 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 20 Sep 2010 13:51:16 +0530 Subject: [PATCH 0207/1414] echo test case --- Makefile.util.def | 6 ++++++ tests/grub_cmd_echo.in | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/grub_cmd_echo.in diff --git a/Makefile.util.def b/Makefile.util.def index 34b3648b1..c19f66115 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -557,6 +557,12 @@ script = { common = tests/partmap_test.in; }; +script = { + testcase; + name = grub_cmd_echo; + common = tests/grub_cmd_echo.in; +}; + program = { testcase; name = example_unit_test; diff --git a/tests/grub_cmd_echo.in b/tests/grub_cmd_echo.in new file mode 100644 index 000000000..6ac33f55e --- /dev/null +++ b/tests/grub_cmd_echo.in @@ -0,0 +1,33 @@ +#! @builddir@/grub-shell-tester +# +# 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 . + +echo +echo -n + +echo foo +echo foo bar + +echo -n foo + +echo -e "foo\nbar" + +echo -n -e "foo\nbar" + +echo foo -n +echo foo -n -e + +echo ------- From e511c9f59166e5c3a85acfbd3d05d0bdf1f9b300 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Mon, 20 Sep 2010 11:49:57 +0200 Subject: [PATCH 0208/1414] * .bzrignore: Add grub-kbdcomp, grub-menulst2cfg, *.marker, grub-core/genmod.sh and grub-core/gensyminfo.sh --- .bzrignore | 5 +++++ ChangeLog | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/.bzrignore b/.bzrignore index 567261417..d4817ad8c 100644 --- a/.bzrignore +++ b/.bzrignore @@ -40,7 +40,9 @@ grub-fstest grub_fstest_init.c grub_fstest_init.h grub-install +grub-kbdcomp grub-macho2img +grub-menulst2cfg grub-mk* grub-pbkdf2 grub-pe2elf @@ -69,6 +71,7 @@ install-sh lib/libgcrypt-grub libgrub_a_init.c *.lst +*.marker Makefile *.mod mod-*.c @@ -103,6 +106,8 @@ Makefile.util.am grub-core/Makefile.core.am grub-core/Makefile.gcry.am grub-core/Makefile.gcry.def +grub-core/genmod.sh +grub-core/gensyminfo.sh grub-core/*.module grub-core/*.pp util/bash-completion.d/grub diff --git a/ChangeLog b/ChangeLog index 92a46a86e..d27ebad1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-20 Yves Blusseau + + * .bzrignore: Add grub-kbdcomp, grub-menulst2cfg, *.marker, + grub-core/genmod.sh and grub-core/gensyminfo.sh + 2010-09-20 BVK Chaitanya Add a test for echo command options. From 15c69261265317f63170bb5e7d8c38843056737c Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Mon, 20 Sep 2010 12:35:33 +0200 Subject: [PATCH 0209/1414] Use gnulib-tool to create gnulib source files. * Add gnulib files generated by gnulib-tool in build-aux, m4 and grub-core/gnulib directories * .bzignore: Add **/.deps and autogenerated gnulib files * configure.ac: Assign auxiliary directory to build-aux, add invocation of gnulib macros, add grub-core/gnulib/Makefile * Makefile.am: Add gnulib directory in SUBDIRS (removing unnecessary .), include m4 directory to aclocal. * Makefile.util.def: Remove direct compilation of gnulib source files and use the new grub-core/gnulib/libgnu.a. * build-aux/config.rpath: move config.rpath from top directory to build-aux * conf/Makefile.common: Remove the macro _GL_UNUSED already defined in gnulib headers * conf/Makefile.extra-dist: Add m4/gnulib-cache.m4 * grub-core/Makefile.core.def: Remove unnecessary extra_dist * grub-core/lib/posix_wrap/localcharset.h (locale_charset): Update header. * grub-core/lib/posix_wrap/langinfo.h (nl_langinfo): Return static string. --- .bzrignore | 18 + ChangeLog | 24 + Makefile.am | 4 +- Makefile.util.def | 28 +- build-aux/arg-nonnull.h | 26 + build-aux/c++defs.h | 271 + config.rpath => build-aux/config.rpath | 132 +- build-aux/warn-on-use.h | 109 + conf/Makefile.common | 2 +- conf/Makefile.extra-dist | 2 + configure.ac | 7 + grub-core/Makefile.core.def | 6 - grub-core/gnulib/Makefile.am | 1336 ++++ grub-core/gnulib/alloca.c | 489 ++ grub-core/gnulib/{alloca.h => alloca.in.h} | 2 +- grub-core/gnulib/asnprintf.c | 35 + grub-core/gnulib/basename.c | 58 - grub-core/gnulib/{dirname.c => btowc.c} | 35 +- grub-core/gnulib/config.charset | 683 ++ grub-core/gnulib/errno.in.h | 160 + grub-core/gnulib/float+.h | 148 + grub-core/gnulib/float.in.h | 62 + grub-core/gnulib/fnmatch.c | 2 +- grub-core/gnulib/{fnmatch.h => fnmatch.in.h} | 37 +- grub-core/gnulib/fnmatch_loop.c | 2 +- grub-core/gnulib/getdelim.c | 2 +- grub-core/gnulib/getline.c | 3 +- grub-core/gnulib/{getopt.h => getopt.in.h} | 70 +- grub-core/gnulib/gettext.h | 2 +- grub-core/gnulib/intprops.h | 83 + grub-core/gnulib/langinfo.in.h | 173 + grub-core/gnulib/localcharset.c | 548 ++ grub-core/gnulib/localcharset.h | 41 + grub-core/gnulib/malloc.c | 60 + grub-core/gnulib/mbrtowc.c | 386 ++ grub-core/gnulib/mbsinit.c | 47 + grub-core/gnulib/mbsrtowcs-state.c | 37 + grub-core/gnulib/mbsrtowcs.c | 136 + grub-core/gnulib/memchr.c | 172 + grub-core/gnulib/memchr.valgrind | 14 + grub-core/gnulib/mempcpy.c | 29 + grub-core/gnulib/nl_langinfo.c | 270 + grub-core/gnulib/printf-args.c | 188 + grub-core/gnulib/printf-args.h | 155 + grub-core/gnulib/printf-parse.c | 627 ++ grub-core/gnulib/printf-parse.h | 180 + grub-core/gnulib/rawmemchr.c | 136 + grub-core/gnulib/rawmemchr.valgrind | 12 + grub-core/gnulib/realloc.c | 91 + grub-core/gnulib/ref-add.sin | 30 + grub-core/gnulib/ref-del.sin | 25 + grub-core/gnulib/regcomp.c | 2 +- grub-core/gnulib/regex.c | 2 +- grub-core/gnulib/regex.h | 2 +- grub-core/gnulib/regex_internal.c | 2 +- grub-core/gnulib/regex_internal.h | 2 +- grub-core/gnulib/regexec.c | 2 +- grub-core/gnulib/size_max.h | 31 + grub-core/gnulib/sleep.c | 75 + grub-core/gnulib/stdbool.in.h | 122 + grub-core/gnulib/stddef.in.h | 86 + grub-core/gnulib/stdint.in.h | 568 ++ grub-core/gnulib/stdio-write.c | 148 + grub-core/gnulib/stdio.in.h | 1071 ++++ grub-core/gnulib/stdlib.in.h | 715 +++ grub-core/gnulib/strcasecmp.c | 63 + grub-core/gnulib/strchrnul.c | 142 + grub-core/gnulib/strchrnul.valgrind | 12 + grub-core/gnulib/streq.h | 176 + grub-core/gnulib/strerror.c | 350 ++ grub-core/gnulib/string.in.h | 945 +++ grub-core/gnulib/strings.in.h | 93 + grub-core/gnulib/strncasecmp.c | 63 + grub-core/gnulib/strndup.c | 37 + grub-core/gnulib/strnlen.c | 31 + .../gnulib/{argp-version-etc.c => strnlen1.c} | 35 +- .../gnulib/{argp-version-etc.h => strnlen1.h} | 27 +- grub-core/gnulib/sys_wait.in.h | 106 + grub-core/gnulib/sysexits.in.h | 71 + grub-core/gnulib/unistd.in.h | 1326 ++++ grub-core/gnulib/vasnprintf.c | 5567 +++++++++++++++++ grub-core/gnulib/vasnprintf.h | 80 + grub-core/gnulib/verify.h | 163 + grub-core/gnulib/vsnprintf.c | 71 + grub-core/gnulib/wchar.in.h | 428 ++ grub-core/gnulib/wcrtomb.c | 53 + grub-core/gnulib/wctype.in.h | 392 ++ grub-core/gnulib/xsize.h | 108 + grub-core/lib/posix_wrap/langinfo.h | 2 +- grub-core/lib/posix_wrap/localcharset.h | 2 +- m4/00gnulib.m4 | 30 + m4/alloca.m4 | 47 + m4/argp.m4 | 65 + m4/asm-underscore.m4 | 48 + m4/btowc.m4 | 109 + m4/codeset.m4 | 23 + m4/dirname.m4 | 26 + m4/dos.m4 | 71 + m4/double-slash-root.m4 | 38 + m4/errno_h.m4 | 115 + m4/error.m4 | 39 + m4/extensions.m4 | 118 + m4/fcntl-o.m4 | 85 + m4/float_h.m4 | 19 + m4/fnmatch.m4 | 121 + m4/getdelim.m4 | 90 + m4/getline.m4 | 97 + m4/getopt.m4 | 318 + m4/glibc21.m4 | 30 + m4/gnulib-cache.m4 | 41 + m4/gnulib-common.m4 | 201 + m4/gnulib-comp.m4 | 573 ++ m4/gnulib-tool.m4 | 57 + m4/include_next.m4 | 192 + m4/intmax_t.m4 | 67 + m4/inttypes_h.m4 | 29 + m4/langinfo_h.m4 | 105 + m4/localcharset.m4 | 17 + m4/locale-fr.m4 | 185 + m4/locale-ja.m4 | 107 + m4/locale-zh.m4 | 92 + m4/longlong.m4 | 106 + m4/malloc.m4 | 66 + m4/mbrtowc.m4 | 393 ++ m4/mbsinit.m4 | 32 + m4/mbsrtowcs.m4 | 123 + m4/mbstate_t.m4 | 34 + m4/memchr.m4 | 87 + m4/mempcpy.m4 | 27 + m4/mmap-anon.m4 | 59 + m4/multiarch.m4 | 65 + m4/nl_langinfo.m4 | 25 + m4/printf.m4 | 1462 +++++ m4/rawmemchr.m4 | 21 + m4/realloc.m4 | 44 + m4/regex.m4 | 235 + m4/size_max.m4 | 79 + m4/sleep.m4 | 49 + m4/ssize_t.m4 | 23 + m4/stdbool.m4 | 103 + m4/stddef_h.m4 | 45 + m4/stdint.m4 | 472 ++ m4/stdint_h.m4 | 27 + m4/stdio_h.m4 | 159 + m4/stdlib_h.m4 | 112 + m4/strcase.m4 | 44 + m4/strchrnul.m4 | 21 + m4/strerror.m4 | 68 + m4/string_h.m4 | 112 + m4/strings_h.m4 | 39 + m4/strndup.m4 | 53 + m4/strnlen.m4 | 32 + m4/sys_wait_h.m4 | 25 + m4/sysexits.m4 | 43 + m4/unistd_h.m4 | 159 + m4/vasnprintf.m4 | 288 + m4/vsnprintf.m4 | 40 + m4/warn-on-use.m4 | 45 + m4/wchar_h.m4 | 152 + m4/wchar_t.m4 | 24 + m4/wcrtomb.m4 | 94 + m4/wctype_h.m4 | 85 + m4/wint_t.m4 | 32 + m4/xsize.m4 | 13 + 164 files changed, 28462 insertions(+), 276 deletions(-) create mode 100644 build-aux/arg-nonnull.h create mode 100644 build-aux/c++defs.h rename config.rpath => build-aux/config.rpath (81%) create mode 100644 build-aux/warn-on-use.h create mode 100644 grub-core/gnulib/Makefile.am create mode 100644 grub-core/gnulib/alloca.c rename grub-core/gnulib/{alloca.h => alloca.in.h} (96%) create mode 100644 grub-core/gnulib/asnprintf.c delete mode 100644 grub-core/gnulib/basename.c rename grub-core/gnulib/{dirname.c => btowc.c} (57%) create mode 100644 grub-core/gnulib/config.charset create mode 100644 grub-core/gnulib/errno.in.h create mode 100644 grub-core/gnulib/float+.h create mode 100644 grub-core/gnulib/float.in.h rename grub-core/gnulib/{fnmatch.h => fnmatch.in.h} (63%) rename grub-core/gnulib/{getopt.h => getopt.in.h} (80%) create mode 100644 grub-core/gnulib/intprops.h create mode 100644 grub-core/gnulib/langinfo.in.h create mode 100644 grub-core/gnulib/localcharset.c create mode 100644 grub-core/gnulib/localcharset.h create mode 100644 grub-core/gnulib/malloc.c create mode 100644 grub-core/gnulib/mbrtowc.c create mode 100644 grub-core/gnulib/mbsinit.c create mode 100644 grub-core/gnulib/mbsrtowcs-state.c create mode 100644 grub-core/gnulib/mbsrtowcs.c create mode 100644 grub-core/gnulib/memchr.c create mode 100644 grub-core/gnulib/memchr.valgrind create mode 100644 grub-core/gnulib/mempcpy.c create mode 100644 grub-core/gnulib/nl_langinfo.c create mode 100644 grub-core/gnulib/printf-args.c create mode 100644 grub-core/gnulib/printf-args.h create mode 100644 grub-core/gnulib/printf-parse.c create mode 100644 grub-core/gnulib/printf-parse.h create mode 100644 grub-core/gnulib/rawmemchr.c create mode 100644 grub-core/gnulib/rawmemchr.valgrind create mode 100644 grub-core/gnulib/realloc.c create mode 100644 grub-core/gnulib/ref-add.sin create mode 100644 grub-core/gnulib/ref-del.sin create mode 100644 grub-core/gnulib/size_max.h create mode 100644 grub-core/gnulib/sleep.c create mode 100644 grub-core/gnulib/stdbool.in.h create mode 100644 grub-core/gnulib/stddef.in.h create mode 100644 grub-core/gnulib/stdint.in.h create mode 100644 grub-core/gnulib/stdio-write.c create mode 100644 grub-core/gnulib/stdio.in.h create mode 100644 grub-core/gnulib/stdlib.in.h create mode 100644 grub-core/gnulib/strcasecmp.c create mode 100644 grub-core/gnulib/strchrnul.c create mode 100644 grub-core/gnulib/strchrnul.valgrind create mode 100644 grub-core/gnulib/streq.h create mode 100644 grub-core/gnulib/strerror.c create mode 100644 grub-core/gnulib/string.in.h create mode 100644 grub-core/gnulib/strings.in.h create mode 100644 grub-core/gnulib/strncasecmp.c create mode 100644 grub-core/gnulib/strndup.c create mode 100644 grub-core/gnulib/strnlen.c rename grub-core/gnulib/{argp-version-etc.c => strnlen1.c} (52%) rename grub-core/gnulib/{argp-version-etc.h => strnlen1.h} (52%) create mode 100644 grub-core/gnulib/sys_wait.in.h create mode 100644 grub-core/gnulib/sysexits.in.h create mode 100644 grub-core/gnulib/unistd.in.h create mode 100644 grub-core/gnulib/vasnprintf.c create mode 100644 grub-core/gnulib/vasnprintf.h create mode 100644 grub-core/gnulib/verify.h create mode 100644 grub-core/gnulib/vsnprintf.c create mode 100644 grub-core/gnulib/wchar.in.h create mode 100644 grub-core/gnulib/wcrtomb.c create mode 100644 grub-core/gnulib/wctype.in.h create mode 100644 grub-core/gnulib/xsize.h create mode 100644 m4/00gnulib.m4 create mode 100644 m4/alloca.m4 create mode 100644 m4/argp.m4 create mode 100644 m4/asm-underscore.m4 create mode 100644 m4/btowc.m4 create mode 100644 m4/codeset.m4 create mode 100644 m4/dirname.m4 create mode 100644 m4/dos.m4 create mode 100644 m4/double-slash-root.m4 create mode 100644 m4/errno_h.m4 create mode 100644 m4/error.m4 create mode 100644 m4/extensions.m4 create mode 100644 m4/fcntl-o.m4 create mode 100644 m4/float_h.m4 create mode 100644 m4/fnmatch.m4 create mode 100644 m4/getdelim.m4 create mode 100644 m4/getline.m4 create mode 100644 m4/getopt.m4 create mode 100644 m4/glibc21.m4 create mode 100644 m4/gnulib-cache.m4 create mode 100644 m4/gnulib-common.m4 create mode 100644 m4/gnulib-comp.m4 create mode 100644 m4/gnulib-tool.m4 create mode 100644 m4/include_next.m4 create mode 100644 m4/intmax_t.m4 create mode 100644 m4/inttypes_h.m4 create mode 100644 m4/langinfo_h.m4 create mode 100644 m4/localcharset.m4 create mode 100644 m4/locale-fr.m4 create mode 100644 m4/locale-ja.m4 create mode 100644 m4/locale-zh.m4 create mode 100644 m4/longlong.m4 create mode 100644 m4/malloc.m4 create mode 100644 m4/mbrtowc.m4 create mode 100644 m4/mbsinit.m4 create mode 100644 m4/mbsrtowcs.m4 create mode 100644 m4/mbstate_t.m4 create mode 100644 m4/memchr.m4 create mode 100644 m4/mempcpy.m4 create mode 100644 m4/mmap-anon.m4 create mode 100644 m4/multiarch.m4 create mode 100644 m4/nl_langinfo.m4 create mode 100644 m4/printf.m4 create mode 100644 m4/rawmemchr.m4 create mode 100644 m4/realloc.m4 create mode 100644 m4/regex.m4 create mode 100644 m4/size_max.m4 create mode 100644 m4/sleep.m4 create mode 100644 m4/ssize_t.m4 create mode 100644 m4/stdbool.m4 create mode 100644 m4/stddef_h.m4 create mode 100644 m4/stdint.m4 create mode 100644 m4/stdint_h.m4 create mode 100644 m4/stdio_h.m4 create mode 100644 m4/stdlib_h.m4 create mode 100644 m4/strcase.m4 create mode 100644 m4/strchrnul.m4 create mode 100644 m4/strerror.m4 create mode 100644 m4/string_h.m4 create mode 100644 m4/strings_h.m4 create mode 100644 m4/strndup.m4 create mode 100644 m4/strnlen.m4 create mode 100644 m4/sys_wait_h.m4 create mode 100644 m4/sysexits.m4 create mode 100644 m4/unistd_h.m4 create mode 100644 m4/vasnprintf.m4 create mode 100644 m4/vsnprintf.m4 create mode 100644 m4/warn-on-use.m4 create mode 100644 m4/wchar_h.m4 create mode 100644 m4/wchar_t.m4 create mode 100644 m4/wcrtomb.m4 create mode 100644 m4/wctype_h.m4 create mode 100644 m4/wint_t.m4 create mode 100644 m4/xsize.m4 diff --git a/.bzrignore b/.bzrignore index d4817ad8c..3c1e294f5 100644 --- a/.bzrignore +++ b/.bzrignore @@ -99,6 +99,7 @@ depcomp mdate-sh texinfo.tex grub-core/lib/libgcrypt-grub +**/.deps **/.deps-util **/.deps-core **/.dirstamp @@ -111,3 +112,20 @@ grub-core/gensyminfo.sh grub-core/*.module grub-core/*.pp util/bash-completion.d/grub +grub-core/gnulib/alloca.h +grub-core/gnulib/arg-nonnull.h +grub-core/gnulib/c++defs.h +grub-core/gnulib/charset.alias +grub-core/gnulib/configmake.h +grub-core/gnulib/getopt.h +grub-core/gnulib/langinfo.h +grub-core/gnulib/ref-add.sed +grub-core/gnulib/ref-del.sed +grub-core/gnulib/stdio.h +grub-core/gnulib/stdlib.h +grub-core/gnulib/string.h +grub-core/gnulib/strings.h +grub-core/gnulib/unistd.h +grub-core/gnulib/warn-on-use.h +grub-core/gnulib/wchar.h +grub-core/gnulib/wctype.h diff --git a/ChangeLog b/ChangeLog index d27ebad1e..3f235a016 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2010-09-20 Yves Blusseau + + Use gnulib-tool to create gnulib source files. + + * Add gnulib files generated by gnulib-tool in build-aux, m4 and + grub-core/gnulib directories + * .bzignore: Add **/.deps and autogenerated gnulib files + * configure.ac: Assign auxiliary directory to build-aux, add invocation + of gnulib macros, add grub-core/gnulib/Makefile + * Makefile.am: Add gnulib directory in SUBDIRS (removing unnecessary .), + include m4 directory to aclocal. + * Makefile.util.def: Remove direct compilation of gnulib source files + and use the new grub-core/gnulib/libgnu.a. + * build-aux/config.rpath: move config.rpath from top directory to + build-aux + * conf/Makefile.common: Remove the macro _GL_UNUSED already defined + in gnulib headers + * conf/Makefile.extra-dist: Add m4/gnulib-cache.m4 + * grub-core/Makefile.core.def: Remove unnecessary extra_dist + * grub-core/lib/posix_wrap/localcharset.h (locale_charset): Update + header. + * grub-core/lib/posix_wrap/langinfo.h (nl_langinfo): Return static + string. + 2010-09-20 Yves Blusseau * .bzrignore: Add grub-kbdcomp, grub-menulst2cfg, *.marker, diff --git a/Makefile.am b/Makefile.am index 9ef8feaac..46275e175 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects DEPDIR = .deps-util -SUBDIRS = . grub-core po docs util/bash-completion.d +SUBDIRS = grub-core/gnulib grub-core po docs util/bash-completion.d include $(top_srcdir)/conf/Makefile.common include $(top_srcdir)/conf/Makefile.extra-dist @@ -11,6 +11,8 @@ AM_LDFLAGS = $(HOST_LDFLAGS) AM_CPPFLAGS = $(HOST_CPPFLAGS) $(CPPFLAGS_DEFAULT) AM_CCASFLAGS = $(HOST_CCASFLAGS) $(CCASFLAGS_DEFAULT) +ACLOCAL_AMFLAGS = -I m4 + CFLAGS_PROGRAM += $(CFLAGS_GNULIB) LDFLAGS_PROGRAM += $(LDFLAGS_GNULIB) CPPFLAGS_PROGRAM += $(CPPFLAGS_GNULIB) diff --git a/Makefile.util.def b/Makefile.util.def index c19f66115..2ec82a4d2 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -11,14 +11,6 @@ library = { common_nodist = grub_script.yy.h; common_nodist = grub_script.tab.h; - common = grub-core/gnulib/error.c; - common = grub-core/gnulib/fnmatch.c; - common = grub-core/gnulib/getdelim.c; - common = grub-core/gnulib/getline.c; - common = grub-core/gnulib/getopt1.c; - common = grub-core/gnulib/getopt.c; - common = grub-core/gnulib/progname.c; - common = util/misc.c; common = grub-core/kern/misc.c; common = grub-core/kern/emu/mm.c; @@ -101,6 +93,7 @@ program = { common = util/bin2h.c; ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; mansection = 1; }; @@ -114,6 +107,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"'; }; @@ -125,6 +119,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; }; program = { @@ -135,6 +130,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; }; program = { @@ -145,6 +141,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; }; program = { @@ -155,6 +152,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; }; @@ -173,6 +171,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL)'; + ldadd = grub-core/gnulib/libgnu.a; condition = COND_GRUB_PE2ELF; }; @@ -184,10 +183,12 @@ program = { common = grub-core/kern/emu/hostfs.c; common = grub-core/disk/host.c; - ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; + + ldadd = libgrub.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; }; program = { @@ -200,6 +201,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; condition = COND_GRUB_MKFONT; }; @@ -218,6 +220,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = grub-core/gnulib/libgnu.a; }; program = { @@ -228,6 +231,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = grub-core/gnulib/libgnu.a; }; program = { @@ -242,6 +246,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = grub-core/gnulib/libgnu.a; enable = i386_pc; enable = sparc64_ieee1275; @@ -255,6 +260,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = grub-core/gnulib/libgnu.a; enable = sparc64_ieee1275; }; @@ -266,6 +272,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; }; data = { @@ -585,4 +592,5 @@ program = { ldadd = libgrub.a; ldflags = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = grub-core/gnulib/libgnu.a; }; diff --git a/build-aux/arg-nonnull.h b/build-aux/arg-nonnull.h new file mode 100644 index 000000000..7e3e2db82 --- /dev/null +++ b/build-aux/arg-nonnull.h @@ -0,0 +1,26 @@ +/* A C macro for declaring that specific arguments must not be NULL. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 General Public License + along with this program. If not, see . */ + +/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools + that the values passed as arguments n, ..., m must be non-NULL pointers. + n = 1 stands for the first argument, n = 2 for the second argument etc. */ +#ifndef _GL_ARG_NONNULL +# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 +# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) +# else +# define _GL_ARG_NONNULL(params) +# endif +#endif diff --git a/build-aux/c++defs.h b/build-aux/c++defs.h new file mode 100644 index 000000000..0c2fad7a2 --- /dev/null +++ b/build-aux/c++defs.h @@ -0,0 +1,271 @@ +/* C++ compatible function declaration macros. + Copyright (C) 2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 General Public License + along with this program. If not, see . */ + +#ifndef _GL_CXXDEFS_H +#define _GL_CXXDEFS_H + +/* The three most frequent use cases of these macros are: + + * For providing a substitute for a function that is missing on some + platforms, but is declared and works fine on the platforms on which + it exists: + + #if @GNULIB_FOO@ + # if !@HAVE_FOO@ + _GL_FUNCDECL_SYS (foo, ...); + # endif + _GL_CXXALIAS_SYS (foo, ...); + _GL_CXXALIASWARN (foo); + #elif defined GNULIB_POSIXCHECK + ... + #endif + + * For providing a replacement for a function that exists on all platforms, + but is broken/insufficient and needs to be replaced on some platforms: + + #if @GNULIB_FOO@ + # if @REPLACE_FOO@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef foo + # define foo rpl_foo + # endif + _GL_FUNCDECL_RPL (foo, ...); + _GL_CXXALIAS_RPL (foo, ...); + # else + _GL_CXXALIAS_SYS (foo, ...); + # endif + _GL_CXXALIASWARN (foo); + #elif defined GNULIB_POSIXCHECK + ... + #endif + + * For providing a replacement for a function that exists on some platforms + but is broken/insufficient and needs to be replaced on some of them and + is additionally either missing or undeclared on some other platforms: + + #if @GNULIB_FOO@ + # if @REPLACE_FOO@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef foo + # define foo rpl_foo + # endif + _GL_FUNCDECL_RPL (foo, ...); + _GL_CXXALIAS_RPL (foo, ...); + # else + # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ + _GL_FUNCDECL_SYS (foo, ...); + # endif + _GL_CXXALIAS_SYS (foo, ...); + # endif + _GL_CXXALIASWARN (foo); + #elif defined GNULIB_POSIXCHECK + ... + #endif +*/ + +/* _GL_EXTERN_C declaration; + performs the declaration with C linkage. */ +#if defined __cplusplus +# define _GL_EXTERN_C extern "C" +#else +# define _GL_EXTERN_C extern +#endif + +/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); + declares a replacement function, named rpl_func, with the given prototype, + consisting of return type, parameters, and attributes. + Example: + _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) + _GL_ARG_NONNULL ((1))); + */ +#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ + _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) +#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ + _GL_EXTERN_C rettype rpl_func parameters_and_attributes + +/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); + declares the system function, named func, with the given prototype, + consisting of return type, parameters, and attributes. + Example: + _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) + _GL_ARG_NONNULL ((1))); + */ +#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ + _GL_EXTERN_C rettype func parameters_and_attributes + +/* _GL_CXXALIAS_RPL (func, rettype, parameters); + declares a C++ alias called GNULIB_NAMESPACE::func + that redirects to rpl_func, if GNULIB_NAMESPACE is defined. + Example: + _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); + */ +#define _GL_CXXALIAS_RPL(func,rettype,parameters) \ + _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ + namespace GNULIB_NAMESPACE \ + { \ + rettype (*const func) parameters = ::rpl_func; \ + } \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#else +# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); + is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); + except that the C function rpl_func may have a slightly different + declaration. A cast is used to silence the "invalid conversion" error + that would otherwise occur. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ + namespace GNULIB_NAMESPACE \ + { \ + rettype (*const func) parameters = \ + reinterpret_cast(::rpl_func); \ + } \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#else +# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +/* _GL_CXXALIAS_SYS (func, rettype, parameters); + declares a C++ alias called GNULIB_NAMESPACE::func + that redirects to the system provided function func, if GNULIB_NAMESPACE + is defined. + Example: + _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); + */ +#if defined __cplusplus && defined GNULIB_NAMESPACE + /* If we were to write + rettype (*const func) parameters = ::func; + like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls + better (remove an indirection through a 'static' pointer variable), + but then the _GL_CXXALIASWARN macro below would cause a warning not only + for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */ +# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ + namespace GNULIB_NAMESPACE \ + { \ + static rettype (*func) parameters = ::func; \ + } \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#else +# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); + is like _GL_CXXALIAS_SYS (func, rettype, parameters); + except that the C function func may have a slightly different declaration. + A cast is used to silence the "invalid conversion" error that would + otherwise occur. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ + namespace GNULIB_NAMESPACE \ + { \ + static rettype (*func) parameters = \ + reinterpret_cast(::func); \ + } \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#else +# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); + is like _GL_CXXALIAS_SYS (func, rettype, parameters); + except that the C function is picked among a set of overloaded functions, + namely the one with rettype2 and parameters2. Two consecutive casts + are used to silence the "cannot find a match" and "invalid conversion" + errors that would otherwise occur. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE + /* The outer cast must be a reinterpret_cast. + The inner cast: When the function is defined as a set of overloaded + functions, it works as a static_cast<>, choosing the designated variant. + When the function is defined as a single variant, it works as a + reinterpret_cast<>. The parenthesized cast syntax works both ways. */ +# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ + namespace GNULIB_NAMESPACE \ + { \ + static rettype (*func) parameters = \ + reinterpret_cast( \ + (rettype2(*)parameters2)(::func)); \ + } \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#else +# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +/* _GL_CXXALIASWARN (func); + causes a warning to be emitted when ::func is used but not when + GNULIB_NAMESPACE::func is used. func must be defined without overloaded + variants. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_CXXALIASWARN(func) \ + _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) +# define _GL_CXXALIASWARN_1(func,namespace) \ + _GL_CXXALIASWARN_2 (func, namespace) +/* To work around GCC bug , + we enable the warning only when not optimizing. */ +# if !__OPTIMIZE__ +# define _GL_CXXALIASWARN_2(func,namespace) \ + _GL_WARN_ON_USE (func, \ + "The symbol ::" #func " refers to the system function. " \ + "Use " #namespace "::" #func " instead.") +# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +# define _GL_CXXALIASWARN_2(func,namespace) \ + extern __typeof__ (func) func +# else +# define _GL_CXXALIASWARN_2(func,namespace) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +# endif +#else +# define _GL_CXXALIASWARN(func) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); + causes a warning to be emitted when the given overloaded variant of ::func + is used but not when GNULIB_NAMESPACE::func is used. */ +#if defined __cplusplus && defined GNULIB_NAMESPACE +# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ + _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ + GNULIB_NAMESPACE) +# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ + _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) +/* To work around GCC bug , + we enable the warning only when not optimizing. */ +# if !__OPTIMIZE__ +# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ + _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ + "The symbol ::" #func " refers to the system function. " \ + "Use " #namespace "::" #func " instead.") +# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ + extern __typeof__ (func) func +# else +# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +# endif +#else +# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ + _GL_EXTERN_C int _gl_cxxalias_dummy +#endif + +#endif /* _GL_CXXDEFS_H */ diff --git a/config.rpath b/build-aux/config.rpath similarity index 81% rename from config.rpath rename to build-aux/config.rpath index 85c2f209b..c492a93b6 100755 --- a/config.rpath +++ b/build-aux/config.rpath @@ -2,7 +2,7 @@ # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # -# Copyright 1996-2008 Free Software Foundation, Inc. +# Copyright 1996-2006 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # @@ -47,7 +47,7 @@ for cc_temp in $CC""; do done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` -# Code taken from libtool.m4's _LT_COMPILER_PIC. +# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. wl= if test "$GCC" = yes; then @@ -64,7 +64,7 @@ else ;; esac ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | pw32* | os2*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' @@ -74,15 +74,9 @@ else ;; newsos6) ;; - linux* | k*bsd*-gnu) + linux*) case $cc_basename in - ecc*) - wl='-Wl,' - ;; - icc* | ifort*) - wl='-Wl,' - ;; - lf95*) + icc* | ecc*) wl='-Wl,' ;; pgcc | pgf77 | pgf90) @@ -106,7 +100,7 @@ else osf3* | osf4* | osf5*) wl='-Wl,' ;; - rdos*) + sco3.2v5*) ;; solaris*) wl='-Wl,' @@ -114,14 +108,11 @@ else sunos4*) wl='-Qoption ld ' ;; - sysv4 | sysv4.2uw2* | sysv4.3*) + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) wl='-Wl,' ;; sysv4*MP*) ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - wl='-Wl,' - ;; unicos*) wl='-Wl,' ;; @@ -130,7 +121,7 @@ else esac fi -# Code taken from libtool.m4's _LT_LINKER_SHLIBS. +# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= @@ -138,7 +129,7 @@ hardcode_direct=no hardcode_minus_L=no case "$host_os" in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. @@ -164,7 +155,7 @@ if test "$with_gnu_ld" = yes; then # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in - aix[3-9]*) + aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no @@ -188,7 +179,7 @@ if test "$with_gnu_ld" = yes; then ld_shlibs=no fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | pw32*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' @@ -198,11 +189,11 @@ if test "$with_gnu_ld" = yes; then ld_shlibs=no fi ;; - interix[3-9]*) + interix3*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; - gnu* | linux* | k*bsd*-gnu) + linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else @@ -260,7 +251,7 @@ else hardcode_direct=unsupported fi ;; - aix[4-9]*) + aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -270,7 +261,7 @@ else # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes @@ -289,7 +280,7 @@ else strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - : + hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported @@ -332,7 +323,7 @@ else ;; bsdi[45]*) ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is @@ -368,7 +359,7 @@ else hardcode_direct=yes hardcode_minus_L=yes ;; - freebsd* | dragonfly*) + freebsd* | kfreebsd*-gnu | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; @@ -421,22 +412,18 @@ else hardcode_libdir_separator=: ;; openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else - ld_shlibs=no + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac fi ;; os2*) @@ -484,7 +471,7 @@ else ld_shlibs=yes fi ;; - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' @@ -500,52 +487,34 @@ else fi # Check dynamic linker characteristics -# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. -# Unlike libtool.m4, here we don't care about _all_ names of the library, but -# only about the one the linker finds when passed -lNAME. This is the last -# element of library_names_spec in libtool.m4, or possibly two of them if the -# linker has special search rules. -library_names_spec= # the last element of library_names_spec in libtool.m4 +# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. libname_spec='lib$name' case "$host_os" in aix3*) - library_names_spec='$libname.a' ;; - aix[4-9]*) - library_names_spec='$libname$shrext' + aix4* | aix5*) ;; amigaos*) - library_names_spec='$libname.a' ;; beos*) - library_names_spec='$libname$shrext' ;; bsdi[45]*) - library_names_spec='$libname$shrext' ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | pw32*) shrext=.dll - library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib - library_names_spec='$libname$shrext' ;; dgux*) - library_names_spec='$libname$shrext' ;; freebsd1*) ;; + kfreebsd*-gnu) + ;; freebsd* | dragonfly*) - case "$host_os" in - freebsd[123]*) - library_names_spec='$libname$shrext$versuffix' ;; - *) - library_names_spec='$libname$shrext' ;; - esac ;; gnu*) - library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in @@ -559,13 +528,10 @@ case "$host_os" in shrext=.sl ;; esac - library_names_spec='$libname$shrext' ;; - interix[3-9]*) - library_names_spec='$libname$shrext' + interix3*) ;; irix5* | irix6* | nonstopux*) - library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= @@ -582,59 +548,41 @@ case "$host_os" in ;; linux*oldld* | linux*aout* | linux*coff*) ;; - linux* | k*bsd*-gnu) - library_names_spec='$libname$shrext' + linux*) ;; knetbsd*-gnu) - library_names_spec='$libname$shrext' ;; netbsd*) - library_names_spec='$libname$shrext' ;; newsos6) - library_names_spec='$libname$shrext' ;; nto-qnx*) - library_names_spec='$libname$shrext' ;; openbsd*) - library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll - library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) - library_names_spec='$libname$shrext' - ;; - rdos*) ;; solaris*) - library_names_spec='$libname$shrext' ;; sunos4*) - library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) - library_names_spec='$libname$shrext' ;; sysv4*MP*) - library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - library_names_spec='$libname$shrext' ;; uts4*) - library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` -escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. */ + +/* _GL_WARN_ON_USE (function, "literal string") issues a declaration + for FUNCTION which will then trigger a compiler warning containing + the text of "literal string" anywhere that function is called, if + supported by the compiler. If the compiler does not support this + feature, the macro expands to an unused extern declaration. + + This macro is useful for marking a function as a potential + portability trap, with the intent that "literal string" include + instructions on the replacement function that should be used + instead. However, one of the reasons that a function is a + portability trap is if it has the wrong signature. Declaring + FUNCTION with a different signature in C is a compilation error, so + this macro must use the same type as any existing declaration so + that programs that avoid the problematic FUNCTION do not fail to + compile merely because they included a header that poisoned the + function. But this implies that _GL_WARN_ON_USE is only safe to + use if FUNCTION is known to already have a declaration. Use of + this macro implies that there must not be any other macro hiding + the declaration of FUNCTION; but undefining FUNCTION first is part + of the poisoning process anyway (although for symbols that are + provided only via a macro, the result is a compilation error rather + than a warning containing "literal string"). Also note that in + C++, it is only safe to use if FUNCTION has no overloads. + + For an example, it is possible to poison 'getline' by: + - adding a call to gl_WARN_ON_USE_PREPARE([[#include ]], + [getline]) in configure.ac, which potentially defines + HAVE_RAW_DECL_GETLINE + - adding this code to a header that wraps the system : + #undef getline + #if HAVE_RAW_DECL_GETLINE + _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" + "not universally present; use the gnulib module getline"); + #endif + + It is not possible to directly poison global variables. But it is + possible to write a wrapper accessor function, and poison that + (less common usage, like &environ, will cause a compilation error + rather than issue the nice warning, but the end result of informing + the developer about their portability problem is still achieved): + #if HAVE_RAW_DECL_ENVIRON + static inline char ***rpl_environ (void) { return &environ; } + _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); + # undef environ + # define environ (*rpl_environ ()) + #endif + */ +#ifndef _GL_WARN_ON_USE + +# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +/* A compiler attribute is available in gcc versions 4.3.0 and later. */ +# define _GL_WARN_ON_USE(function, message) \ +extern __typeof__ (function) function __attribute__ ((__warning__ (message))) +# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +/* Verify the existence of the function. */ +# define _GL_WARN_ON_USE(function, message) \ +extern __typeof__ (function) function +# else /* Unsupported. */ +# define _GL_WARN_ON_USE(function, message) \ +_GL_WARN_EXTERN_C int _gl_warn_on_use +# endif +#endif + +/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") + is like _GL_WARN_ON_USE (function, "string"), except that the function is + declared with the given prototype, consisting of return type, parameters, + and attributes. + This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does + not work in this case. */ +#ifndef _GL_WARN_ON_USE_CXX +# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +extern rettype function parameters_and_attributes \ + __attribute__ ((__warning__ (msg))) +# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +/* Verify the existence of the function. */ +# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +extern rettype function parameters_and_attributes +# else /* Unsupported. */ +# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +_GL_WARN_EXTERN_C int _gl_warn_on_use +# endif +#endif + +/* _GL_WARN_EXTERN_C declaration; + performs the declaration with C linkage. */ +#ifndef _GL_WARN_EXTERN_C +# if defined __cplusplus +# define _GL_WARN_EXTERN_C extern "C" +# else +# define _GL_WARN_EXTERN_C extern +# endif +#endif diff --git a/conf/Makefile.common b/conf/Makefile.common index a861c25e6..baac922c1 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -80,7 +80,7 @@ platformdir = $(pkglibrootdir)/$(target_cpu)-$(platform) CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap -CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -D_GL_UNUSED="__attribute__ ((unused))" +CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused CPPFLAGS_GNULIB = -I$(top_srcdir)/grub-core/gnulib CFLAGS_POSIX = -fno-builtin diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 68989d333..c340bb80e 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -30,3 +30,5 @@ EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h') + +EXTRA_DIST += m4/gnulib-cache.m4 diff --git a/configure.ac b/configure.ac index 75fa43d53..ad48c6298 100644 --- a/configure.ac +++ b/configure.ac @@ -34,6 +34,8 @@ dnl type. AC_INIT([GRUB],[1.98],[bug-grub@gnu.org]) +AC_CONFIG_AUX_DIR([build-aux]) + # We don't want -g -O2 by default in CFLAGS : ${CFLAGS=""} @@ -249,6 +251,7 @@ AC_PATH_PROG(MAKEINFO, makeinfo) # AC_PROG_CC +gl_EARLY AM_PROG_CC_C_O AM_PROG_AS @@ -309,6 +312,9 @@ HOST_CC=$CC AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc], [AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.])]) +# For gnulib. +gl_INIT + # # Check for target programs. # @@ -927,6 +933,7 @@ fi AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([grub-core/Makefile]) +AC_CONFIG_FILES([grub-core/gnulib/Makefile]) AC_CONFIG_FILES([po/Makefile]) AC_CONFIG_FILES([docs/Makefile]) AC_CONFIG_FILES([util/bash-completion.d/Makefile]) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8e6b82ca5..5fa6ba153 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -380,12 +380,6 @@ module = { library = { name = libgnulib.a; common = gnulib/regex.c; - - extra_dist = gnulib/regcomp.c; - extra_dist = gnulib/regexec.c; - extra_dist = gnulib/fnmatch_loop.c; - extra_dist = gnulib/regex_internal.c; - cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; }; diff --git a/grub-core/gnulib/Makefile.am b/grub-core/gnulib/Makefile.am new file mode 100644 index 000000000..e990aefb1 --- /dev/null +++ b/grub-core/gnulib/Makefile.am @@ -0,0 +1,1336 @@ +## DO NOT EDIT! GENERATED AUTOMATICALLY! +## Process this file with automake to produce Makefile.in. +# Copyright (C) 2002-2010 Free Software Foundation, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline progname regex + +AUTOMAKE_OPTIONS = 1.5 gnits + +SUBDIRS = +noinst_HEADERS = +noinst_LIBRARIES = +noinst_LTLIBRARIES = +EXTRA_DIST = +BUILT_SOURCES = +SUFFIXES = +MOSTLYCLEANFILES = core *.stackdump +MOSTLYCLEANDIRS = +CLEANFILES = +DISTCLEANFILES = +MAINTAINERCLEANFILES = + +AM_CPPFLAGS = +AM_CFLAGS = + +noinst_LIBRARIES += libgnu.a + +libgnu_a_SOURCES = +libgnu_a_LIBADD = $(gl_LIBOBJS) +libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) +EXTRA_libgnu_a_SOURCES = + +## begin gnulib module alloca + + +EXTRA_DIST += alloca.c + +EXTRA_libgnu_a_SOURCES += alloca.c + +libgnu_a_LIBADD += @ALLOCA@ +libgnu_a_DEPENDENCIES += @ALLOCA@ +## end gnulib module alloca + +## begin gnulib module alloca-opt + +BUILT_SOURCES += $(ALLOCA_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +alloca.h: alloca.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/alloca.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +MOSTLYCLEANFILES += alloca.h alloca.h-t + +EXTRA_DIST += alloca.in.h + +## end gnulib module alloca-opt + +## begin gnulib module arg-nonnull + +# The BUILT_SOURCES created by this Makefile snippet are not used via #include +# statements but through direct file reference. Therefore this snippet must be +# present in all Makefile.am that need it. This is ensured by the applicability +# 'all' defined above. + +BUILT_SOURCES += arg-nonnull.h +# The arg-nonnull.h that gets inserted into generated .h files is the same as +# build-aux/arg-nonnull.h, except that it has the copyright header cut off. +arg-nonnull.h: $(top_srcdir)/build-aux/arg-nonnull.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/GL_ARG_NONNULL/,$$p' \ + < $(top_srcdir)/build-aux/arg-nonnull.h \ + > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t + +ARG_NONNULL_H=arg-nonnull.h + +EXTRA_DIST += $(top_srcdir)/build-aux/arg-nonnull.h + +## end gnulib module arg-nonnull + +## begin gnulib module argp + +libgnu_a_SOURCES += argp.h argp-ba.c argp-eexst.c \ + argp-fmtstream.c argp-fmtstream.h argp-fs-xinl.c argp-help.c \ + argp-namefrob.h argp-parse.c argp-pin.c argp-pv.c argp-pvh.c \ + argp-xinl.c + +## end gnulib module argp + +## begin gnulib module btowc + + +EXTRA_DIST += btowc.c + +EXTRA_libgnu_a_SOURCES += btowc.c + +## end gnulib module btowc + +## begin gnulib module c++defs + +# The BUILT_SOURCES created by this Makefile snippet are not used via #include +# statements but through direct file reference. Therefore this snippet must be +# present in all Makefile.am that need it. This is ensured by the applicability +# 'all' defined above. + +BUILT_SOURCES += c++defs.h +# The c++defs.h that gets inserted into generated .h files is the same as +# build-aux/c++defs.h, except that it has the copyright header cut off. +c++defs.h: $(top_srcdir)/build-aux/c++defs.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/_GL_CXXDEFS/,$$p' \ + < $(top_srcdir)/build-aux/c++defs.h \ + > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += c++defs.h c++defs.h-t + +CXXDEFS_H=c++defs.h + +EXTRA_DIST += $(top_srcdir)/build-aux/c++defs.h + +## end gnulib module c++defs + +## begin gnulib module configmake + +# Retrieve values of the variables through 'configure' followed by +# 'make', not directly through 'configure', so that a user who +# sets some of these variables consistently on the 'make' command +# line gets correct results. +# +# One advantage of this approach, compared to the classical +# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS, +# is that it protects against the use of undefined variables. +# If, say, $(libdir) is not set in the Makefile, LIBDIR is not +# defined by this module, and code using LIBDIR gives a +# compilation error. +# +# Another advantage is that 'make' output is shorter. +# +# Listed in the same order as the GNU makefile conventions. +# The Automake-defined pkg* macros are appended, in the order +# listed in the Automake 1.10a+ documentation. +configmake.h: Makefile + $(AM_V_GEN)rm -f $@-t && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + echo '#define PREFIX "$(prefix)"'; \ + echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ + echo '#define BINDIR "$(bindir)"'; \ + echo '#define SBINDIR "$(sbindir)"'; \ + echo '#define LIBEXECDIR "$(libexecdir)"'; \ + echo '#define DATAROOTDIR "$(datarootdir)"'; \ + echo '#define DATADIR "$(datadir)"'; \ + echo '#define SYSCONFDIR "$(sysconfdir)"'; \ + echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ + echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ + echo '#define INCLUDEDIR "$(includedir)"'; \ + echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ + echo '#define DOCDIR "$(docdir)"'; \ + echo '#define INFODIR "$(infodir)"'; \ + echo '#define HTMLDIR "$(htmldir)"'; \ + echo '#define DVIDIR "$(dvidir)"'; \ + echo '#define PDFDIR "$(pdfdir)"'; \ + echo '#define PSDIR "$(psdir)"'; \ + echo '#define LIBDIR "$(libdir)"'; \ + echo '#define LISPDIR "$(lispdir)"'; \ + echo '#define LOCALEDIR "$(localedir)"'; \ + echo '#define MANDIR "$(mandir)"'; \ + echo '#define MANEXT "$(manext)"'; \ + echo '#define PKGDATADIR "$(pkgdatadir)"'; \ + echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ + echo '#define PKGLIBDIR "$(pkglibdir)"'; \ + echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ + } | sed '/""/d' > $@-t && \ + if test -f $@ && cmp $@-t $@ > /dev/null; then \ + rm -f $@-t; \ + else \ + rm -f $@; mv $@-t $@; \ + fi + +BUILT_SOURCES += configmake.h +CLEANFILES += configmake.h configmake.h-t + +## end gnulib module configmake + +## begin gnulib module dirname-lgpl + + +EXTRA_DIST += basename-lgpl.c dirname-lgpl.c dirname.h stripslash.c + +EXTRA_libgnu_a_SOURCES += basename-lgpl.c dirname-lgpl.c stripslash.c + +## end gnulib module dirname-lgpl + +## begin gnulib module errno + +BUILT_SOURCES += $(ERRNO_H) + +# We need the following in order to create when the system +# doesn't have one that is POSIX compliant. +errno.h: errno.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ + -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ + -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ + -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \ + -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \ + -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \ + -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \ + < $(srcdir)/errno.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += errno.h errno.h-t + +EXTRA_DIST += errno.in.h + +## end gnulib module errno + +## begin gnulib module error + + +EXTRA_DIST += error.c error.h + +EXTRA_libgnu_a_SOURCES += error.c + +## end gnulib module error + +## begin gnulib module float + +BUILT_SOURCES += $(FLOAT_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +float.h: float.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ + < $(srcdir)/float.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += float.h float.h-t + +EXTRA_DIST += float.in.h + +## end gnulib module float + +## begin gnulib module fnmatch + +BUILT_SOURCES += $(FNMATCH_H) + +# We need the following in order to create when the system +# doesn't have one that supports the required API. +fnmatch.h: fnmatch.in.h $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/fnmatch.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t + +EXTRA_DIST += fnmatch.c fnmatch.in.h fnmatch_loop.c + +EXTRA_libgnu_a_SOURCES += fnmatch.c fnmatch_loop.c + +## end gnulib module fnmatch + +## begin gnulib module getdelim + + +EXTRA_DIST += getdelim.c + +EXTRA_libgnu_a_SOURCES += getdelim.c + +## end gnulib module getdelim + +## begin gnulib module getline + + +EXTRA_DIST += getline.c + +EXTRA_libgnu_a_SOURCES += getline.c + +## end gnulib module getline + +## begin gnulib module getopt-posix + +BUILT_SOURCES += $(GETOPT_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +getopt.h: getopt.in.h $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/getopt.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +MOSTLYCLEANFILES += getopt.h getopt.h-t + +EXTRA_DIST += getopt.c getopt.in.h getopt1.c getopt_int.h + +EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c + +## end gnulib module getopt-posix + +## begin gnulib module gettext-h + +libgnu_a_SOURCES += gettext.h + +## end gnulib module gettext-h + +## begin gnulib module intprops + + +EXTRA_DIST += intprops.h + +## end gnulib module intprops + +## begin gnulib module langinfo + +BUILT_SOURCES += langinfo.h + +# We need the following in order to create an empty placeholder for +# when the system doesn't have one. +langinfo.h: langinfo.in.h $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \ + -e 's|@''GNULIB_NL_LANGINFO''@|$(GNULIB_NL_LANGINFO)|g' \ + -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ + -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ + -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ + -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ + -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ + -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/langinfo.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += langinfo.h langinfo.h-t + +EXTRA_DIST += langinfo.in.h + +## end gnulib module langinfo + +## begin gnulib module localcharset + +libgnu_a_SOURCES += localcharset.h localcharset.c + +# We need the following in order to install a simple file in $(libdir) +# which is shared with other installed packages. We use a list of referencing +# packages so that "make uninstall" will remove the file if and only if it +# is not used by another installed package. +# On systems with glibc-2.1 or newer, the file is redundant, therefore we +# avoid installing it. + +all-local: charset.alias ref-add.sed ref-del.sed + +charset_alias = $(DESTDIR)$(libdir)/charset.alias +charset_tmp = $(DESTDIR)$(libdir)/charset.tmp +install-exec-local: install-exec-localcharset +install-exec-localcharset: all-local + if test $(GLIBC21) = no; then \ + case '$(host_os)' in \ + darwin[56]*) \ + need_charset_alias=true ;; \ + darwin* | cygwin* | mingw* | pw32* | cegcc*) \ + need_charset_alias=false ;; \ + *) \ + need_charset_alias=true ;; \ + esac ; \ + else \ + need_charset_alias=false ; \ + fi ; \ + if $$need_charset_alias; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ + fi ; \ + if test -f $(charset_alias); then \ + sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + else \ + if $$need_charset_alias; then \ + sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + fi ; \ + fi + +uninstall-local: uninstall-localcharset +uninstall-localcharset: all-local + if test -f $(charset_alias); then \ + sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ + if grep '^# Packages using this file: $$' $(charset_tmp) \ + > /dev/null; then \ + rm -f $(charset_alias); \ + else \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ + fi; \ + rm -f $(charset_tmp); \ + fi + +charset.alias: config.charset + $(AM_V_GEN)rm -f t-$@ $@ && \ + $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ + mv t-$@ $@ + +SUFFIXES += .sed .sin +.sin.sed: + $(AM_V_GEN)rm -f t-$@ $@ && \ + sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ + mv t-$@ $@ + +CLEANFILES += charset.alias ref-add.sed ref-del.sed + +EXTRA_DIST += config.charset ref-add.sin ref-del.sin + +## end gnulib module localcharset + +## begin gnulib module malloc-gnu + + +EXTRA_DIST += malloc.c + +EXTRA_libgnu_a_SOURCES += malloc.c + +## end gnulib module malloc-gnu + +## begin gnulib module malloc-posix + + +EXTRA_DIST += malloc.c + +EXTRA_libgnu_a_SOURCES += malloc.c + +## end gnulib module malloc-posix + +## begin gnulib module mbrtowc + + +EXTRA_DIST += mbrtowc.c + +EXTRA_libgnu_a_SOURCES += mbrtowc.c + +## end gnulib module mbrtowc + +## begin gnulib module mbsinit + + +EXTRA_DIST += mbsinit.c + +EXTRA_libgnu_a_SOURCES += mbsinit.c + +## end gnulib module mbsinit + +## begin gnulib module mbsrtowcs + + +EXTRA_DIST += mbsrtowcs-state.c mbsrtowcs.c + +EXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c mbsrtowcs.c + +## end gnulib module mbsrtowcs + +## begin gnulib module memchr + + +EXTRA_DIST += memchr.c memchr.valgrind + +EXTRA_libgnu_a_SOURCES += memchr.c + +## end gnulib module memchr + +## begin gnulib module mempcpy + + +EXTRA_DIST += mempcpy.c + +EXTRA_libgnu_a_SOURCES += mempcpy.c + +## end gnulib module mempcpy + +## begin gnulib module nl_langinfo + + +EXTRA_DIST += nl_langinfo.c + +EXTRA_libgnu_a_SOURCES += nl_langinfo.c + +## end gnulib module nl_langinfo + +## begin gnulib module progname + +libgnu_a_SOURCES += progname.h progname.c + +## end gnulib module progname + +## begin gnulib module rawmemchr + + +EXTRA_DIST += rawmemchr.c rawmemchr.valgrind + +EXTRA_libgnu_a_SOURCES += rawmemchr.c + +## end gnulib module rawmemchr + +## begin gnulib module realloc-posix + + +EXTRA_DIST += realloc.c + +EXTRA_libgnu_a_SOURCES += realloc.c + +## end gnulib module realloc-posix + +## begin gnulib module regex + + +EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c + +EXTRA_libgnu_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c + +## end gnulib module regex + +## begin gnulib module size_max + +libgnu_a_SOURCES += size_max.h + +## end gnulib module size_max + +## begin gnulib module sleep + + +EXTRA_DIST += sleep.c + +EXTRA_libgnu_a_SOURCES += sleep.c + +## end gnulib module sleep + +## begin gnulib module stdbool + +BUILT_SOURCES += $(STDBOOL_H) + +# We need the following in order to create when the system +# doesn't have one that works. +stdbool.h: stdbool.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdbool.h stdbool.h-t + +EXTRA_DIST += stdbool.in.h + +## end gnulib module stdbool + +## begin gnulib module stddef + +BUILT_SOURCES += $(STDDEF_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stddef.h: stddef.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ + -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ + -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ + < $(srcdir)/stddef.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stddef.h stddef.h-t + +EXTRA_DIST += stddef.in.h + +## end gnulib module stddef + +## begin gnulib module stdint + +BUILT_SOURCES += $(STDINT_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stdint.h: stdint.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ + -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ + -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ + -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ + -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ + -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ + -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ + -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ + -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ + -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ + < $(srcdir)/stdint.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdint.h stdint.h-t + +EXTRA_DIST += stdint.in.h + +## end gnulib module stdint + +## begin gnulib module stdio + +BUILT_SOURCES += stdio.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ + -e 's|@''GNULIB_DPRINTF''@|$(GNULIB_DPRINTF)|g' \ + -e 's|@''GNULIB_FCLOSE''@|$(GNULIB_FCLOSE)|g' \ + -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ + -e 's|@''GNULIB_FOPEN''@|$(GNULIB_FOPEN)|g' \ + -e 's|@''GNULIB_FPRINTF''@|$(GNULIB_FPRINTF)|g' \ + -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_FPURGE''@|$(GNULIB_FPURGE)|g' \ + -e 's|@''GNULIB_FPUTC''@|$(GNULIB_FPUTC)|g' \ + -e 's|@''GNULIB_FPUTS''@|$(GNULIB_FPUTS)|g' \ + -e 's|@''GNULIB_FREOPEN''@|$(GNULIB_FREOPEN)|g' \ + -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ + -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ + -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ + -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ + -e 's|@''GNULIB_FWRITE''@|$(GNULIB_FWRITE)|g' \ + -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ + -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ + -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ + -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \ + -e 's|@''GNULIB_PERROR''@|$(GNULIB_PERROR)|g' \ + -e 's|@''GNULIB_POPEN''@|$(GNULIB_POPEN)|g' \ + -e 's|@''GNULIB_PRINTF''@|$(GNULIB_PRINTF)|g' \ + -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ + -e 's|@''GNULIB_PUTC''@|$(GNULIB_PUTC)|g' \ + -e 's|@''GNULIB_PUTCHAR''@|$(GNULIB_PUTCHAR)|g' \ + -e 's|@''GNULIB_PUTS''@|$(GNULIB_PUTS)|g' \ + -e 's|@''GNULIB_REMOVE''@|$(GNULIB_REMOVE)|g' \ + -e 's|@''GNULIB_RENAME''@|$(GNULIB_RENAME)|g' \ + -e 's|@''GNULIB_RENAMEAT''@|$(GNULIB_RENAMEAT)|g' \ + -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ + -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_STDIO_H_SIGPIPE''@|$(GNULIB_STDIO_H_SIGPIPE)|g' \ + -e 's|@''GNULIB_TMPFILE''@|$(GNULIB_TMPFILE)|g' \ + -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ + -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ + -e 's|@''GNULIB_VFPRINTF''@|$(GNULIB_VFPRINTF)|g' \ + -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VPRINTF''@|$(GNULIB_VPRINTF)|g' \ + -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ + -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ + -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ + < $(srcdir)/stdio.in.h | \ + sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ + -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ + -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ + -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ + -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ + -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ + -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \ + -e 's|@''HAVE_FSEEKO''@|$(HAVE_FSEEKO)|g' \ + -e 's|@''HAVE_FTELLO''@|$(HAVE_FTELLO)|g' \ + -e 's|@''HAVE_RENAMEAT''@|$(HAVE_RENAMEAT)|g' \ + -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ + -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ + -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ + -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ + -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ + -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \ + -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ + -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \ + -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \ + -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ + -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ + -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ + -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ + -e 's|@''REPLACE_GETDELIM''@|$(REPLACE_GETDELIM)|g' \ + -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ + -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \ + -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \ + -e 's|@''REPLACE_POPEN''@|$(REPLACE_POPEN)|g' \ + -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ + -e 's|@''REPLACE_REMOVE''@|$(REPLACE_REMOVE)|g' \ + -e 's|@''REPLACE_RENAME''@|$(REPLACE_RENAME)|g' \ + -e 's|@''REPLACE_RENAMEAT''@|$(REPLACE_RENAMEAT)|g' \ + -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ + -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ + -e 's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \ + -e 's|@''REPLACE_TMPFILE''@|$(REPLACE_TMPFILE)|g' \ + -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ + -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ + -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ + -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ + -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ + -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ + -e 's|@''ASM_SYMBOL_PREFIX''@|$(ASM_SYMBOL_PREFIX)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdio.h stdio.h-t + +EXTRA_DIST += stdio-write.c stdio.in.h + +EXTRA_libgnu_a_SOURCES += stdio-write.c + +## end gnulib module stdio + +## begin gnulib module stdlib + +BUILT_SOURCES += stdlib.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ + -e 's|@''GNULIB__EXIT''@|$(GNULIB__EXIT)|g' \ + -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \ + -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ + -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ + -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ + -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \ + -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ + -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ + -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \ + -e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \ + -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ + -e 's|@''GNULIB_MKSTEMPS''@|$(GNULIB_MKSTEMPS)|g' \ + -e 's|@''GNULIB_PTSNAME''@|$(GNULIB_PTSNAME)|g' \ + -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \ + -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \ + -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ + -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \ + -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \ + -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \ + -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \ + -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \ + -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \ + -e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \ + -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \ + -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ + -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ + -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ + -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ + -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ + -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ + -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \ + -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \ + -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \ + -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ + -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ + -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ + -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ + -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ + -e 's|@''HAVE_SETENV''@|$(HAVE_SETENV)|g' \ + -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ + -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ + -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ + -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ + -e 's|@''HAVE_UNSETENV''@|$(HAVE_UNSETENV)|g' \ + -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ + -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ + -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ + -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ + -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ + -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ + -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ + -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/stdlib.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdlib.h stdlib.h-t + +EXTRA_DIST += stdlib.in.h + +## end gnulib module stdlib + +## begin gnulib module strcase + + +EXTRA_DIST += strcasecmp.c strncasecmp.c + +EXTRA_libgnu_a_SOURCES += strcasecmp.c strncasecmp.c + +## end gnulib module strcase + +## begin gnulib module strchrnul + + +EXTRA_DIST += strchrnul.c strchrnul.valgrind + +EXTRA_libgnu_a_SOURCES += strchrnul.c + +## end gnulib module strchrnul + +## begin gnulib module streq + + +EXTRA_DIST += streq.h + +## end gnulib module streq + +## begin gnulib module strerror + + +EXTRA_DIST += strerror.c + +EXTRA_libgnu_a_SOURCES += strerror.c + +## end gnulib module strerror + +## begin gnulib module string + +BUILT_SOURCES += string.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +string.h: string.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ + -e 's|@''GNULIB_MBSLEN''@|$(GNULIB_MBSLEN)|g' \ + -e 's|@''GNULIB_MBSNLEN''@|$(GNULIB_MBSNLEN)|g' \ + -e 's|@''GNULIB_MBSCHR''@|$(GNULIB_MBSCHR)|g' \ + -e 's|@''GNULIB_MBSRCHR''@|$(GNULIB_MBSRCHR)|g' \ + -e 's|@''GNULIB_MBSSTR''@|$(GNULIB_MBSSTR)|g' \ + -e 's|@''GNULIB_MBSCASECMP''@|$(GNULIB_MBSCASECMP)|g' \ + -e 's|@''GNULIB_MBSNCASECMP''@|$(GNULIB_MBSNCASECMP)|g' \ + -e 's|@''GNULIB_MBSPCASECMP''@|$(GNULIB_MBSPCASECMP)|g' \ + -e 's|@''GNULIB_MBSCASESTR''@|$(GNULIB_MBSCASESTR)|g' \ + -e 's|@''GNULIB_MBSCSPN''@|$(GNULIB_MBSCSPN)|g' \ + -e 's|@''GNULIB_MBSPBRK''@|$(GNULIB_MBSPBRK)|g' \ + -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ + -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ + -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ + -e 's|@''GNULIB_MEMCHR''@|$(GNULIB_MEMCHR)|g' \ + -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ + -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ + -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ + -e 's|@''GNULIB_RAWMEMCHR''@|$(GNULIB_RAWMEMCHR)|g' \ + -e 's|@''GNULIB_STPCPY''@|$(GNULIB_STPCPY)|g' \ + -e 's|@''GNULIB_STPNCPY''@|$(GNULIB_STPNCPY)|g' \ + -e 's|@''GNULIB_STRCHRNUL''@|$(GNULIB_STRCHRNUL)|g' \ + -e 's|@''GNULIB_STRDUP''@|$(GNULIB_STRDUP)|g' \ + -e 's|@''GNULIB_STRNCAT''@|$(GNULIB_STRNCAT)|g' \ + -e 's|@''GNULIB_STRNDUP''@|$(GNULIB_STRNDUP)|g' \ + -e 's|@''GNULIB_STRNLEN''@|$(GNULIB_STRNLEN)|g' \ + -e 's|@''GNULIB_STRPBRK''@|$(GNULIB_STRPBRK)|g' \ + -e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \ + -e 's|@''GNULIB_STRSTR''@|$(GNULIB_STRSTR)|g' \ + -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \ + -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \ + -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \ + -e 's|@''GNULIB_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \ + -e 's|@''GNULIB_STRVERSCMP''@|$(GNULIB_STRVERSCMP)|g' \ + < $(srcdir)/string.in.h | \ + sed -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ + -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ + -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ + -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ + -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \ + -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ + -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ + -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ + -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ + -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ + -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ + -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ + -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ + -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ + -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ + -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ + -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ + -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ + -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ + -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ + -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ + -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ + -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ + -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ + -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ + -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + < $(srcdir)/string.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += string.h string.h-t + +EXTRA_DIST += string.in.h + +## end gnulib module string + +## begin gnulib module strings + +BUILT_SOURCES += strings.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +strings.h: strings.in.h $(WARN_ON_USE_H) $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ + -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ + -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/strings.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += strings.h strings.h-t + +EXTRA_DIST += strings.in.h + +## end gnulib module strings + +## begin gnulib module strndup + + +EXTRA_DIST += strndup.c + +EXTRA_libgnu_a_SOURCES += strndup.c + +## end gnulib module strndup + +## begin gnulib module strnlen + + +EXTRA_DIST += strnlen.c + +EXTRA_libgnu_a_SOURCES += strnlen.c + +## end gnulib module strnlen + +## begin gnulib module strnlen1 + +libgnu_a_SOURCES += strnlen1.h strnlen1.c + +## end gnulib module strnlen1 + +## begin gnulib module sys_wait + +BUILT_SOURCES += sys/wait.h + +# We need the following in order to create when the system +# has one that is incomplete. +sys/wait.h: sys_wait.in.h + $(AM_V_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_SYS_WAIT_H''@|$(NEXT_SYS_WAIT_H)|g' \ + < $(srcdir)/sys_wait.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += sys/wait.h sys/wait.h-t +MOSTLYCLEANDIRS += sys + +EXTRA_DIST += sys_wait.in.h + +## end gnulib module sys_wait + +## begin gnulib module sysexits + +BUILT_SOURCES += $(SYSEXITS_H) + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +sysexits.h: sysexits.in.h + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ + < $(srcdir)/sysexits.in.h; \ + } > $@-t && \ + mv -f $@-t $@ +MOSTLYCLEANFILES += sysexits.h sysexits.h-t + +EXTRA_DIST += sysexits.in.h + +## end gnulib module sysexits + +## begin gnulib module unistd + +BUILT_SOURCES += unistd.h + +# We need the following in order to create an empty placeholder for +# when the system doesn't have one. +unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ + -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ + -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|g' \ + -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ + -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \ + -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \ + -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \ + -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \ + -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ + -e 's|@''GNULIB_FCHOWNAT''@|$(GNULIB_FCHOWNAT)|g' \ + -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \ + -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ + -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ + -e 's|@''GNULIB_GETDOMAINNAME''@|$(GNULIB_GETDOMAINNAME)|g' \ + -e 's|@''GNULIB_GETDTABLESIZE''@|$(GNULIB_GETDTABLESIZE)|g' \ + -e 's|@''GNULIB_GETGROUPS''@|$(GNULIB_GETGROUPS)|g' \ + -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \ + -e 's|@''GNULIB_GETLOGIN''@|$(GNULIB_GETLOGIN)|g' \ + -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ + -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \ + -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \ + -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ + -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \ + -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \ + -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ + -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \ + -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \ + -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \ + -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ + -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \ + -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \ + -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ + -e 's|@''GNULIB_SYMLINK''@|$(GNULIB_SYMLINK)|g' \ + -e 's|@''GNULIB_SYMLINKAT''@|$(GNULIB_SYMLINKAT)|g' \ + -e 's|@''GNULIB_TTYNAME_R''@|$(GNULIB_TTYNAME_R)|g' \ + -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \ + -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \ + -e 's|@''GNULIB_UNLINK''@|$(GNULIB_UNLINK)|g' \ + -e 's|@''GNULIB_UNLINKAT''@|$(GNULIB_UNLINKAT)|g' \ + -e 's|@''GNULIB_USLEEP''@|$(GNULIB_USLEEP)|g' \ + -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \ + < $(srcdir)/unistd.in.h | \ + sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ + -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ + -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ + -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \ + -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ + -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ + -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \ + -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ + -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ + -e 's|@''HAVE_GETDOMAINNAME''@|$(HAVE_GETDOMAINNAME)|g' \ + -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ + -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ + -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ + -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \ + -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ + -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \ + -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \ + -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \ + -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \ + -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \ + -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \ + -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ + -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \ + -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ + -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \ + -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \ + -e 's|@''HAVE_TTYNAME_R''@|$(HAVE_TTYNAME_R)|g' \ + -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \ + -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \ + -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \ + -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ + -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \ + -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \ + -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \ + -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ + -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ + -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ + -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ + -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ + -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ + -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ + -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ + -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ + -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ + -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ + -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \ + -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \ + -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \ + -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \ + -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ + -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ + -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \ + -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \ + -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \ + -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \ + -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \ + -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \ + -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \ + -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += unistd.h unistd.h-t + +EXTRA_DIST += unistd.in.h + +## end gnulib module unistd + +## begin gnulib module vasnprintf + + +EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h + +EXTRA_libgnu_a_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c + +## end gnulib module vasnprintf + +## begin gnulib module verify + +libgnu_a_SOURCES += verify.h + +## end gnulib module verify + +## begin gnulib module vsnprintf + + +EXTRA_DIST += vsnprintf.c + +EXTRA_libgnu_a_SOURCES += vsnprintf.c + +## end gnulib module vsnprintf + +## begin gnulib module warn-on-use + +BUILT_SOURCES += warn-on-use.h +# The warn-on-use.h that gets inserted into generated .h files is the same as +# build-aux/warn-on-use.h, except that it has the copyright header cut off. +warn-on-use.h: $(top_srcdir)/build-aux/warn-on-use.h + $(AM_V_GEN)rm -f $@-t $@ && \ + sed -n -e '/^.ifndef/,$$p' \ + < $(top_srcdir)/build-aux/warn-on-use.h \ + > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t + +WARN_ON_USE_H=warn-on-use.h + +EXTRA_DIST += $(top_srcdir)/build-aux/warn-on-use.h + +## end gnulib module warn-on-use + +## begin gnulib module wchar + +BUILT_SOURCES += wchar.h + +# We need the following in order to create when the system +# version does not work standalone. +wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ + -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ + -e 's|@''GNULIB_BTOWC''@|$(GNULIB_BTOWC)|g' \ + -e 's|@''GNULIB_WCTOB''@|$(GNULIB_WCTOB)|g' \ + -e 's|@''GNULIB_MBSINIT''@|$(GNULIB_MBSINIT)|g' \ + -e 's|@''GNULIB_MBRTOWC''@|$(GNULIB_MBRTOWC)|g' \ + -e 's|@''GNULIB_MBRLEN''@|$(GNULIB_MBRLEN)|g' \ + -e 's|@''GNULIB_MBSRTOWCS''@|$(GNULIB_MBSRTOWCS)|g' \ + -e 's|@''GNULIB_MBSNRTOWCS''@|$(GNULIB_MBSNRTOWCS)|g' \ + -e 's|@''GNULIB_WCRTOMB''@|$(GNULIB_WCRTOMB)|g' \ + -e 's|@''GNULIB_WCSRTOMBS''@|$(GNULIB_WCSRTOMBS)|g' \ + -e 's|@''GNULIB_WCSNRTOMBS''@|$(GNULIB_WCSNRTOMBS)|g' \ + -e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \ + -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ + -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ + -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ + -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ + -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \ + -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \ + -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \ + -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ + -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ + -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ + -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \ + -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ + -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ + -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ + -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ + -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ + -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \ + -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \ + -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \ + -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ + -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ + -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ + -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ + -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/wchar.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += wchar.h wchar.h-t + +EXTRA_DIST += wchar.in.h + +## end gnulib module wchar + +## begin gnulib module wcrtomb + + +EXTRA_DIST += wcrtomb.c + +EXTRA_libgnu_a_SOURCES += wcrtomb.c + +## end gnulib module wcrtomb + +## begin gnulib module wctype + +BUILT_SOURCES += wctype.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +wctype.h: wctype.in.h $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ + -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \ + -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ + -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ + -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ + -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/wctype.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += wctype.h wctype.h-t + +EXTRA_DIST += wctype.in.h + +## end gnulib module wctype + +## begin gnulib module xsize + +libgnu_a_SOURCES += xsize.h + +## end gnulib module xsize + + +mostlyclean-local: mostlyclean-generic + @for dir in '' $(MOSTLYCLEANDIRS); do \ + if test -n "$$dir" && test -d $$dir; then \ + echo "rmdir $$dir"; rmdir $$dir; \ + fi; \ + done; \ + : diff --git a/grub-core/gnulib/alloca.c b/grub-core/gnulib/alloca.c new file mode 100644 index 000000000..75afdb960 --- /dev/null +++ b/grub-core/gnulib/alloca.c @@ -0,0 +1,489 @@ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#include + +#include + +#include +#include + +#ifdef emacs +# include "lisp.h" +# include "blockinput.h" +# ifdef EMACS_FREE +# undef free +# define free EMACS_FREE +# endif +#else +# define memory_full() abort () +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +# ifndef alloca + +# ifdef emacs +# ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +# ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +/* Using #error here is not wise since this file should work for + old and obscure compilers. */ +# endif /* STACK_DIRECTION undefined */ +# endif /* static */ +# endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +# if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +# else +# define ADDRESS_FUNCTION(arg) &(arg) +# endif + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +# ifndef STACK_DIRECTION +# define STACK_DIRECTION 0 /* Direction unknown. */ +# endif + +# if STACK_DIRECTION != 0 + +# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +# else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +# define STACK_DIR stack_dir + +static void +find_stack_direction (void) +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +# endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +# ifndef ALIGN_SIZE +# define ALIGN_SIZE sizeof(double) +# endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +void * +alloca (size_t size) +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +# if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +# endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + +# ifdef emacs + BLOCK_INPUT; +# endif + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free (hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + +# ifdef emacs + UNBLOCK_INPUT; +# endif + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + /* Address of header. */ + register header *new; + + size_t combined_size = sizeof (header) + size; + if (combined_size < sizeof (header)) + memory_full (); + + new = malloc (combined_size); + + if (! new) + memory_full (); + + new->h.next = last_alloca_header; + new->h.deep = depth; + + last_alloca_header = new; + + /* User storage begins just after header. */ + + return (void *) (new + 1); + } +} + +# if defined (CRAY) && defined (CRAY_STACKSEG_END) + +# ifdef DEBUG_I00AFUNC +# include +# endif + +# ifndef CRAY_STACK +# define CRAY_STACK +# ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +# else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +# endif /* CRAY2 */ +# endif /* not CRAY_STACK */ + +# ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +# else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +# ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +# endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +# ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +# endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +# endif /* not CRAY2 */ +# endif /* CRAY */ + +# endif /* no alloca */ +#endif /* not GCC version 3 */ diff --git a/grub-core/gnulib/alloca.h b/grub-core/gnulib/alloca.in.h similarity index 96% rename from grub-core/gnulib/alloca.h rename to grub-core/gnulib/alloca.in.h index 107534e98..44f20b7a1 100644 --- a/grub-core/gnulib/alloca.h +++ b/grub-core/gnulib/alloca.in.h @@ -5,7 +5,7 @@ This program 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 2, or (at your option) + by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/asnprintf.c b/grub-core/gnulib/asnprintf.c new file mode 100644 index 000000000..3bd2229d5 --- /dev/null +++ b/grub-core/gnulib/asnprintf.c @@ -0,0 +1,35 @@ +/* Formatted output to strings. + Copyright (C) 1999, 2002, 2006, 2009, 2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include "vasnprintf.h" + +#include + +char * +asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) +{ + va_list args; + char *result; + + va_start (args, format); + result = vasnprintf (resultbuf, lengthp, format, args); + va_end (args); + return result; +} diff --git a/grub-core/gnulib/basename.c b/grub-core/gnulib/basename.c deleted file mode 100644 index 24da93ac4..000000000 --- a/grub-core/gnulib/basename.c +++ /dev/null @@ -1,58 +0,0 @@ -/* basename.c -- return the last element in a file name - - Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2010 Free Software - Foundation, Inc. - - This program 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. - - This program 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 this program. If not, see . */ - -#include - -#include "dirname.h" - -#include -#include "xalloc.h" -#include "xstrndup.h" - -char * -base_name (char const *name) -{ - char const *base = last_component (name); - size_t length; - - /* If there is no last component, then name is a file system root or the - empty string. */ - if (! *base) - return xstrndup (name, base_len (name)); - - /* Collapse a sequence of trailing slashes into one. */ - length = base_len (base); - if (ISSLASH (base[length])) - length++; - - /* On systems with drive letters, `a/b:c' must return `./b:c' rather - than `b:c' to avoid confusion with a drive letter. On systems - with pure POSIX semantics, this is not an issue. */ - if (FILE_SYSTEM_PREFIX_LEN (base)) - { - char *p = xmalloc (length + 3); - p[0] = '.'; - p[1] = '/'; - memcpy (p + 2, base, length); - p[length + 2] = '\0'; - return p; - } - - /* Finally, copy the basename. */ - return xstrndup (base, length); -} diff --git a/grub-core/gnulib/dirname.c b/grub-core/gnulib/btowc.c similarity index 57% rename from grub-core/gnulib/dirname.c rename to grub-core/gnulib/btowc.c index 953a9acc3..8744602aa 100644 --- a/grub-core/gnulib/dirname.c +++ b/grub-core/gnulib/btowc.c @@ -1,7 +1,6 @@ -/* dirname.c -- return all but the last element in a file name - - Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2010 Free Software - Foundation, Inc. +/* Convert unibyte character to wide character. + Copyright (C) 2008, 2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,21 +17,23 @@ #include -#include "dirname.h" +/* Specification. */ +#include +#include #include -#include -#include "xalloc.h" -/* Just like mdir_name (dirname-lgpl.c), except, rather than - returning NULL upon malloc failure, here, we report the - "memory exhausted" condition and exit. */ - -char * -dir_name (char const *file) +wint_t +btowc (int c) { - char *result = mdir_name (file); - if (!result) - xalloc_die (); - return result; + if (c != EOF) + { + char buf[1]; + wchar_t wc; + + buf[0] = c; + if (mbtowc (&wc, buf, 1) >= 0) + return wc; + } + return WEOF; } diff --git a/grub-core/gnulib/config.charset b/grub-core/gnulib/config.charset new file mode 100644 index 000000000..aa7d00dba --- /dev/null +++ b/grub-core/gnulib/config.charset @@ -0,0 +1,683 @@ +#! /bin/sh +# Output a system dependent table of character encoding aliases. +# +# Copyright (C) 2000-2004, 2006-2010 Free Software Foundation, Inc. +# +# This program 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, or (at your option) +# any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The table consists of lines of the form +# ALIAS CANONICAL +# +# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". +# ALIAS is compared in a case sensitive way. +# +# CANONICAL is the GNU canonical name for this character encoding. +# It must be an encoding supported by libiconv. Support by GNU libc is +# also desirable. CANONICAL is case insensitive. Usually an upper case +# MIME charset name is preferred. +# The current list of GNU canonical charset names is as follows. +# +# name MIME? used by which systems +# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin +# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +# ISO-8859-3 Y glibc solaris cygwin +# ISO-8859-4 Y osf solaris freebsd netbsd openbsd darwin +# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +# ISO-8859-6 Y glibc aix hpux solaris cygwin +# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin +# ISO-8859-8 Y glibc aix hpux osf solaris cygwin +# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin cygwin +# ISO-8859-13 glibc netbsd openbsd darwin cygwin +# ISO-8859-14 glibc cygwin +# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin +# KOI8-R Y glibc solaris freebsd netbsd openbsd darwin +# KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin +# KOI8-T glibc +# CP437 dos +# CP775 dos +# CP850 aix osf dos +# CP852 dos +# CP855 dos +# CP856 aix +# CP857 dos +# CP861 dos +# CP862 dos +# CP864 dos +# CP865 dos +# CP866 freebsd netbsd openbsd darwin dos +# CP869 dos +# CP874 woe32 dos +# CP922 aix +# CP932 aix cygwin woe32 dos +# CP943 aix +# CP949 osf darwin woe32 dos +# CP950 woe32 dos +# CP1046 aix +# CP1124 aix +# CP1125 dos +# CP1129 aix +# CP1131 darwin +# CP1250 woe32 +# CP1251 glibc solaris netbsd openbsd darwin cygwin woe32 +# CP1252 aix woe32 +# CP1253 woe32 +# CP1254 woe32 +# CP1255 glibc woe32 +# CP1256 woe32 +# CP1257 woe32 +# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin +# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin +# EUC-TW glibc aix hpux irix osf solaris netbsd +# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin +# BIG5-HKSCS glibc solaris darwin +# GBK glibc aix osf solaris darwin cygwin woe32 dos +# GB18030 glibc solaris netbsd darwin +# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin +# JOHAB glibc solaris woe32 +# TIS-620 glibc aix hpux osf solaris cygwin +# VISCII Y glibc +# TCVN5712-1 glibc +# ARMSCII-8 glibc darwin +# GEORGIAN-PS glibc cygwin +# PT154 glibc +# HP-ROMAN8 hpux +# HP-ARABIC8 hpux +# HP-GREEK8 hpux +# HP-HEBREW8 hpux +# HP-TURKISH8 hpux +# HP-KANA8 hpux +# DEC-KANJI osf +# DEC-HANYU osf +# UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin +# +# Note: Names which are not marked as being a MIME name should not be used in +# Internet protocols for information interchange (mail, news, etc.). +# +# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications +# must understand both names and treat them as equivalent. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + +host="$1" +os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` +echo "# This file contains a table of character encoding aliases," +echo "# suitable for operating system '${os}'." +echo "# It was automatically generated from config.charset." +# List of references, updated during installation: +echo "# Packages using this file: " +case "$os" in + linux-gnulibc1*) + # Linux libc5 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "C ASCII" + echo "POSIX ASCII" + for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ + en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ + en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ + es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ + et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ + fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ + it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ + sv_FI sv_SE; do + echo "$l ISO-8859-1" + echo "$l.iso-8859-1 ISO-8859-1" + echo "$l.iso-8859-15 ISO-8859-15" + echo "$l.iso-8859-15@euro ISO-8859-15" + echo "$l@euro ISO-8859-15" + echo "$l.cp-437 CP437" + echo "$l.cp-850 CP850" + echo "$l.cp-1252 CP1252" + echo "$l.cp-1252@euro CP1252" + #echo "$l.atari-st ATARI-ST" # not a commonly used encoding + echo "$l.utf-8 UTF-8" + echo "$l.utf-8@euro UTF-8" + done + for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ + sl_SI sr sr_CS sr_YU; do + echo "$l ISO-8859-2" + echo "$l.iso-8859-2 ISO-8859-2" + echo "$l.cp-852 CP852" + echo "$l.cp-1250 CP1250" + echo "$l.utf-8 UTF-8" + done + for l in mk mk_MK ru ru_RU; do + echo "$l ISO-8859-5" + echo "$l.iso-8859-5 ISO-8859-5" + echo "$l.koi8-r KOI8-R" + echo "$l.cp-866 CP866" + echo "$l.cp-1251 CP1251" + echo "$l.utf-8 UTF-8" + done + for l in ar ar_SA; do + echo "$l ISO-8859-6" + echo "$l.iso-8859-6 ISO-8859-6" + echo "$l.cp-864 CP864" + #echo "$l.cp-868 CP868" # not a commonly used encoding + echo "$l.cp-1256 CP1256" + echo "$l.utf-8 UTF-8" + done + for l in el el_GR gr gr_GR; do + echo "$l ISO-8859-7" + echo "$l.iso-8859-7 ISO-8859-7" + echo "$l.cp-869 CP869" + echo "$l.cp-1253 CP1253" + echo "$l.cp-1253@euro CP1253" + echo "$l.utf-8 UTF-8" + echo "$l.utf-8@euro UTF-8" + done + for l in he he_IL iw iw_IL; do + echo "$l ISO-8859-8" + echo "$l.iso-8859-8 ISO-8859-8" + echo "$l.cp-862 CP862" + echo "$l.cp-1255 CP1255" + echo "$l.utf-8 UTF-8" + done + for l in tr tr_TR; do + echo "$l ISO-8859-9" + echo "$l.iso-8859-9 ISO-8859-9" + echo "$l.cp-857 CP857" + echo "$l.cp-1254 CP1254" + echo "$l.utf-8 UTF-8" + done + for l in lt lt_LT lv lv_LV; do + #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name + echo "$l ISO-8859-13" + done + for l in ru_UA uk uk_UA; do + echo "$l KOI8-U" + done + for l in zh zh_CN; do + #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name + echo "$l GB2312" + done + for l in ja ja_JP ja_JP.EUC; do + echo "$l EUC-JP" + done + for l in ko ko_KR; do + echo "$l EUC-KR" + done + for l in th th_TH; do + echo "$l TIS-620" + done + for l in fa fa_IR; do + #echo "$l ISIRI-3342" # a broken encoding + echo "$l.utf-8 UTF-8" + done + ;; + linux* | *-gnu*) + # With glibc-2.1 or newer, we don't need any canonicalization, + # because glibc has iconv and both glibc and libiconv support all + # GNU canonical names directly. Therefore, the Makefile does not + # need to install the alias file at all. + # The following applies only to glibc-2.0.x and older libcs. + echo "ISO_646.IRV:1983 ASCII" + ;; + aix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "IBM-850 CP850" + echo "IBM-856 CP856" + echo "IBM-921 ISO-8859-13" + echo "IBM-922 CP922" + echo "IBM-932 CP932" + echo "IBM-943 CP943" + echo "IBM-1046 CP1046" + echo "IBM-1124 CP1124" + echo "IBM-1129 CP1129" + echo "IBM-1252 CP1252" + echo "IBM-eucCN GB2312" + echo "IBM-eucJP EUC-JP" + echo "IBM-eucKR EUC-KR" + echo "IBM-eucTW EUC-TW" + echo "big5 BIG5" + echo "GBK GBK" + echo "TIS-620 TIS-620" + echo "UTF-8 UTF-8" + ;; + hpux*) + echo "iso88591 ISO-8859-1" + echo "iso88592 ISO-8859-2" + echo "iso88595 ISO-8859-5" + echo "iso88596 ISO-8859-6" + echo "iso88597 ISO-8859-7" + echo "iso88598 ISO-8859-8" + echo "iso88599 ISO-8859-9" + echo "iso885915 ISO-8859-15" + echo "roman8 HP-ROMAN8" + echo "arabic8 HP-ARABIC8" + echo "greek8 HP-GREEK8" + echo "hebrew8 HP-HEBREW8" + echo "turkish8 HP-TURKISH8" + echo "kana8 HP-KANA8" + echo "tis620 TIS-620" + echo "big5 BIG5" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "hp15CN GB2312" + #echo "ccdc ?" # what is this? + echo "SJIS SHIFT_JIS" + echo "utf8 UTF-8" + ;; + irix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + ;; + osf*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "cp850 CP850" + echo "big5 BIG5" + echo "dechanyu DEC-HANYU" + echo "dechanzi GB2312" + echo "deckanji DEC-KANJI" + echo "deckorean EUC-KR" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "GBK GBK" + echo "KSC5601 CP949" + echo "sdeckanji EUC-JP" + echo "SJIS SHIFT_JIS" + echo "TACTIS TIS-620" + echo "UTF-8 UTF-8" + ;; + solaris*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-3 ISO-8859-3" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "koi8-r KOI8-R" + echo "ansi-1251 CP1251" + echo "BIG5 BIG5" + echo "Big5-HKSCS BIG5-HKSCS" + echo "gb2312 GB2312" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "cns11643 EUC-TW" + echo "5601 EUC-KR" + echo "ko_KR.johap92 JOHAB" + echo "eucJP EUC-JP" + echo "PCK SHIFT_JIS" + echo "TIS620.2533 TIS-620" + #echo "sun_eu_greek ?" # what is this? + echo "UTF-8 UTF-8" + ;; + freebsd* | os2*) + # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just + # reuse FreeBSD's locale data for OS/2. + echo "C ASCII" + echo "US-ASCII ASCII" + for l in la_LN lt_LN; do + echo "$l.ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ + lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do + echo "$l.ISO_8859-1 ISO-8859-1" + echo "$l.DIS_8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do + echo "$l.ISO_8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO_8859-4 ISO-8859-4" + done + for l in ru_RU ru_SU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO_8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ja_JP.Shift_JIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + netbsd*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "BIG5 BIG5" + echo "SJIS SHIFT_JIS" + ;; + openbsd*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + ;; + darwin[56]*) + # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "C ASCII" + for l in en_AU en_CA en_GB en_US la_LN; do + echo "$l.US-ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ + nl_NL no_NO pt_PT sv_SE; do + echo "$l ISO-8859-1" + echo "$l.ISO8859-1 ISO-8859-1" + echo "$l.ISO8859-15 ISO-8859-15" + done + for l in la_LN; do + echo "$l.ISO8859-1 ISO-8859-1" + echo "$l.ISO8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do + echo "$l.ISO8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO8859-4 ISO-8859-4" + done + for l in ru_RU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + for l in bg_BG; do + echo "$l.CP1251 CP1251" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + darwin*) + # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is + # useless: + # - It returns the empty string when LANG is set to a locale of the + # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 + # LC_CTYPE file. + # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by + # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. + # - The documentation says: + # "... all code that calls BSD system routines should ensure + # that the const *char parameters of these routines are in UTF-8 + # encoding. All BSD system functions expect their string + # parameters to be in UTF-8 encoding and nothing else." + # It also says + # "An additional caveat is that string parameters for files, + # paths, and other file-system entities must be in canonical + # UTF-8. In a canonical UTF-8 Unicode string, all decomposable + # characters are decomposed ..." + # but this is not true: You can pass non-decomposed UTF-8 strings + # to file system functions, and it is the OS which will convert + # them to decomposed UTF-8 before accessing the file system. + # - The Apple Terminal application displays UTF-8 by default. + # - However, other applications are free to use different encodings: + # - xterm uses ISO-8859-1 by default. + # - TextEdit uses MacRoman by default. + # We prefer UTF-8 over decomposed UTF-8-MAC because one should + # minimize the use of decomposed Unicode. Unfortunately, through the + # Darwin file system, decomposed UTF-8 strings are leaked into user + # space nevertheless. + # Then there are also the locales with encodings other than US-ASCII + # and UTF-8. These locales can be occasionally useful to users (e.g. + # when grepping through ISO-8859-1 encoded text files), when all their + # file names are in US-ASCII. + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + echo "KOI8-R KOI8-R" + echo "KOI8-U KOI8-U" + echo "CP866 CP866" + echo "CP949 CP949" + echo "CP1131 CP1131" + echo "CP1251 CP1251" + echo "eucCN GB2312" + echo "GB2312 GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "Big5 BIG5" + echo "Big5HKSCS BIG5-HKSCS" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "SJIS SHIFT_JIS" + echo "ARMSCII-8 ARMSCII-8" + echo "PT154 PT154" + #echo "ISCII-DEV ?" + echo "* UTF-8" + ;; + beos* | haiku*) + # BeOS and Haiku have a single locale, and it has UTF-8 encoding. + echo "* UTF-8" + ;; + msdosdjgpp*) + # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "#" + echo "# The encodings given here may not all be correct." + echo "# If you find that the encoding given for your language and" + echo "# country is not the one your DOS machine actually uses, just" + echo "# correct it in this file, and send a mail to" + echo "# Juan Manuel Guerrero " + echo "# and Bruno Haible ." + echo "#" + echo "C ASCII" + # ISO-8859-1 languages + echo "ca CP850" + echo "ca_ES CP850" + echo "da CP865" # not CP850 ?? + echo "da_DK CP865" # not CP850 ?? + echo "de CP850" + echo "de_AT CP850" + echo "de_CH CP850" + echo "de_DE CP850" + echo "en CP850" + echo "en_AU CP850" # not CP437 ?? + echo "en_CA CP850" + echo "en_GB CP850" + echo "en_NZ CP437" + echo "en_US CP437" + echo "en_ZA CP850" # not CP437 ?? + echo "es CP850" + echo "es_AR CP850" + echo "es_BO CP850" + echo "es_CL CP850" + echo "es_CO CP850" + echo "es_CR CP850" + echo "es_CU CP850" + echo "es_DO CP850" + echo "es_EC CP850" + echo "es_ES CP850" + echo "es_GT CP850" + echo "es_HN CP850" + echo "es_MX CP850" + echo "es_NI CP850" + echo "es_PA CP850" + echo "es_PY CP850" + echo "es_PE CP850" + echo "es_SV CP850" + echo "es_UY CP850" + echo "es_VE CP850" + echo "et CP850" + echo "et_EE CP850" + echo "eu CP850" + echo "eu_ES CP850" + echo "fi CP850" + echo "fi_FI CP850" + echo "fr CP850" + echo "fr_BE CP850" + echo "fr_CA CP850" + echo "fr_CH CP850" + echo "fr_FR CP850" + echo "ga CP850" + echo "ga_IE CP850" + echo "gd CP850" + echo "gd_GB CP850" + echo "gl CP850" + echo "gl_ES CP850" + echo "id CP850" # not CP437 ?? + echo "id_ID CP850" # not CP437 ?? + echo "is CP861" # not CP850 ?? + echo "is_IS CP861" # not CP850 ?? + echo "it CP850" + echo "it_CH CP850" + echo "it_IT CP850" + echo "lt CP775" + echo "lt_LT CP775" + echo "lv CP775" + echo "lv_LV CP775" + echo "nb CP865" # not CP850 ?? + echo "nb_NO CP865" # not CP850 ?? + echo "nl CP850" + echo "nl_BE CP850" + echo "nl_NL CP850" + echo "nn CP865" # not CP850 ?? + echo "nn_NO CP865" # not CP850 ?? + echo "no CP865" # not CP850 ?? + echo "no_NO CP865" # not CP850 ?? + echo "pt CP850" + echo "pt_BR CP850" + echo "pt_PT CP850" + echo "sv CP850" + echo "sv_SE CP850" + # ISO-8859-2 languages + echo "cs CP852" + echo "cs_CZ CP852" + echo "hr CP852" + echo "hr_HR CP852" + echo "hu CP852" + echo "hu_HU CP852" + echo "pl CP852" + echo "pl_PL CP852" + echo "ro CP852" + echo "ro_RO CP852" + echo "sk CP852" + echo "sk_SK CP852" + echo "sl CP852" + echo "sl_SI CP852" + echo "sq CP852" + echo "sq_AL CP852" + echo "sr CP852" # CP852 or CP866 or CP855 ?? + echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? + echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? + # ISO-8859-3 languages + echo "mt CP850" + echo "mt_MT CP850" + # ISO-8859-5 languages + echo "be CP866" + echo "be_BE CP866" + echo "bg CP866" # not CP855 ?? + echo "bg_BG CP866" # not CP855 ?? + echo "mk CP866" # not CP855 ?? + echo "mk_MK CP866" # not CP855 ?? + echo "ru CP866" + echo "ru_RU CP866" + echo "uk CP1125" + echo "uk_UA CP1125" + # ISO-8859-6 languages + echo "ar CP864" + echo "ar_AE CP864" + echo "ar_DZ CP864" + echo "ar_EG CP864" + echo "ar_IQ CP864" + echo "ar_IR CP864" + echo "ar_JO CP864" + echo "ar_KW CP864" + echo "ar_MA CP864" + echo "ar_OM CP864" + echo "ar_QA CP864" + echo "ar_SA CP864" + echo "ar_SY CP864" + # ISO-8859-7 languages + echo "el CP869" + echo "el_GR CP869" + # ISO-8859-8 languages + echo "he CP862" + echo "he_IL CP862" + # ISO-8859-9 languages + echo "tr CP857" + echo "tr_TR CP857" + # Japanese + echo "ja CP932" + echo "ja_JP CP932" + # Chinese + echo "zh_CN GBK" + echo "zh_TW CP950" # not CP938 ?? + # Korean + echo "kr CP949" # not CP934 ?? + echo "kr_KR CP949" # not CP934 ?? + # Thai + echo "th CP874" + echo "th_TH CP874" + # Other + echo "eo CP850" + echo "eo_EO CP850" + ;; +esac diff --git a/grub-core/gnulib/errno.in.h b/grub-core/gnulib/errno.in.h new file mode 100644 index 000000000..140e5d134 --- /dev/null +++ b/grub-core/gnulib/errno.in.h @@ -0,0 +1,160 @@ +/* A POSIX-like . + + Copyright (C) 2008-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_ERRNO_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_ERRNO_H@ + +#ifndef _GL_ERRNO_H +#define _GL_ERRNO_H + + +/* On native Windows platforms, many macros are not defined. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value. */ +# define EWOULDBLOCK EAGAIN + +/* Values >= 100 seem safe to use. */ +# define ETXTBSY 100 +# define GNULIB_defined_ETXTBSY 1 + +/* These are intentionally the same values as the WSA* error numbers, defined + in . */ +# define EINPROGRESS 10036 +# define EALREADY 10037 +# define ENOTSOCK 10038 +# define EDESTADDRREQ 10039 +# define EMSGSIZE 10040 +# define EPROTOTYPE 10041 +# define ENOPROTOOPT 10042 +# define EPROTONOSUPPORT 10043 +# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ +# define EOPNOTSUPP 10045 +# define EPFNOSUPPORT 10046 /* not required by POSIX */ +# define EAFNOSUPPORT 10047 +# define EADDRINUSE 10048 +# define EADDRNOTAVAIL 10049 +# define ENETDOWN 10050 +# define ENETUNREACH 10051 +# define ENETRESET 10052 +# define ECONNABORTED 10053 +# define ECONNRESET 10054 +# define ENOBUFS 10055 +# define EISCONN 10056 +# define ENOTCONN 10057 +# define ESHUTDOWN 10058 /* not required by POSIX */ +# define ETOOMANYREFS 10059 /* not required by POSIX */ +# define ETIMEDOUT 10060 +# define ECONNREFUSED 10061 +# define ELOOP 10062 +# define EHOSTDOWN 10064 /* not required by POSIX */ +# define EHOSTUNREACH 10065 +# define EPROCLIM 10067 /* not required by POSIX */ +# define EUSERS 10068 /* not required by POSIX */ +# define EDQUOT 10069 +# define ESTALE 10070 +# define EREMOTE 10071 /* not required by POSIX */ +# define GNULIB_defined_ESOCK 1 + +# endif + + +/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros + EMULTIHOP, ENOLINK, EOVERFLOW are not defined. */ +# if @EMULTIHOP_HIDDEN@ +# define EMULTIHOP @EMULTIHOP_VALUE@ +# define GNULIB_defined_EMULTIHOP 1 +# endif +# if @ENOLINK_HIDDEN@ +# define ENOLINK @ENOLINK_VALUE@ +# define GNULIB_defined_ENOLINK 1 +# endif +# if @EOVERFLOW_HIDDEN@ +# define EOVERFLOW @EOVERFLOW_VALUE@ +# define GNULIB_defined_EOVERFLOW 1 +# endif + + +/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK, + EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined. + Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151, + HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133. + + Note: When one of these systems defines some of these macros some day, + binaries will have to be recompiled so that they recognizes the new + errno values from the system. */ + +# ifndef ENOMSG +# define ENOMSG 2000 +# define GNULIB_defined_ENOMSG 1 +# endif + +# ifndef EIDRM +# define EIDRM 2001 +# define GNULIB_defined_EIDRM 1 +# endif + +# ifndef ENOLINK +# define ENOLINK 2002 +# define GNULIB_defined_ENOLINK 1 +# endif + +# ifndef EPROTO +# define EPROTO 2003 +# define GNULIB_defined_EPROTO 1 +# endif + +# ifndef EMULTIHOP +# define EMULTIHOP 2004 +# define GNULIB_defined_EMULTIHOP 1 +# endif + +# ifndef EBADMSG +# define EBADMSG 2005 +# define GNULIB_defined_EBADMSG 1 +# endif + +# ifndef EOVERFLOW +# define EOVERFLOW 2006 +# define GNULIB_defined_EOVERFLOW 1 +# endif + +# ifndef ENOTSUP +# define ENOTSUP 2007 +# define GNULIB_defined_ENOTSUP 1 +# endif + +# ifndef ESTALE +# define ESTALE 2009 +# define GNULIB_defined_ESTALE 1 +# endif + +# ifndef ECANCELED +# define ECANCELED 2008 +# define GNULIB_defined_ECANCELED 1 +# endif + + +#endif /* _GL_ERRNO_H */ +#endif /* _GL_ERRNO_H */ diff --git a/grub-core/gnulib/float+.h b/grub-core/gnulib/float+.h new file mode 100644 index 000000000..b55e5e6de --- /dev/null +++ b/grub-core/gnulib/float+.h @@ -0,0 +1,148 @@ +/* Supplemental information about the floating-point formats. + Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2007. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _FLOATPLUS_H +#define _FLOATPLUS_H + +#include +#include + +/* Number of bits in the mantissa of a floating-point number, including the + "hidden bit". */ +#if FLT_RADIX == 2 +# define FLT_MANT_BIT FLT_MANT_DIG +# define DBL_MANT_BIT DBL_MANT_DIG +# define LDBL_MANT_BIT LDBL_MANT_DIG +#elif FLT_RADIX == 4 +# define FLT_MANT_BIT (FLT_MANT_DIG * 2) +# define DBL_MANT_BIT (DBL_MANT_DIG * 2) +# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2) +#elif FLT_RADIX == 16 +# define FLT_MANT_BIT (FLT_MANT_DIG * 4) +# define DBL_MANT_BIT (DBL_MANT_DIG * 4) +# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4) +#endif + +/* Bit mask that can be used to mask the exponent, as an unsigned number. */ +#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7) +#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) +#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7) + +/* Number of bits used for the exponent of a floating-point number, including + the exponent's sign. */ +#define FLT_EXP_BIT \ + (FLT_EXP_MASK < 0x100 ? 8 : \ + FLT_EXP_MASK < 0x200 ? 9 : \ + FLT_EXP_MASK < 0x400 ? 10 : \ + FLT_EXP_MASK < 0x800 ? 11 : \ + FLT_EXP_MASK < 0x1000 ? 12 : \ + FLT_EXP_MASK < 0x2000 ? 13 : \ + FLT_EXP_MASK < 0x4000 ? 14 : \ + FLT_EXP_MASK < 0x8000 ? 15 : \ + FLT_EXP_MASK < 0x10000 ? 16 : \ + FLT_EXP_MASK < 0x20000 ? 17 : \ + FLT_EXP_MASK < 0x40000 ? 18 : \ + FLT_EXP_MASK < 0x80000 ? 19 : \ + FLT_EXP_MASK < 0x100000 ? 20 : \ + FLT_EXP_MASK < 0x200000 ? 21 : \ + FLT_EXP_MASK < 0x400000 ? 22 : \ + FLT_EXP_MASK < 0x800000 ? 23 : \ + FLT_EXP_MASK < 0x1000000 ? 24 : \ + FLT_EXP_MASK < 0x2000000 ? 25 : \ + FLT_EXP_MASK < 0x4000000 ? 26 : \ + FLT_EXP_MASK < 0x8000000 ? 27 : \ + FLT_EXP_MASK < 0x10000000 ? 28 : \ + FLT_EXP_MASK < 0x20000000 ? 29 : \ + FLT_EXP_MASK < 0x40000000 ? 30 : \ + FLT_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) +#define DBL_EXP_BIT \ + (DBL_EXP_MASK < 0x100 ? 8 : \ + DBL_EXP_MASK < 0x200 ? 9 : \ + DBL_EXP_MASK < 0x400 ? 10 : \ + DBL_EXP_MASK < 0x800 ? 11 : \ + DBL_EXP_MASK < 0x1000 ? 12 : \ + DBL_EXP_MASK < 0x2000 ? 13 : \ + DBL_EXP_MASK < 0x4000 ? 14 : \ + DBL_EXP_MASK < 0x8000 ? 15 : \ + DBL_EXP_MASK < 0x10000 ? 16 : \ + DBL_EXP_MASK < 0x20000 ? 17 : \ + DBL_EXP_MASK < 0x40000 ? 18 : \ + DBL_EXP_MASK < 0x80000 ? 19 : \ + DBL_EXP_MASK < 0x100000 ? 20 : \ + DBL_EXP_MASK < 0x200000 ? 21 : \ + DBL_EXP_MASK < 0x400000 ? 22 : \ + DBL_EXP_MASK < 0x800000 ? 23 : \ + DBL_EXP_MASK < 0x1000000 ? 24 : \ + DBL_EXP_MASK < 0x2000000 ? 25 : \ + DBL_EXP_MASK < 0x4000000 ? 26 : \ + DBL_EXP_MASK < 0x8000000 ? 27 : \ + DBL_EXP_MASK < 0x10000000 ? 28 : \ + DBL_EXP_MASK < 0x20000000 ? 29 : \ + DBL_EXP_MASK < 0x40000000 ? 30 : \ + DBL_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) +#define LDBL_EXP_BIT \ + (LDBL_EXP_MASK < 0x100 ? 8 : \ + LDBL_EXP_MASK < 0x200 ? 9 : \ + LDBL_EXP_MASK < 0x400 ? 10 : \ + LDBL_EXP_MASK < 0x800 ? 11 : \ + LDBL_EXP_MASK < 0x1000 ? 12 : \ + LDBL_EXP_MASK < 0x2000 ? 13 : \ + LDBL_EXP_MASK < 0x4000 ? 14 : \ + LDBL_EXP_MASK < 0x8000 ? 15 : \ + LDBL_EXP_MASK < 0x10000 ? 16 : \ + LDBL_EXP_MASK < 0x20000 ? 17 : \ + LDBL_EXP_MASK < 0x40000 ? 18 : \ + LDBL_EXP_MASK < 0x80000 ? 19 : \ + LDBL_EXP_MASK < 0x100000 ? 20 : \ + LDBL_EXP_MASK < 0x200000 ? 21 : \ + LDBL_EXP_MASK < 0x400000 ? 22 : \ + LDBL_EXP_MASK < 0x800000 ? 23 : \ + LDBL_EXP_MASK < 0x1000000 ? 24 : \ + LDBL_EXP_MASK < 0x2000000 ? 25 : \ + LDBL_EXP_MASK < 0x4000000 ? 26 : \ + LDBL_EXP_MASK < 0x8000000 ? 27 : \ + LDBL_EXP_MASK < 0x10000000 ? 28 : \ + LDBL_EXP_MASK < 0x20000000 ? 29 : \ + LDBL_EXP_MASK < 0x40000000 ? 30 : \ + LDBL_EXP_MASK <= 0x7fffffff ? 31 : \ + 32) + +/* Number of bits used for a floating-point number: the mantissa (not + counting the "hidden bit", since it may or may not be explicit), the + exponent, and the sign. */ +#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1) +#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1) +#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1) + +/* Number of bytes used for a floating-point number. + This can be smaller than the 'sizeof'. For example, on i386 systems, + 'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence + LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but + sizeof (long double) = 12 or = 16. */ +#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) +#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) +#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) + +/* Verify that SIZEOF_FLT <= sizeof (float) etc. */ +typedef int verify_sizeof_flt[2 * (SIZEOF_FLT <= sizeof (float)) - 1]; +typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1]; +typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1]; + +#endif /* _FLOATPLUS_H */ diff --git a/grub-core/gnulib/float.in.h b/grub-core/gnulib/float.in.h new file mode 100644 index 000000000..caf822f1d --- /dev/null +++ b/grub-core/gnulib/float.in.h @@ -0,0 +1,62 @@ +/* A correct . + + Copyright (C) 2007-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +#ifndef _GL_FLOAT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_FLOAT_H@ + +#ifndef _GL_FLOAT_H +#define _GL_FLOAT_H + +/* 'long double' properties. */ +#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) +/* Number of mantissa units, in base FLT_RADIX. */ +# undef LDBL_MANT_DIG +# define LDBL_MANT_DIG 64 +/* Number of decimal digits that is sufficient for representing a number. */ +# undef LDBL_DIG +# define LDBL_DIG 18 +/* x-1 where x is the smallest representable number > 1. */ +# undef LDBL_EPSILON +# define LDBL_EPSILON 1.0842021724855044340E-19L +/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ +# undef LDBL_MIN_EXP +# define LDBL_MIN_EXP (-16381) +/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ +# undef LDBL_MAX_EXP +# define LDBL_MAX_EXP 16384 +/* Minimum positive normalized number. */ +# undef LDBL_MIN +# define LDBL_MIN 3.3621031431120935063E-4932L +/* Maximum representable finite number. */ +# undef LDBL_MAX +# define LDBL_MAX 1.1897314953572317650E+4932L +/* Minimum e such that 10^e is in the range of normalized numbers. */ +# undef LDBL_MIN_10_EXP +# define LDBL_MIN_10_EXP (-4931) +/* Maximum e such that 10^e is in the range of representable finite numbers. */ +# undef LDBL_MAX_10_EXP +# define LDBL_MAX_10_EXP 4932 +#endif + +#endif /* _GL_FLOAT_H */ +#endif /* _GL_FLOAT_H */ diff --git a/grub-core/gnulib/fnmatch.c b/grub-core/gnulib/fnmatch.c index f15dbb806..d73e47dae 100644 --- a/grub-core/gnulib/fnmatch.c +++ b/grub-core/gnulib/fnmatch.c @@ -3,7 +3,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/fnmatch.h b/grub-core/gnulib/fnmatch.in.h similarity index 63% rename from grub-core/gnulib/fnmatch.h rename to grub-core/gnulib/fnmatch.in.h index b086b45aa..8caab1959 100644 --- a/grub-core/gnulib/fnmatch.h +++ b/grub-core/gnulib/fnmatch.in.h @@ -1,11 +1,11 @@ /* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003, - 2005, 2007 Free Software Foundation, Inc. + 2005, 2007, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef _FNMATCH_H -#define _FNMATCH_H 1 +#ifndef _FNMATCH_H +#define _FNMATCH_H 1 + +/* The definition of _GL_ARG_NONNULL is copied here. */ #ifdef __cplusplus extern "C" { @@ -26,37 +28,38 @@ extern "C" { /* We #undef these before defining them because some losing systems (HP-UX A.08.07 for example) define these in . */ -#undef FNM_PATHNAME -#undef FNM_NOESCAPE -#undef FNM_PERIOD +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD /* Bits set in the FLAGS argument to `fnmatch'. */ -#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ -#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ -#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ #if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE -# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ -# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ -# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ -# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ +# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ #endif /* Value returned by `fnmatch' if STRING does not match PATTERN. */ -#define FNM_NOMATCH 1 +#define FNM_NOMATCH 1 /* This value is returned if the implementation does not support `fnmatch'. Since this is not the case here it will never be returned but the conformance test suites still require the symbol to be defined. */ #ifdef _XOPEN_SOURCE -# define FNM_NOSYS (-1) +# define FNM_NOSYS (-1) #endif /* Match NAME against the file name pattern PATTERN, returning zero if it matches, FNM_NOMATCH if not. */ extern int fnmatch (const char *__pattern, const char *__name, - int __flags); + int __flags) + _GL_ARG_NONNULL ((1, 2)); #ifdef __cplusplus } diff --git a/grub-core/gnulib/fnmatch_loop.c b/grub-core/gnulib/fnmatch_loop.c index 8cd444404..741c993ef 100644 --- a/grub-core/gnulib/fnmatch_loop.c +++ b/grub-core/gnulib/fnmatch_loop.c @@ -4,7 +4,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/getdelim.c b/grub-core/gnulib/getdelim.c index c0240900c..66d07b9ae 100644 --- a/grub-core/gnulib/getdelim.c +++ b/grub-core/gnulib/getdelim.c @@ -4,7 +4,7 @@ This program 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 2, or (at + published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but diff --git a/grub-core/gnulib/getline.c b/grub-core/gnulib/getline.c index 6cf187be2..30c076e87 100644 --- a/grub-core/gnulib/getline.c +++ b/grub-core/gnulib/getline.c @@ -3,7 +3,7 @@ This program 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 2, or (at + published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but @@ -21,7 +21,6 @@ #include #include -#include ssize_t getline (char **lineptr, size_t *n, FILE *stream) diff --git a/grub-core/gnulib/getopt.h b/grub-core/gnulib/getopt.in.h similarity index 80% rename from grub-core/gnulib/getopt.h rename to grub-core/gnulib/getopt.in.h index d2d3e6e63..57a8e8992 100644 --- a/grub-core/gnulib/getopt.h +++ b/grub-core/gnulib/getopt.in.h @@ -1,6 +1,6 @@ /* Declarations for getopt. - Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007 - Free Software Foundation, Inc. + Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2010 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -16,24 +16,42 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef _GETOPT_H +#ifndef _GL_GETOPT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. We must + also inform the replacement unistd.h to not recursively use + ; our definitions will be present soon enough. */ +#if @HAVE_GETOPT_H@ +# define _GL_SYSTEM_GETOPT +# @INCLUDE_NEXT@ @NEXT_GETOPT_H@ +# undef _GL_SYSTEM_GETOPT +#endif + +#ifndef _GL_GETOPT_H #ifndef __need_getopt -# define _GETOPT_H 1 +# define _GL_GETOPT_H 1 #endif /* Standalone applications should #define __GETOPT_PREFIX to an identifier that prefixes the external functions and variables defined in this header. When this happens, include the headers that might declare getopt so that they will not cause - confusion if included after this file. Then systematically rename + confusion if included after this file (if the system had , + we have already included it). Then systematically rename identifiers so that they do not collide with the system functions and variables. Renaming avoids problems with some compilers and linkers. */ #if defined __GETOPT_PREFIX && !defined __need_getopt -# include -# include -# include +# if !@HAVE_GETOPT_H@ +# include +# include +# include +# endif # undef __need_getopt # undef getopt # undef getopt_long @@ -42,6 +60,7 @@ # undef opterr # undef optind # undef optopt +# undef option # define __GETOPT_CONCAT(x, y) x ## y # define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) # define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) @@ -52,6 +71,8 @@ # define opterr __GETOPT_ID (opterr) # define optind __GETOPT_ID (optind) # define optopt __GETOPT_ID (optopt) +# define option __GETOPT_ID (option) +# define _getopt_internal __GETOPT_ID (getopt_internal) #endif /* Standalone applications get correct prototypes for getopt_long and @@ -94,12 +115,14 @@ # define __GNUC_PREREQ(maj, min) (0) # endif # if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () +# define __THROW throw () # else # define __THROW # endif #endif +/* The definition of _GL_ARG_NONNULL is copied here. */ + #ifdef __cplusplus extern "C" { #endif @@ -142,9 +165,9 @@ extern int optopt; zero. The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but @@ -169,10 +192,10 @@ struct option /* Names for the values of the `has_arg' field of `struct option'. */ -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ /* Get definitions and prototypes for functions to process the @@ -201,17 +224,17 @@ struct option the environment, then do not permute arguments. */ extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __THROW; + __THROW _GL_ARG_NONNULL ((2, 3)); #ifndef __need_getopt extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; + const char *__shortopts, + const struct option *__longopts, int *__longind) + __THROW _GL_ARG_NONNULL ((2, 3)); #endif @@ -223,3 +246,4 @@ extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, #undef __need_getopt #endif /* getopt.h */ +#endif /* getopt.h */ diff --git a/grub-core/gnulib/gettext.h b/grub-core/gnulib/gettext.h index 6a069c448..881ae3304 100644 --- a/grub-core/gnulib/gettext.h +++ b/grub-core/gnulib/gettext.h @@ -4,7 +4,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/intprops.h b/grub-core/gnulib/intprops.h new file mode 100644 index 000000000..46f4d47d7 --- /dev/null +++ b/grub-core/gnulib/intprops.h @@ -0,0 +1,83 @@ +/* intprops.h -- properties of integer types + + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009, 2010 Free Software + Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +/* Written by Paul Eggert. */ + +#ifndef GL_INTPROPS_H +# define GL_INTPROPS_H + +# include + +/* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + +/* True if the arithmetic type T is an integer type. bool counts as + an integer. */ +# define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) + +/* True if negative values of the signed integer type T use two's + complement, ones' complement, or signed magnitude representation, + respectively. Much GNU code assumes two's complement, but some + people like to be portable to all possible C hosts. */ +# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) +# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) +# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) + +/* True if the arithmetic type T is signed. */ +# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* The maximum and minimum values for the integer type T. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ +# define TYPE_MINIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) 0 \ + : TYPE_SIGNED_MAGNITUDE (t) \ + ? ~ (t) 0 \ + : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) +# define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) + +/* Return zero if T can be determined to be an unsigned type. + Otherwise, return 1. + When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a + tighter bound. Otherwise, it overestimates the true bound by one byte + when applied to unsigned types of size 2, 4, 16, ... bytes. + The symbol signed_type_or_expr__ is private to this header file. */ +# if __GNUC__ >= 2 +# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t)) +# else +# define signed_type_or_expr__(t) 1 +# endif + +/* Bound on length of the string representing an integer type or expression T. + Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485; + add 1 for integer division truncation; add 1 more for a minus sign + if needed. */ +# define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \ + + signed_type_or_expr__ (t) + 1) + +/* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +# define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + +#endif /* GL_INTPROPS_H */ diff --git a/grub-core/gnulib/langinfo.in.h b/grub-core/gnulib/langinfo.in.h new file mode 100644 index 000000000..3a92647b9 --- /dev/null +++ b/grub-core/gnulib/langinfo.in.h @@ -0,0 +1,173 @@ +/* Substitute for and wrapper around . + Copyright (C) 2009, 2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* + * POSIX for platforms that lack it or have an incomplete one. + * + */ + +#ifndef _GL_LANGINFO_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_LANGINFO_H@ +# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@ +#endif + +#ifndef _GL_LANGINFO_H +#define _GL_LANGINFO_H + + +#if !@HAVE_LANGINFO_H@ + +/* A platform that lacks . */ + +/* Assume that it also lacks and the nl_item type. */ +typedef int nl_item; + +/* nl_langinfo items of the LC_CTYPE category */ +# define CODESET 10000 +/* nl_langinfo items of the LC_NUMERIC category */ +# define RADIXCHAR 10001 +# define THOUSEP 10002 +/* nl_langinfo items of the LC_TIME category */ +# define D_T_FMT 10003 +# define D_FMT 10004 +# define T_FMT 10005 +# define T_FMT_AMPM 10006 +# define AM_STR 10007 +# define PM_STR 10008 +# define DAY_1 10009 +# define DAY_2 (DAY_1 + 1) +# define DAY_3 (DAY_1 + 2) +# define DAY_4 (DAY_1 + 3) +# define DAY_5 (DAY_1 + 4) +# define DAY_6 (DAY_1 + 5) +# define DAY_7 (DAY_1 + 6) +# define ABDAY_1 10016 +# define ABDAY_2 (ABDAY_1 + 1) +# define ABDAY_3 (ABDAY_1 + 2) +# define ABDAY_4 (ABDAY_1 + 3) +# define ABDAY_5 (ABDAY_1 + 4) +# define ABDAY_6 (ABDAY_1 + 5) +# define ABDAY_7 (ABDAY_1 + 6) +# define MON_1 10023 +# define MON_2 (MON_1 + 1) +# define MON_3 (MON_1 + 2) +# define MON_4 (MON_1 + 3) +# define MON_5 (MON_1 + 4) +# define MON_6 (MON_1 + 5) +# define MON_7 (MON_1 + 6) +# define MON_8 (MON_1 + 7) +# define MON_9 (MON_1 + 8) +# define MON_10 (MON_1 + 9) +# define MON_11 (MON_1 + 10) +# define MON_12 (MON_1 + 11) +# define ABMON_1 10035 +# define ABMON_2 (ABMON_1 + 1) +# define ABMON_3 (ABMON_1 + 2) +# define ABMON_4 (ABMON_1 + 3) +# define ABMON_5 (ABMON_1 + 4) +# define ABMON_6 (ABMON_1 + 5) +# define ABMON_7 (ABMON_1 + 6) +# define ABMON_8 (ABMON_1 + 7) +# define ABMON_9 (ABMON_1 + 8) +# define ABMON_10 (ABMON_1 + 9) +# define ABMON_11 (ABMON_1 + 10) +# define ABMON_12 (ABMON_1 + 11) +# define ERA 10047 +# define ERA_D_FMT 10048 +# define ERA_D_T_FMT 10049 +# define ERA_T_FMT 10050 +# define ALT_DIGITS 10051 +/* nl_langinfo items of the LC_MONETARY category */ +# define CRNCYSTR 10052 +/* nl_langinfo items of the LC_MESSAGES category */ +# define YESEXPR 10053 +# define NOEXPR 10054 + +#else + +/* A platform that has . */ + +# if !@HAVE_LANGINFO_CODESET@ +# define CODESET 10000 +# define GNULIB_defined_CODESET 1 +# endif + +# if !@HAVE_LANGINFO_T_FMT_AMPM@ +# define T_FMT_AMPM 10006 +# define GNULIB_defined_T_FMT_AMPM 1 +# endif + +# if !@HAVE_LANGINFO_ERA@ +# define ERA 10047 +# define ERA_D_FMT 10048 +# define ERA_D_T_FMT 10049 +# define ERA_T_FMT 10050 +# define ALT_DIGITS 10051 +# define GNULIB_defined_ERA 1 +# endif + +# if !@HAVE_LANGINFO_YESEXPR@ +# define YESEXPR 10053 +# define NOEXPR 10054 +# define GNULIB_defined_YESEXPR 1 +# endif + +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Declare overridden functions. */ + + +/* Return a piece of locale dependent information. + Note: The difference between nl_langinfo (CODESET) and locale_charset () + is that the latter normalizes the encoding names to GNU conventions. */ + +#if @GNULIB_NL_LANGINFO@ +# if @REPLACE_NL_LANGINFO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef nl_langinfo +# define nl_langinfo rpl_nl_langinfo +# endif +_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item)); +_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item)); +# else +# if !@HAVE_NL_LANGINFO@ +_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item)); +# endif +_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item)); +# endif +_GL_CXXALIASWARN (nl_langinfo); +#elif defined GNULIB_POSIXCHECK +# undef nl_langinfo +# if HAVE_RAW_DECL_NL_LANGINFO +_GL_WARN_ON_USE (nl_langinfo, "nl_langinfo is not portable - " + "use gnulib module nl_langinfo for portability"); +# endif +#endif + + +#endif /* _GL_LANGINFO_H */ +#endif /* _GL_LANGINFO_H */ diff --git a/grub-core/gnulib/localcharset.c b/grub-core/gnulib/localcharset.c new file mode 100644 index 000000000..fa2207fe1 --- /dev/null +++ b/grub-core/gnulib/localcharset.c @@ -0,0 +1,548 @@ +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000-2006, 2008-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Bruno Haible . */ + +#include + +/* Specification. */ +#include "localcharset.h" + +#include +#include +#include +#include +#include + +#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */ +#endif + +#if defined _WIN32 || defined __WIN32__ +# define WIN32_NATIVE +#endif + +#if defined __EMX__ +/* Assume EMX program runs on OS/2, even if compiled under DOS. */ +# ifndef OS2 +# define OS2 +# endif +#endif + +#if !defined WIN32_NATIVE +# include +# if HAVE_LANGINFO_CODESET +# include +# else +# if 0 /* see comment below */ +# include +# endif +# endif +# ifdef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# endif +#elif defined WIN32_NATIVE +# define WIN32_LEAN_AND_MEAN +# include +#endif +#if defined OS2 +# define INCL_DOS +# include +#endif + +#if ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + +/* Get LIBDIR. */ +#ifndef LIBDIR +# include "configmake.h" +#endif + +/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Win32, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#endif + +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif + +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif + +#if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc getc_unlocked +#endif + +/* The following static variable is declared 'volatile' to avoid a + possible multithread problem in the function get_charset_aliases. If we + are running in a threaded environment, and if two threads initialize + 'charset_aliases' simultaneously, both will produce the same value, + and everything will be ok if the two assignments to 'charset_aliases' + are atomic. But I don't know what will happen if the two assignments mix. */ +#if __STDC__ != 1 +# define volatile /* empty */ +#endif +/* Pointer to the contents of the charset.alias file, if it has already been + read, else NULL. Its format is: + ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ +static const char * volatile charset_aliases; + +/* Return a pointer to the contents of the charset.alias file. */ +static const char * +get_charset_aliases (void) +{ + const char *cp; + + cp = charset_aliases; + if (cp == NULL) + { +#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) + const char *dir; + const char *base = "charset.alias"; + char *file_name; + + /* Make it possible to override the charset.alias location. This is + necessary for running the testsuite before "make install". */ + dir = getenv ("CHARSETALIASDIR"); + if (dir == NULL || dir[0] == '\0') + dir = relocate (LIBDIR); + + /* Concatenate dir and base into freshly allocated file_name. */ + { + size_t dir_len = strlen (dir); + size_t base_len = strlen (base); + int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); + file_name = (char *) malloc (dir_len + add_slash + base_len + 1); + if (file_name != NULL) + { + memcpy (file_name, dir, dir_len); + if (add_slash) + file_name[dir_len] = DIRECTORY_SEPARATOR; + memcpy (file_name + dir_len + add_slash, base, base_len + 1); + } + } + + if (file_name == NULL) + /* Out of memory. Treat the file as empty. */ + cp = ""; + else + { + int fd; + + /* Open the file. Reject symbolic links on platforms that support + O_NOFOLLOW. This is a security feature. Without it, an attacker + could retrieve parts of the contents (namely, the tail of the + first line that starts with "* ") of an arbitrary file by placing + a symbolic link to that file under the name "charset.alias" in + some writable directory and defining the environment variable + CHARSETALIASDIR to point to that directory. */ + fd = open (file_name, + O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + /* File not found. Treat it as empty. */ + cp = ""; + else + { + FILE *fp; + + fp = fdopen (fd, "r"); + if (fp == NULL) + { + /* Out of memory. Treat the file as empty. */ + close (fd); + cp = ""; + } + else + { + /* Parse the file's contents. */ + char *res_ptr = NULL; + size_t res_size = 0; + + for (;;) + { + int c; + char buf1[50+1]; + char buf2[50+1]; + size_t l1, l2; + char *old_res_ptr; + + c = getc (fp); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') + { + /* Skip comment, to end of line. */ + do + c = getc (fp); + while (!(c == EOF || c == '\n')); + if (c == EOF) + break; + continue; + } + ungetc (c, fp); + if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) + break; + l1 = strlen (buf1); + l2 = strlen (buf2); + old_res_ptr = res_ptr; + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = (char *) malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = (char *) realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + if (old_res_ptr != NULL) + free (old_res_ptr); + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); + strcpy (res_ptr + res_size - (l2 + 1), buf2); + } + fclose (fp); + if (res_size == 0) + cp = ""; + else + { + *(res_ptr + res_size) = '\0'; + cp = res_ptr; + } + } + } + + free (file_name); + } + +#else + +# if defined DARWIN7 + /* To avoid the trouble of installing a file that is shared by many + GNU packages -- many packaging systems have problems with this --, + simply inline the aliases here. */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-4" "\0" "ISO-8859-4" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + "ISO8859-13" "\0" "ISO-8859-13" "\0" + "ISO8859-15" "\0" "ISO-8859-15" "\0" + "KOI8-R" "\0" "KOI8-R" "\0" + "KOI8-U" "\0" "KOI8-U" "\0" + "CP866" "\0" "CP866" "\0" + "CP949" "\0" "CP949" "\0" + "CP1131" "\0" "CP1131" "\0" + "CP1251" "\0" "CP1251" "\0" + "eucCN" "\0" "GB2312" "\0" + "GB2312" "\0" "GB2312" "\0" + "eucJP" "\0" "EUC-JP" "\0" + "eucKR" "\0" "EUC-KR" "\0" + "Big5" "\0" "BIG5" "\0" + "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" + "GBK" "\0" "GBK" "\0" + "GB18030" "\0" "GB18030" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "ARMSCII-8" "\0" "ARMSCII-8" "\0" + "PT154" "\0" "PT154" "\0" + /*"ISCII-DEV" "\0" "?" "\0"*/ + "*" "\0" "UTF-8" "\0"; +# endif + +# if defined VMS + /* To avoid the troubles of an extra file charset.alias_vms in the + sources of many GNU packages, simply inline the aliases here. */ + /* The list of encodings is taken from the OpenVMS 7.3-1 documentation + "Compaq C Run-Time Library Reference Manual for OpenVMS systems" + section 10.7 "Handling Different Character Sets". */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-8" "\0" "ISO-8859-8" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + /* Japanese */ + "eucJP" "\0" "EUC-JP" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "DECKANJI" "\0" "DEC-KANJI" "\0" + "SDECKANJI" "\0" "EUC-JP" "\0" + /* Chinese */ + "eucTW" "\0" "EUC-TW" "\0" + "DECHANYU" "\0" "DEC-HANYU" "\0" + "DECHANZI" "\0" "GB2312" "\0" + /* Korean */ + "DECKOREAN" "\0" "EUC-KR" "\0"; +# endif + +# if defined WIN32_NATIVE || defined __CYGWIN__ + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + + cp = "CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0" + "CP20127" "\0" "ASCII" "\0" + "CP20866" "\0" "KOI8-R" "\0" + "CP20936" "\0" "GB2312" "\0" + "CP21866" "\0" "KOI8-RU" "\0" + "CP28591" "\0" "ISO-8859-1" "\0" + "CP28592" "\0" "ISO-8859-2" "\0" + "CP28593" "\0" "ISO-8859-3" "\0" + "CP28594" "\0" "ISO-8859-4" "\0" + "CP28595" "\0" "ISO-8859-5" "\0" + "CP28596" "\0" "ISO-8859-6" "\0" + "CP28597" "\0" "ISO-8859-7" "\0" + "CP28598" "\0" "ISO-8859-8" "\0" + "CP28599" "\0" "ISO-8859-9" "\0" + "CP28605" "\0" "ISO-8859-15" "\0" + "CP38598" "\0" "ISO-8859-8" "\0" + "CP51932" "\0" "EUC-JP" "\0" + "CP51936" "\0" "GB2312" "\0" + "CP51949" "\0" "EUC-KR" "\0" + "CP51950" "\0" "EUC-TW" "\0" + "CP54936" "\0" "GB18030" "\0" + "CP65001" "\0" "UTF-8" "\0"; +# endif +#endif + + charset_aliases = cp; + } + + return cp; +} + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ + +#ifdef STATIC +STATIC +#endif +const char * +locale_charset (void) +{ + const char *codeset; + const char *aliases; + +#if !(defined WIN32_NATIVE || defined OS2) + +# if HAVE_LANGINFO_CODESET + + /* Most systems support nl_langinfo (CODESET) nowadays. */ + codeset = nl_langinfo (CODESET); + +# ifdef __CYGWIN__ + /* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always + returns "US-ASCII". Return the suffix of the locale name from the + environment variables (if present) or the codepage as a number. */ + if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) + { + const char *locale; + static char buf[2 + 10 + 1]; + + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return + it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + + /* Woe32 has a function returning the locale's codepage as a number: + GetACP(). This encoding is used by Cygwin, unless the user has set + the environment variable CYGWIN=codepage:oem (which very few people + do). + Output directed to console windows needs to be converted (to + GetOEMCP() if the console is using a raster font, or to + GetConsoleOutputCP() if it is using a TrueType font). Cygwin does + this conversion transparently (see winsup/cygwin/fhandler_console.cc), + converting to GetConsoleOutputCP(). This leads to correct results, + except when SetConsoleOutputCP has been called and a raster font is + in use. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + } +# endif + +# else + + /* On old systems which lack it, use setlocale or getenv. */ + const char *locale = NULL; + + /* But most old systems don't have a complete set of locales. Some + (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't + use setlocale here; it would return "C" when it doesn't support the + locale name the user has set. */ +# if 0 + locale = setlocale (LC_CTYPE, NULL); +# endif + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + } + + /* On some old systems, one used to set locale = "iso8859_1". On others, + you set it to "language_COUNTRY.charset". In any case, we resolve it + through the charset.alias file. */ + codeset = locale; + +# endif + +#elif defined WIN32_NATIVE + + static char buf[2 + 10 + 1]; + + /* Woe32 has a function returning the locale's codepage as a number: + GetACP(). + When the output goes to a console window, it needs to be provided in + GetOEMCP() encoding if the console is using a raster font, or in + GetConsoleOutputCP() encoding if it is using a TrueType font. + But in GUI programs and for output sent to files and pipes, GetACP() + encoding is the best bet. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + +#elif defined OS2 + + const char *locale; + static char buf[2 + 10 + 1]; + ULONG cp[3]; + ULONG cplen; + + /* Allow user to override the codeset, as set in the operating system, + with standard language environment variables. */ + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + + /* Resolve through the charset.alias file. */ + codeset = locale; + } + else + { + /* OS/2 has a function returning the locale's codepage as a number. */ + if (DosQueryCp (sizeof (cp), cp, &cplen)) + codeset = ""; + else + { + sprintf (buf, "CP%u", cp[0]); + codeset = buf; + } + } + +#endif + + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + + /* Resolve alias. */ + for (aliases = get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (strcmp (codeset, aliases) == 0 + || (aliases[0] == '*' && aliases[1] == '\0')) + { + codeset = aliases + strlen (aliases) + 1; + break; + } + + /* Don't return an empty string. GNU libc and GNU libiconv interpret + the empty string as denoting "the locale's character encoding", + thus GNU libiconv would call this function a second time. */ + if (codeset[0] == '\0') + codeset = "ASCII"; + + return codeset; +} diff --git a/grub-core/gnulib/localcharset.h b/grub-core/gnulib/localcharset.h new file mode 100644 index 000000000..899b3bae7 --- /dev/null +++ b/grub-core/gnulib/localcharset.h @@ -0,0 +1,41 @@ +/* Determine a canonical name for the current locale's character encoding. + Copyright (C) 2000-2003, 2009-2010 Free Software Foundation, Inc. + This file is part of the GNU CHARSET Library. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _LOCALCHARSET_H +#define _LOCALCHARSET_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ +extern const char * locale_charset (void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _LOCALCHARSET_H */ diff --git a/grub-core/gnulib/malloc.c b/grub-core/gnulib/malloc.c new file mode 100644 index 000000000..4fa38ee41 --- /dev/null +++ b/grub-core/gnulib/malloc.c @@ -0,0 +1,60 @@ +/* malloc() function that is glibc compatible. + + Copyright (C) 1997-1998, 2006-2007, 2009-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* written by Jim Meyering and Bruno Haible */ + +#include +/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ +#ifdef malloc +# define NEED_MALLOC_GNU 1 +# undef malloc +/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ +#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU +# define NEED_MALLOC_GNU 1 +#endif + +/* Specification. */ +#include + +#include + +/* Call the system's malloc below. */ +#undef malloc + +/* Allocate an N-byte block of memory from the heap. + If N is zero, allocate a 1-byte block. */ + +void * +rpl_malloc (size_t n) +{ + void *result; + +#if NEED_MALLOC_GNU + if (n == 0) + n = 1; +#endif + + result = malloc (n); + +#if !HAVE_MALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/grub-core/gnulib/mbrtowc.c b/grub-core/gnulib/mbrtowc.c new file mode 100644 index 000000000..5c2650e95 --- /dev/null +++ b/grub-core/gnulib/mbrtowc.c @@ -0,0 +1,386 @@ +/* Convert multibyte character to wide character. + Copyright (C) 1999-2002, 2005-2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#if GNULIB_defined_mbstate_t +/* Implement mbrtowc() on top of mbtowc(). */ + +# include +# include + +# include "localcharset.h" +# include "streq.h" +# include "verify.h" + + +verify (sizeof (mbstate_t) >= 4); + +static char internal_state[4]; + +size_t +mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ + char *pstate = (char *)ps; + + if (pstate == NULL) + pstate = internal_state; + + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } + + if (n == 0) + return (size_t)(-2); + + /* Here n > 0. */ + { + size_t nstate = pstate[0]; + char buf[4]; + const char *p; + size_t m; + + switch (nstate) + { + case 0: + p = s; + m = n; + break; + case 3: + buf[2] = pstate[3]; + /*FALLTHROUGH*/ + case 2: + buf[1] = pstate[2]; + /*FALLTHROUGH*/ + case 1: + buf[0] = pstate[1]; + p = buf; + m = nstate; + buf[m++] = s[0]; + if (n >= 2 && m < 4) + { + buf[m++] = s[1]; + if (n >= 3 && m < 4) + buf[m++] = s[2]; + } + break; + default: + errno = EINVAL; + return (size_t)(-1); + } + + /* Here m > 0. */ + +# if __GLIBC__ + /* Work around bug */ + mbtowc (NULL, NULL, 0); +# endif + { + int res = mbtowc (pwc, p, m); + + if (res >= 0) + { + if (pwc != NULL && ((*pwc == 0) != (res == 0))) + abort (); + if (nstate >= (res > 0 ? res : 1)) + abort (); + res -= nstate; + pstate[0] = 0; + return res; + } + + /* mbtowc does not distinguish between invalid and incomplete multibyte + sequences. But mbrtowc needs to make this distinction. + There are two possible approaches: + - Use iconv() and its return value. + - Use built-in knowledge about the possible encodings. + Given the low quality of implementation of iconv() on the systems that + lack mbrtowc(), we use the second approach. + The possible encodings are: + - 8-bit encodings, + - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, + - UTF-8. + Use specialized code for each. */ + if (m >= 4 || m >= MB_CUR_MAX) + goto invalid; + /* Here MB_CUR_MAX > 1 and 0 < m < 4. */ + { + const char *encoding = locale_charset (); + + if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) + { + /* Cf. unistr/u8-mblen.c. */ + unsigned char c = (unsigned char) p[0]; + + if (c >= 0xc2) + { + if (c < 0xe0) + { + if (m == 1) + goto incomplete; + } + else if (c < 0xf0) + { + if (m == 1) + goto incomplete; + if (m == 2) + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xe1 || c2 >= 0xa0) + && (c != 0xed || c2 < 0xa0)) + goto incomplete; + } + } + else if (c <= 0xf4) + { + if (m == 1) + goto incomplete; + else /* m == 2 || m == 3 */ + { + unsigned char c2 = (unsigned char) p[1]; + + if ((c2 ^ 0x80) < 0x40 + && (c >= 0xf1 || c2 >= 0x90) + && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if ((c3 ^ 0x80) < 0x40) + goto incomplete; + } + } + } + } + } + goto invalid; + } + + /* As a reference for this code, you can use the GNU libiconv + implementation. Look for uses of the RET_TOOFEW macro. */ + + if (STREQ (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f) + goto incomplete; + } + if (m == 2) + { + unsigned char c = (unsigned char) p[0]; + + if (c == 0x8f) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0xa1 && c2 < 0xff) + goto incomplete; + } + } + goto invalid; + } + if (STREQ (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + || STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) + || STREQ (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0xa1 && c < 0xff) + goto incomplete; + } + goto invalid; + } + if (STREQ (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0xa1 && c < 0xff) || c == 0x8e) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c == 0x8e) + goto incomplete; + } + goto invalid; + } + if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) + goto incomplete; + } + else /* m == 2 || m == 3 */ + { + unsigned char c = (unsigned char) p[0]; + + if (c >= 0x90 && c <= 0xe3) + { + unsigned char c2 = (unsigned char) p[1]; + + if (c2 >= 0x30 && c2 <= 0x39) + { + if (m == 2) + goto incomplete; + else /* m == 3 */ + { + unsigned char c3 = (unsigned char) p[2]; + + if (c3 >= 0x81 && c3 <= 0xfe) + goto incomplete; + } + } + } + } + goto invalid; + } + if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) + { + if (m == 1) + { + unsigned char c = (unsigned char) p[0]; + + if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea) + || (c >= 0xf0 && c <= 0xf9)) + goto incomplete; + } + goto invalid; + } + + /* An unknown multibyte encoding. */ + goto incomplete; + } + + incomplete: + { + size_t k = nstate; + /* Here 0 <= k < m < 4. */ + pstate[++k] = s[0]; + if (k < m) + { + pstate[++k] = s[1]; + if (k < m) + pstate[++k] = s[2]; + } + if (k != m) + abort (); + } + pstate[0] = m; + return (size_t)(-2); + + invalid: + errno = EILSEQ; + /* The conversion state is undefined, says POSIX. */ + return (size_t)(-1); + } + } +} + +#else +/* Override the system's mbrtowc() function. */ + +# undef mbrtowc + +size_t +rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) +{ +# if MBRTOWC_NULL_ARG_BUG || MBRTOWC_RETVAL_BUG + if (s == NULL) + { + pwc = NULL; + s = ""; + n = 1; + } +# endif + +# if MBRTOWC_RETVAL_BUG + { + static mbstate_t internal_state; + + /* Override mbrtowc's internal state. We can not call mbsinit() on the + hidden internal state, but we can call it on our variable. */ + if (ps == NULL) + ps = &internal_state; + + if (!mbsinit (ps)) + { + /* Parse the rest of the multibyte character byte for byte. */ + size_t count = 0; + for (; n > 0; s++, n--) + { + wchar_t wc; + size_t ret = mbrtowc (&wc, s, 1, ps); + + if (ret == (size_t)(-1)) + return (size_t)(-1); + count++; + if (ret != (size_t)(-2)) + { + /* The multibyte character has been completed. */ + if (pwc != NULL) + *pwc = wc; + return (wc == 0 ? 0 : count); + } + } + return (size_t)(-2); + } + } +# endif + +# if MBRTOWC_NUL_RETVAL_BUG + { + wchar_t wc; + size_t ret = mbrtowc (&wc, s, n, ps); + + if (ret != (size_t)(-1) && ret != (size_t)(-2)) + { + if (pwc != NULL) + *pwc = wc; + if (wc == 0) + ret = 0; + } + return ret; + } +# else + return mbrtowc (pwc, s, n, ps); +# endif +} + +#endif diff --git a/grub-core/gnulib/mbsinit.c b/grub-core/gnulib/mbsinit.c new file mode 100644 index 000000000..066ddfe5b --- /dev/null +++ b/grub-core/gnulib/mbsinit.c @@ -0,0 +1,47 @@ +/* Test for initial conversion state. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include "verify.h" + +/* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs() + and wcrtomb(), wcsrtombs(). + We assume that + - sizeof (mbstate_t) >= 4, + - only stateless encodings are supported (such as UTF-8 and EUC-JP, but + not ISO-2022 variants), + - for each encoding, the number of bytes for a wide character is <= 4. + (This maximum is attained for UTF-8, GB18030, EUC-TW.) + We define the meaning of mbstate_t as follows: + - In mb -> wc direction, mbstate_t's first byte contains the number of + buffered bytes (in the range 0..3), followed by up to 3 buffered bytes. + - In wc -> mb direction, mbstate_t contains no information. In other + words, it is always in the initial state. */ + +verify (sizeof (mbstate_t) >= 4); + +int +mbsinit (const mbstate_t *ps) +{ + const char *pstate = (const char *)ps; + + return pstate[0] == 0; +} diff --git a/grub-core/gnulib/mbsrtowcs-state.c b/grub-core/gnulib/mbsrtowcs-state.c new file mode 100644 index 000000000..35045f657 --- /dev/null +++ b/grub-core/gnulib/mbsrtowcs-state.c @@ -0,0 +1,37 @@ +/* Convert string to wide string. + Copyright (C) 2008-2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +#include + +/* Internal state used by the functions mbsrtowcs() and mbsnrtowcs(). */ +mbstate_t _gl_mbsrtowcs_state +/* The state must initially be in the "initial state"; so, zero-initialize it. + On most systems, putting it into BSS is sufficient. Not so on MacOS X 10.3, + see . + When it needs an initializer, use 0 or {0} as initializer? 0 only works + when mbstate_t is a scalar type (such as when gnulib defines it, or on + AIX, IRIX, mingw). {0} works as an initializer in all cases: for a struct + or union type, but also for a scalar type (ISO C 99, 6.7.8.(11)). */ +#if defined __ELF__ + /* On ELF systems, variables in BSS behave well. */ +#else + /* Use braces, to be on the safe side. */ + = { 0 } +#endif + ; diff --git a/grub-core/gnulib/mbsrtowcs.c b/grub-core/gnulib/mbsrtowcs.c new file mode 100644 index 000000000..c577f36f2 --- /dev/null +++ b/grub-core/gnulib/mbsrtowcs.c @@ -0,0 +1,136 @@ +/* Convert string to wide string. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#include "strnlen1.h" + + +extern mbstate_t _gl_mbsrtowcs_state; + +size_t +mbsrtowcs (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) +{ + if (ps == NULL) + ps = &_gl_mbsrtowcs_state; + { + const char *src = *srcp; + + if (dest != NULL) + { + wchar_t *destptr = dest; + + for (; len > 0; destptr++, len--) + { + size_t src_avail; + size_t ret; + + /* An optimized variant of + src_avail = strnlen1 (src, MB_LEN_MAX); */ + if (src[0] == '\0') + src_avail = 1; + else if (src[1] == '\0') + src_avail = 2; + else if (src[2] == '\0') + src_avail = 3; + else if (MB_LEN_MAX <= 4 || src[3] == '\0') + src_avail = 4; + else + src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); + + /* Parse the next multibyte character. */ + ret = mbrtowc (destptr, src, src_avail, ps); + + if (ret == (size_t)(-2)) + /* Encountered a multibyte character that extends past a '\0' byte + or that is longer than MB_LEN_MAX bytes. Cannot happen. */ + abort (); + + if (ret == (size_t)(-1)) + goto bad_input; + if (ret == 0) + { + src = NULL; + /* Here mbsinit (ps). */ + break; + } + src += ret; + } + + *srcp = src; + return destptr - dest; + } + else + { + /* Ignore dest and len, don't store *srcp at the end, and + don't clobber *ps. */ + mbstate_t state = *ps; + size_t totalcount = 0; + + for (;; totalcount++) + { + size_t src_avail; + size_t ret; + + /* An optimized variant of + src_avail = strnlen1 (src, MB_LEN_MAX); */ + if (src[0] == '\0') + src_avail = 1; + else if (src[1] == '\0') + src_avail = 2; + else if (src[2] == '\0') + src_avail = 3; + else if (MB_LEN_MAX <= 4 || src[3] == '\0') + src_avail = 4; + else + src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); + + /* Parse the next multibyte character. */ + ret = mbrtowc (NULL, src, src_avail, &state); + + if (ret == (size_t)(-2)) + /* Encountered a multibyte character that extends past a '\0' byte + or that is longer than MB_LEN_MAX bytes. Cannot happen. */ + abort (); + + if (ret == (size_t)(-1)) + goto bad_input2; + if (ret == 0) + { + /* Here mbsinit (&state). */ + break; + } + src += ret; + } + + return totalcount; + } + + bad_input: + *srcp = src; + bad_input2: + errno = EILSEQ; + return (size_t)(-1); + } +} diff --git a/grub-core/gnulib/memchr.c b/grub-core/gnulib/memchr.c new file mode 100644 index 000000000..6c2b2d6c7 --- /dev/null +++ b/grub-core/gnulib/memchr.c @@ -0,0 +1,172 @@ +/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2010 + Free Software Foundation, Inc. + + Based on strlen implementation by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se) and + commentary by Jim Blandy (jimb@ai.mit.edu); + adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), + and implemented by Roland McGrath (roland@ai.mit.edu). + +NOTE: The canonical source of this file is maintained with the GNU C Library. +Bugs can be reported to bug-glibc@prep.ai.mit.edu. + +This program 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 any +later version. + +This program 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 this program. If not, see . */ + +#ifndef _LIBC +# include +#endif + +#include + +#include + +#if defined _LIBC +# include +#else +# define reg_char char +#endif + +#include + +#if HAVE_BP_SYM_H || defined _LIBC +# include +#else +# define BP_SYM(sym) sym +#endif + +#undef __memchr +#ifdef _LIBC +# undef memchr +#endif + +#ifndef weak_alias +# define __memchr memchr +#endif + +/* Search no more than N bytes of S for C. */ +void * +__memchr (void const *s, int c_in, size_t n) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned reg_char c; + + c = (unsigned char) c_in; + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + n > 0 && (size_t) char_ptr % sizeof (longword) != 0; + --n, ++char_ptr) + if (*char_ptr == c) + return (void *) char_ptr; + + longword_ptr = (const longword *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will test a + longword at a time. The tricky part is testing if *any of the four* + bytes in the longword in question are equal to c. We first use an xor + with repeated_c. This reduces the task to testing whether *any of the + four* bytes in longword1 is zero. + + We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + So, the test whether any byte in longword1 is zero is equivalent to + testing whether tmp is nonzero. */ + + while (n >= sizeof (longword)) + { + longword longword1 = *longword_ptr ^ repeated_c; + + if ((((longword1 - repeated_one) & ~longword1) + & (repeated_one << 7)) != 0) + break; + longword_ptr++; + n -= sizeof (longword); + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that either n < sizeof (longword), or one of the + sizeof (longword) bytes starting at char_ptr is == c. On little-endian + machines, we could determine the first such byte without any further + memory accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. Choose code + that works in both cases. */ + + for (; n > 0; --n, ++char_ptr) + { + if (*char_ptr == c) + return (void *) char_ptr; + } + + return NULL; +} +#ifdef weak_alias +weak_alias (__memchr, BP_SYM (memchr)) +#endif diff --git a/grub-core/gnulib/memchr.valgrind b/grub-core/gnulib/memchr.valgrind new file mode 100644 index 000000000..60f247e10 --- /dev/null +++ b/grub-core/gnulib/memchr.valgrind @@ -0,0 +1,14 @@ +# Suppress a valgrind message about use of uninitialized memory in memchr(). +# POSIX states that when the character is found, memchr must not read extra +# bytes in an overestimated length (for example, where memchr is used to +# implement strnlen). However, we use a safe word read to provide a speedup. +{ + memchr-value4 + Memcheck:Value4 + fun:rpl_memchr +} +{ + memchr-value8 + Memcheck:Value8 + fun:rpl_memchr +} diff --git a/grub-core/gnulib/mempcpy.c b/grub-core/gnulib/mempcpy.c new file mode 100644 index 000000000..b624d69fd --- /dev/null +++ b/grub-core/gnulib/mempcpy.c @@ -0,0 +1,29 @@ +/* Copy memory area and return pointer after last written byte. + Copyright (C) 2003, 2007, 2009, 2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +/* Copy N bytes of SRC to DEST, return pointer to bytes after the + last written byte. */ +void * +mempcpy (void *dest, const void *src, size_t n) +{ + return (char *) memcpy (dest, src, n) + n; +} diff --git a/grub-core/gnulib/nl_langinfo.c b/grub-core/gnulib/nl_langinfo.c new file mode 100644 index 000000000..a3d0d11eb --- /dev/null +++ b/grub-core/gnulib/nl_langinfo.c @@ -0,0 +1,270 @@ +/* nl_langinfo() replacement: query locale dependent information. + + Copyright (C) 2007-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#if REPLACE_NL_LANGINFO + +/* Override nl_langinfo with support for added nl_item values. */ + +# include +# include + +# undef nl_langinfo + +char * +rpl_nl_langinfo (nl_item item) +{ + switch (item) + { +# if GNULIB_defined_CODESET + case CODESET: + { + const char *locale; + static char buf[2 + 10 + 1]; + + locale = setlocale (LC_CTYPE, NULL); + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return + it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + return ""; + } +# endif +# if GNULIB_defined_T_FMT_AMPM + case T_FMT_AMPM: + return "%I:%M:%S %p"; +# endif +# if GNULIB_defined_ERA + case ERA: + /* The format is not standardized. In glibc it is a sequence of strings + of the form "direction:offset:start_date:end_date:era_name:era_format" + with an empty string at the end. */ + return ""; + case ERA_D_FMT: + /* The %Ex conversion in strftime behaves like %x if the locale does not + have an alternative time format. */ + item = D_FMT; + break; + case ERA_D_T_FMT: + /* The %Ec conversion in strftime behaves like %c if the locale does not + have an alternative time format. */ + item = D_T_FMT; + break; + case ERA_T_FMT: + /* The %EX conversion in strftime behaves like %X if the locale does not + have an alternative time format. */ + item = T_FMT; + break; + case ALT_DIGITS: + /* The format is not standardized. In glibc it is a sequence of 10 + strings, appended in memory. */ + return "\0\0\0\0\0\0\0\0\0\0"; +# endif +# if GNULIB_defined_YESEXPR + case YESEXPR: + return "^[yY]"; + case NOEXPR: + return "^[nN]"; +# endif + default: + break; + } + return nl_langinfo (item); +} + +#else + +/* Provide nl_langinfo from scratch. */ + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* Native Windows platforms. */ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# include + +# else + +/* An old Unix platform without locales, such as Linux libc5 or BeOS. */ + +# endif + +# include + +char * +nl_langinfo (nl_item item) +{ + switch (item) + { + /* nl_langinfo items of the LC_CTYPE category */ + case CODESET: +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + { + static char buf[2 + 10 + 1]; + + /* Woe32 has a function returning the locale's codepage as a number. */ + sprintf (buf, "CP%u", GetACP ()); + return buf; + } +# elif defined __BEOS__ + return "UTF-8"; +# else + return "ISO-8859-1"; +# endif + /* nl_langinfo items of the LC_NUMERIC category */ + case RADIXCHAR: + return localeconv () ->decimal_point; + case THOUSEP: + return localeconv () ->thousands_sep; + /* nl_langinfo items of the LC_TIME category. + TODO: Really use the locale. */ + case D_T_FMT: + case ERA_D_T_FMT: + return "%a %b %e %H:%M:%S %Y"; + case D_FMT: + case ERA_D_FMT: + return "%m/%d/%y"; + case T_FMT: + case ERA_T_FMT: + return "%H:%M:%S"; + case T_FMT_AMPM: + return "%I:%M:%S %p"; + case AM_STR: + return "AM"; + case PM_STR: + return "PM"; + case DAY_1: + return "Sunday"; + case DAY_2: + return "Monday"; + case DAY_3: + return "Tuesday"; + case DAY_4: + return "Wednesday"; + case DAY_5: + return "Thursday"; + case DAY_6: + return "Friday"; + case DAY_7: + return "Saturday"; + case ABDAY_1: + return "Sun"; + case ABDAY_2: + return "Mon"; + case ABDAY_3: + return "Tue"; + case ABDAY_4: + return "Wed"; + case ABDAY_5: + return "Thu"; + case ABDAY_6: + return "Fri"; + case ABDAY_7: + return "Sat"; + case MON_1: + return "January"; + case MON_2: + return "February"; + case MON_3: + return "March"; + case MON_4: + return "April"; + case MON_5: + return "May"; + case MON_6: + return "June"; + case MON_7: + return "July"; + case MON_8: + return "August"; + case MON_9: + return "September"; + case MON_10: + return "October"; + case MON_11: + return "November"; + case MON_12: + return "December"; + case ABMON_1: + return "Jan"; + case ABMON_2: + return "Feb"; + case ABMON_3: + return "Mar"; + case ABMON_4: + return "Apr"; + case ABMON_5: + return "May"; + case ABMON_6: + return "Jun"; + case ABMON_7: + return "Jul"; + case ABMON_8: + return "Aug"; + case ABMON_9: + return "Sep"; + case ABMON_10: + return "Oct"; + case ABMON_11: + return "Nov"; + case ABMON_12: + return "Dec"; + case ERA: + return ""; + case ALT_DIGITS: + return "\0\0\0\0\0\0\0\0\0\0"; + /* nl_langinfo items of the LC_MONETARY category + TODO: Really use the locale. */ + case CRNCYSTR: + return "-"; + /* nl_langinfo items of the LC_MESSAGES category + TODO: Really use the locale. */ + case YESEXPR: + return "^[yY]"; + case NOEXPR: + return "^[nN]"; + default: + return ""; + } +} + +#endif diff --git a/grub-core/gnulib/printf-args.c b/grub-core/gnulib/printf-args.c new file mode 100644 index 000000000..46c03a21e --- /dev/null +++ b/grub-core/gnulib/printf-args.c @@ -0,0 +1,188 @@ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2010 Free Software + Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + PRINTF_FETCHARGS Name of the function to be defined. + STATIC Set to 'static' to declare the function static. */ + +#ifndef PRINTF_FETCHARGS +# include +#endif + +/* Specification. */ +#ifndef PRINTF_FETCHARGS +# include "printf-args.h" +#endif + +#ifdef STATIC +STATIC +#endif +int +PRINTF_FETCHARGS (va_list args, arguments *a) +{ + size_t i; + argument *ap; + + for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++) + switch (ap->type) + { + case TYPE_SCHAR: + ap->a.a_schar = va_arg (args, /*signed char*/ int); + break; + case TYPE_UCHAR: + ap->a.a_uchar = va_arg (args, /*unsigned char*/ int); + break; + case TYPE_SHORT: + ap->a.a_short = va_arg (args, /*short*/ int); + break; + case TYPE_USHORT: + ap->a.a_ushort = va_arg (args, /*unsigned short*/ int); + break; + case TYPE_INT: + ap->a.a_int = va_arg (args, int); + break; + case TYPE_UINT: + ap->a.a_uint = va_arg (args, unsigned int); + break; + case TYPE_LONGINT: + ap->a.a_longint = va_arg (args, long int); + break; + case TYPE_ULONGINT: + ap->a.a_ulongint = va_arg (args, unsigned long int); + break; +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + ap->a.a_longlongint = va_arg (args, long long int); + break; + case TYPE_ULONGLONGINT: + ap->a.a_ulonglongint = va_arg (args, unsigned long long int); + break; +#endif + case TYPE_DOUBLE: + ap->a.a_double = va_arg (args, double); + break; + case TYPE_LONGDOUBLE: + ap->a.a_longdouble = va_arg (args, long double); + break; + case TYPE_CHAR: + ap->a.a_char = va_arg (args, int); + break; +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: + /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by + default argument promotions", this is not the case in mingw32, + where wint_t is 'unsigned short'. */ + ap->a.a_wide_char = + (sizeof (wint_t) < sizeof (int) + ? (wint_t) va_arg (args, int) + : va_arg (args, wint_t)); + break; +#endif + case TYPE_STRING: + ap->a.a_string = va_arg (args, const char *); + /* A null pointer is an invalid argument for "%s", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_string == NULL) + ap->a.a_string = "(NULL)"; + break; +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: + ap->a.a_wide_string = va_arg (args, const wchar_t *); + /* A null pointer is an invalid argument for "%ls", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_wide_string == NULL) + { + static const wchar_t wide_null_string[] = + { + (wchar_t)'(', + (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', + (wchar_t)')', + (wchar_t)0 + }; + ap->a.a_wide_string = wide_null_string; + } + break; +#endif + case TYPE_POINTER: + ap->a.a_pointer = va_arg (args, void *); + break; + case TYPE_COUNT_SCHAR_POINTER: + ap->a.a_count_schar_pointer = va_arg (args, signed char *); + break; + case TYPE_COUNT_SHORT_POINTER: + ap->a.a_count_short_pointer = va_arg (args, short *); + break; + case TYPE_COUNT_INT_POINTER: + ap->a.a_count_int_pointer = va_arg (args, int *); + break; + case TYPE_COUNT_LONGINT_POINTER: + ap->a.a_count_longint_pointer = va_arg (args, long int *); + break; +#if HAVE_LONG_LONG_INT + case TYPE_COUNT_LONGLONGINT_POINTER: + ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); + break; +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case TYPE_U8_STRING: + ap->a.a_u8_string = va_arg (args, const uint8_t *); + /* A null pointer is an invalid argument for "%U", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u8_string == NULL) + { + static const uint8_t u8_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u8_string = u8_null_string; + } + break; + case TYPE_U16_STRING: + ap->a.a_u16_string = va_arg (args, const uint16_t *); + /* A null pointer is an invalid argument for "%lU", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u16_string == NULL) + { + static const uint16_t u16_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u16_string = u16_null_string; + } + break; + case TYPE_U32_STRING: + ap->a.a_u32_string = va_arg (args, const uint32_t *); + /* A null pointer is an invalid argument for "%llU", but in practice + it occurs quite frequently in printf statements that produce + debug output. Use a fallback in this case. */ + if (ap->a.a_u32_string == NULL) + { + static const uint32_t u32_null_string[] = + { '(', 'N', 'U', 'L', 'L', ')', 0 }; + ap->a.a_u32_string = u32_null_string; + } + break; +#endif + default: + /* Unknown type. */ + return -1; + } + return 0; +} diff --git a/grub-core/gnulib/printf-args.h b/grub-core/gnulib/printf-args.h new file mode 100644 index 000000000..2536ebafd --- /dev/null +++ b/grub-core/gnulib/printf-args.h @@ -0,0 +1,155 @@ +/* Decomposed printf argument list. + Copyright (C) 1999, 2002-2003, 2006-2007, 2009-2010 Free Software + Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _PRINTF_ARGS_H +#define _PRINTF_ARGS_H + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + PRINTF_FETCHARGS Name of the function to be declared. + STATIC Set to 'static' to declare the function static. */ + +/* Default parameters. */ +#ifndef PRINTF_FETCHARGS +# define PRINTF_FETCHARGS printf_fetchargs +#endif + +/* Get size_t. */ +#include + +/* Get wchar_t. */ +#if HAVE_WCHAR_T +# include +#endif + +/* Get wint_t. */ +#if HAVE_WINT_T +# include +#endif + +/* Get va_list. */ +#include + + +/* Argument types */ +typedef enum +{ + TYPE_NONE, + TYPE_SCHAR, + TYPE_UCHAR, + TYPE_SHORT, + TYPE_USHORT, + TYPE_INT, + TYPE_UINT, + TYPE_LONGINT, + TYPE_ULONGINT, +#if HAVE_LONG_LONG_INT + TYPE_LONGLONGINT, + TYPE_ULONGLONGINT, +#endif + TYPE_DOUBLE, + TYPE_LONGDOUBLE, + TYPE_CHAR, +#if HAVE_WINT_T + TYPE_WIDE_CHAR, +#endif + TYPE_STRING, +#if HAVE_WCHAR_T + TYPE_WIDE_STRING, +#endif + TYPE_POINTER, + TYPE_COUNT_SCHAR_POINTER, + TYPE_COUNT_SHORT_POINTER, + TYPE_COUNT_INT_POINTER, + TYPE_COUNT_LONGINT_POINTER +#if HAVE_LONG_LONG_INT +, TYPE_COUNT_LONGLONGINT_POINTER +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ +, TYPE_U8_STRING +, TYPE_U16_STRING +, TYPE_U32_STRING +#endif +} arg_type; + +/* Polymorphic argument */ +typedef struct +{ + arg_type type; + union + { + signed char a_schar; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long int a_longint; + unsigned long int a_ulongint; +#if HAVE_LONG_LONG_INT + long long int a_longlongint; + unsigned long long int a_ulonglongint; +#endif + float a_float; + double a_double; + long double a_longdouble; + int a_char; +#if HAVE_WINT_T + wint_t a_wide_char; +#endif + const char* a_string; +#if HAVE_WCHAR_T + const wchar_t* a_wide_string; +#endif + void* a_pointer; + signed char * a_count_schar_pointer; + short * a_count_short_pointer; + int * a_count_int_pointer; + long int * a_count_longint_pointer; +#if HAVE_LONG_LONG_INT + long long int * a_count_longlongint_pointer; +#endif +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + const uint8_t * a_u8_string; + const uint16_t * a_u16_string; + const uint32_t * a_u32_string; +#endif + } + a; +} +argument; + +typedef struct +{ + size_t count; + argument *arg; +} +arguments; + + +/* Fetch the arguments, putting them into a. */ +#ifdef STATIC +STATIC +#else +extern +#endif +int PRINTF_FETCHARGS (va_list args, arguments *a); + +#endif /* _PRINTF_ARGS_H */ diff --git a/grub-core/gnulib/printf-parse.c b/grub-core/gnulib/printf-parse.c new file mode 100644 index 000000000..f612beb5b --- /dev/null +++ b/grub-core/gnulib/printf-parse.c @@ -0,0 +1,627 @@ +/* Formatted output to strings. + Copyright (C) 1999-2000, 2002-2003, 2006-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file can be parametrized with the following macros: + CHAR_T The element type of the format string. + CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters + in the format string are ASCII. + DIRECTIVE Structure denoting a format directive. + Depends on CHAR_T. + DIRECTIVES Structure denoting the set of format directives of a + format string. Depends on CHAR_T. + PRINTF_PARSE Function that parses a format string. + Depends on CHAR_T. + STATIC Set to 'static' to declare the function static. + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ + +#ifndef PRINTF_PARSE +# include +#endif + +/* Specification. */ +#ifndef PRINTF_PARSE +# include "printf-parse.h" +#endif + +/* Default parameters. */ +#ifndef PRINTF_PARSE +# define PRINTF_PARSE printf_parse +# define CHAR_T char +# define DIRECTIVE char_directive +# define DIRECTIVES char_directives +#endif + +/* Get size_t, NULL. */ +#include + +/* Get intmax_t. */ +#if defined IN_LIBINTL || defined IN_LIBASPRINTF +# if HAVE_STDINT_H_WITH_UINTMAX +# include +# endif +# if HAVE_INTTYPES_H_WITH_UINTMAX +# include +# endif +#else +# include +#endif + +/* malloc(), realloc(), free(). */ +#include + +/* errno. */ +#include + +/* Checked size_t computations. */ +#include "xsize.h" + +#if CHAR_T_ONLY_ASCII +/* c_isascii(). */ +# include "c-ctype.h" +#endif + +#ifdef STATIC +STATIC +#endif +int +PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) +{ + const CHAR_T *cp = format; /* pointer into format */ + size_t arg_posn = 0; /* number of regular arguments consumed */ + size_t d_allocated; /* allocated elements of d->dir */ + size_t a_allocated; /* allocated elements of a->arg */ + size_t max_width_length = 0; + size_t max_precision_length = 0; + + d->count = 0; + d_allocated = 1; + d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE)); + if (d->dir == NULL) + /* Out of memory. */ + goto out_of_memory_1; + + a->count = 0; + a_allocated = 0; + a->arg = NULL; + +#define REGISTER_ARG(_index_,_type_) \ + { \ + size_t n = (_index_); \ + if (n >= a_allocated) \ + { \ + size_t memory_size; \ + argument *memory; \ + \ + a_allocated = xtimes (a_allocated, 2); \ + if (a_allocated <= n) \ + a_allocated = xsum (n, 1); \ + memory_size = xtimes (a_allocated, sizeof (argument)); \ + if (size_overflow_p (memory_size)) \ + /* Overflow, would lead to out of memory. */ \ + goto out_of_memory; \ + memory = (argument *) (a->arg \ + ? realloc (a->arg, memory_size) \ + : malloc (memory_size)); \ + if (memory == NULL) \ + /* Out of memory. */ \ + goto out_of_memory; \ + a->arg = memory; \ + } \ + while (a->count <= n) \ + a->arg[a->count++].type = TYPE_NONE; \ + if (a->arg[n].type == TYPE_NONE) \ + a->arg[n].type = (_type_); \ + else if (a->arg[n].type != (_type_)) \ + /* Ambiguous type for positional argument. */ \ + goto error; \ + } + + while (*cp != '\0') + { + CHAR_T c = *cp++; + if (c == '%') + { + size_t arg_index = ARG_NONE; + DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ + + /* Initialize the next directive. */ + dp->dir_start = cp - 1; + dp->flags = 0; + dp->width_start = NULL; + dp->width_end = NULL; + dp->width_arg_index = ARG_NONE; + dp->precision_start = NULL; + dp->precision_end = NULL; + dp->precision_arg_index = ARG_NONE; + dp->arg_index = ARG_NONE; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory later. */ + goto error; + arg_index = n - 1; + cp = np + 1; + } + } + + /* Read the flags. */ + for (;;) + { + if (*cp == '\'') + { + dp->flags |= FLAG_GROUP; + cp++; + } + else if (*cp == '-') + { + dp->flags |= FLAG_LEFT; + cp++; + } + else if (*cp == '+') + { + dp->flags |= FLAG_SHOWSIGN; + cp++; + } + else if (*cp == ' ') + { + dp->flags |= FLAG_SPACE; + cp++; + } + else if (*cp == '#') + { + dp->flags |= FLAG_ALT; + cp++; + } + else if (*cp == '0') + { + dp->flags |= FLAG_ZERO; + cp++; + } + else + break; + } + + /* Parse the field width. */ + if (*cp == '*') + { + dp->width_start = cp; + cp++; + dp->width_end = cp; + if (max_width_length < 1) + max_width_length = 1; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory later. */ + goto error; + dp->width_arg_index = n - 1; + cp = np + 1; + } + } + if (dp->width_arg_index == ARG_NONE) + { + dp->width_arg_index = arg_posn++; + if (dp->width_arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->width_arg_index, TYPE_INT); + } + else if (*cp >= '0' && *cp <= '9') + { + size_t width_length; + + dp->width_start = cp; + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + dp->width_end = cp; + width_length = dp->width_end - dp->width_start; + if (max_width_length < width_length) + max_width_length = width_length; + } + + /* Parse the precision. */ + if (*cp == '.') + { + cp++; + if (*cp == '*') + { + dp->precision_start = cp - 1; + cp++; + dp->precision_end = cp; + if (max_precision_length < 2) + max_precision_length = 2; + + /* Test for positional argument. */ + if (*cp >= '0' && *cp <= '9') + { + const CHAR_T *np; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + ; + if (*np == '$') + { + size_t n = 0; + + for (np = cp; *np >= '0' && *np <= '9'; np++) + n = xsum (xtimes (n, 10), *np - '0'); + if (n == 0) + /* Positional argument 0. */ + goto error; + if (size_overflow_p (n)) + /* n too large, would lead to out of memory + later. */ + goto error; + dp->precision_arg_index = n - 1; + cp = np + 1; + } + } + if (dp->precision_arg_index == ARG_NONE) + { + dp->precision_arg_index = arg_posn++; + if (dp->precision_arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->precision_arg_index, TYPE_INT); + } + else + { + size_t precision_length; + + dp->precision_start = cp - 1; + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + dp->precision_end = cp; + precision_length = dp->precision_end - dp->precision_start; + if (max_precision_length < precision_length) + max_precision_length = precision_length; + } + } + + { + arg_type type; + + /* Parse argument type/size specifiers. */ + { + int flags = 0; + + for (;;) + { + if (*cp == 'h') + { + flags |= (1 << (flags & 1)); + cp++; + } + else if (*cp == 'L') + { + flags |= 4; + cp++; + } + else if (*cp == 'l') + { + flags += 8; + cp++; + } + else if (*cp == 'j') + { + if (sizeof (intmax_t) > sizeof (long)) + { + /* intmax_t = long long */ + flags += 16; + } + else if (sizeof (intmax_t) > sizeof (int)) + { + /* intmax_t = long */ + flags += 8; + } + cp++; + } + else if (*cp == 'z' || *cp == 'Z') + { + /* 'z' is standardized in ISO C 99, but glibc uses 'Z' + because the warning facility in gcc-2.95.2 understands + only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ + if (sizeof (size_t) > sizeof (long)) + { + /* size_t = long long */ + flags += 16; + } + else if (sizeof (size_t) > sizeof (int)) + { + /* size_t = long */ + flags += 8; + } + cp++; + } + else if (*cp == 't') + { + if (sizeof (ptrdiff_t) > sizeof (long)) + { + /* ptrdiff_t = long long */ + flags += 16; + } + else if (sizeof (ptrdiff_t) > sizeof (int)) + { + /* ptrdiff_t = long */ + flags += 8; + } + cp++; + } +#if defined __APPLE__ && defined __MACH__ + /* On MacOS X 10.3, PRIdMAX is defined as "qd". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'q') + { + if (64 / 8 > sizeof (long)) + { + /* int64_t = long long */ + flags += 16; + } + else + { + /* int64_t = long */ + flags += 8; + } + cp++; + } +#endif +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* On native Win32, PRIdMAX is defined as "I64d". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') + { + if (64 / 8 > sizeof (long)) + { + /* __int64 = long long */ + flags += 16; + } + else + { + /* __int64 = long */ + flags += 8; + } + cp += 3; + } +#endif + else + break; + } + + /* Read the conversion character. */ + c = *cp++; + switch (c) + { + case 'd': case 'i': +#if HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGLONGINT; + else +#endif + /* If 'long long' exists and is the same as 'long', we parse + "lld" into TYPE_LONGINT. */ + if (flags >= 8) + type = TYPE_LONGINT; + else if (flags & 2) + type = TYPE_SCHAR; + else if (flags & 1) + type = TYPE_SHORT; + else + type = TYPE_INT; + break; + case 'o': case 'u': case 'x': case 'X': +#if HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_ULONGLONGINT; + else +#endif + /* If 'unsigned long long' exists and is the same as + 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ + if (flags >= 8) + type = TYPE_ULONGINT; + else if (flags & 2) + type = TYPE_UCHAR; + else if (flags & 1) + type = TYPE_USHORT; + else + type = TYPE_UINT; + break; + case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': + case 'a': case 'A': + if (flags >= 16 || (flags & 4)) + type = TYPE_LONGDOUBLE; + else + type = TYPE_DOUBLE; + break; + case 'c': + if (flags >= 8) +#if HAVE_WINT_T + type = TYPE_WIDE_CHAR; +#else + goto error; +#endif + else + type = TYPE_CHAR; + break; +#if HAVE_WINT_T + case 'C': + type = TYPE_WIDE_CHAR; + c = 'c'; + break; +#endif + case 's': + if (flags >= 8) +#if HAVE_WCHAR_T + type = TYPE_WIDE_STRING; +#else + goto error; +#endif + else + type = TYPE_STRING; + break; +#if HAVE_WCHAR_T + case 'S': + type = TYPE_WIDE_STRING; + c = 's'; + break; +#endif + case 'p': + type = TYPE_POINTER; + break; + case 'n': +#if HAVE_LONG_LONG_INT + /* If 'long long' exists and is larger than 'long': */ + if (flags >= 16 || (flags & 4)) + type = TYPE_COUNT_LONGLONGINT_POINTER; + else +#endif + /* If 'long long' exists and is the same as 'long', we parse + "lln" into TYPE_COUNT_LONGINT_POINTER. */ + if (flags >= 8) + type = TYPE_COUNT_LONGINT_POINTER; + else if (flags & 2) + type = TYPE_COUNT_SCHAR_POINTER; + else if (flags & 1) + type = TYPE_COUNT_SHORT_POINTER; + else + type = TYPE_COUNT_INT_POINTER; + break; +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + case 'U': + if (flags >= 16) + type = TYPE_U32_STRING; + else if (flags >= 8) + type = TYPE_U16_STRING; + else + type = TYPE_U8_STRING; + break; +#endif + case '%': + type = TYPE_NONE; + break; + default: + /* Unknown conversion character. */ + goto error; + } + } + + if (type != TYPE_NONE) + { + dp->arg_index = arg_index; + if (dp->arg_index == ARG_NONE) + { + dp->arg_index = arg_posn++; + if (dp->arg_index == ARG_NONE) + /* arg_posn wrapped around. */ + goto error; + } + REGISTER_ARG (dp->arg_index, type); + } + dp->conversion = c; + dp->dir_end = cp; + } + + d->count++; + if (d->count >= d_allocated) + { + size_t memory_size; + DIRECTIVE *memory; + + d_allocated = xtimes (d_allocated, 2); + memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); + if (size_overflow_p (memory_size)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + memory = (DIRECTIVE *) realloc (d->dir, memory_size); + if (memory == NULL) + /* Out of memory. */ + goto out_of_memory; + d->dir = memory; + } + } +#if CHAR_T_ONLY_ASCII + else if (!c_isascii (c)) + { + /* Non-ASCII character. Not supported. */ + goto error; + } +#endif + } + d->dir[d->count].dir_start = cp; + + d->max_width_length = max_width_length; + d->max_precision_length = max_precision_length; + return 0; + +error: + if (a->arg) + free (a->arg); + if (d->dir) + free (d->dir); + errno = EINVAL; + return -1; + +out_of_memory: + if (a->arg) + free (a->arg); + if (d->dir) + free (d->dir); +out_of_memory_1: + errno = ENOMEM; + return -1; +} + +#undef PRINTF_PARSE +#undef DIRECTIVES +#undef DIRECTIVE +#undef CHAR_T_ONLY_ASCII +#undef CHAR_T diff --git a/grub-core/gnulib/printf-parse.h b/grub-core/gnulib/printf-parse.h new file mode 100644 index 000000000..0f2b70820 --- /dev/null +++ b/grub-core/gnulib/printf-parse.h @@ -0,0 +1,180 @@ +/* Parse printf format string. + Copyright (C) 1999, 2002-2003, 2005, 2007, 2009-2010 Free Software + Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _PRINTF_PARSE_H +#define _PRINTF_PARSE_H + +/* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + STATIC Set to 'static' to declare the function static. */ + +#include "printf-args.h" + + +/* Flags */ +#define FLAG_GROUP 1 /* ' flag */ +#define FLAG_LEFT 2 /* - flag */ +#define FLAG_SHOWSIGN 4 /* + flag */ +#define FLAG_SPACE 8 /* space flag */ +#define FLAG_ALT 16 /* # flag */ +#define FLAG_ZERO 32 + +/* arg_index value indicating that no argument is consumed. */ +#define ARG_NONE (~(size_t)0) + +/* xxx_directive: A parsed directive. + xxx_directives: A parsed format string. */ + +/* A parsed directive. */ +typedef struct +{ + const char* dir_start; + const char* dir_end; + int flags; + const char* width_start; + const char* width_end; + size_t width_arg_index; + const char* precision_start; + const char* precision_end; + size_t precision_arg_index; + char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +char_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + char_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +char_directives; + +#if ENABLE_UNISTDIO + +/* A parsed directive. */ +typedef struct +{ + const uint8_t* dir_start; + const uint8_t* dir_end; + int flags; + const uint8_t* width_start; + const uint8_t* width_end; + size_t width_arg_index; + const uint8_t* precision_start; + const uint8_t* precision_end; + size_t precision_arg_index; + uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u8_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u8_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +u8_directives; + +/* A parsed directive. */ +typedef struct +{ + const uint16_t* dir_start; + const uint16_t* dir_end; + int flags; + const uint16_t* width_start; + const uint16_t* width_end; + size_t width_arg_index; + const uint16_t* precision_start; + const uint16_t* precision_end; + size_t precision_arg_index; + uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u16_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u16_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +u16_directives; + +/* A parsed directive. */ +typedef struct +{ + const uint32_t* dir_start; + const uint32_t* dir_end; + int flags; + const uint32_t* width_start; + const uint32_t* width_end; + size_t width_arg_index; + const uint32_t* precision_start; + const uint32_t* precision_end; + size_t precision_arg_index; + uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ + size_t arg_index; +} +u32_directive; + +/* A parsed format string. */ +typedef struct +{ + size_t count; + u32_directive *dir; + size_t max_width_length; + size_t max_precision_length; +} +u32_directives; + +#endif + + +/* Parses the format string. Fills in the number N of directives, and fills + in directives[0], ..., directives[N-1], and sets directives[N].dir_start + to the end of the format string. Also fills in the arg_type fields of the + arguments and the needed count of arguments. */ +#if ENABLE_UNISTDIO +extern int + ulc_printf_parse (const char *format, char_directives *d, arguments *a); +extern int + u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a); +extern int + u16_printf_parse (const uint16_t *format, u16_directives *d, + arguments *a); +extern int + u32_printf_parse (const uint32_t *format, u32_directives *d, + arguments *a); +#else +# ifdef STATIC +STATIC +# else +extern +# endif +int printf_parse (const char *format, char_directives *d, arguments *a); +#endif + +#endif /* _PRINTF_PARSE_H */ diff --git a/grub-core/gnulib/rawmemchr.c b/grub-core/gnulib/rawmemchr.c new file mode 100644 index 000000000..0a88777d9 --- /dev/null +++ b/grub-core/gnulib/rawmemchr.c @@ -0,0 +1,136 @@ +/* Searching in a string. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Find the first occurrence of C in S. */ +void * +rawmemchr (const void *s, int c_in) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned char c; + + c = (unsigned char) c_in; + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + (size_t) char_ptr % sizeof (longword) != 0; + ++char_ptr) + if (*char_ptr == c) + return (void *) char_ptr; + + longword_ptr = (const longword *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will + test a longword at a time. The tricky part is testing if *any of + the four* bytes in the longword in question are equal to NUL or + c. We first use an xor with repeated_c. This reduces the task + to testing whether *any of the four* bytes in longword1 is zero. + + We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + The test whether any byte in longword1 is zero is equivalent + to testing whether tmp is nonzero. + + This test can read beyond the end of a string, depending on where + C_IN is encountered. However, this is considered safe since the + initialization phase ensured that the read will be aligned, + therefore, the read will not cross page boundaries and will not + cause a fault. */ + + while (1) + { + longword longword1 = *longword_ptr ^ repeated_c; + + if ((((longword1 - repeated_one) & ~longword1) + & (repeated_one << 7)) != 0) + break; + longword_ptr++; + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that one of the sizeof (longword) bytes + starting at char_ptr is == c. On little-endian machines, we + could determine the first such byte without any further memory + accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. + Choose code that works in both cases. */ + + char_ptr = (unsigned char *) longword_ptr; + while (*char_ptr != c) + char_ptr++; + return (void *) char_ptr; +} diff --git a/grub-core/gnulib/rawmemchr.valgrind b/grub-core/gnulib/rawmemchr.valgrind new file mode 100644 index 000000000..636392368 --- /dev/null +++ b/grub-core/gnulib/rawmemchr.valgrind @@ -0,0 +1,12 @@ +# Suppress a valgrind message about use of uninitialized memory in rawmemchr(). +# This use is OK because it provides only a speedup. +{ + rawmemchr-value4 + Memcheck:Value4 + fun:rawmemchr +} +{ + rawmemchr-value8 + Memcheck:Value8 + fun:rawmemchr +} diff --git a/grub-core/gnulib/realloc.c b/grub-core/gnulib/realloc.c new file mode 100644 index 000000000..053208f37 --- /dev/null +++ b/grub-core/gnulib/realloc.c @@ -0,0 +1,91 @@ +/* realloc() function that is glibc compatible. + + Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2010 Free Software + Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +/* written by Jim Meyering and Bruno Haible */ + +#include + +/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */ +#ifdef realloc +# define NEED_REALLOC_GNU 1 +/* Whereas the gnulib module 'realloc-gnu' defines HAVE_REALLOC_GNU. */ +#elif GNULIB_REALLOC_GNU && !HAVE_REALLOC_GNU +# define NEED_REALLOC_GNU 1 +#endif + +/* Infer the properties of the system's malloc function. + The gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ +#if GNULIB_MALLOC_GNU && HAVE_MALLOC_GNU +# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1 +#endif + +/* Below we want to call the system's malloc and realloc. + Undefine the symbols here so that including provides a + declaration of malloc(), not of rpl_malloc(), and likewise for realloc. */ +#undef malloc +#undef realloc + +/* Specification. */ +#include + +#include + +/* Below we want to call the system's malloc and realloc. + Undefine the symbols, if they were defined by gnulib's + replacement. */ +#undef malloc +#undef realloc + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. If N is zero, change it to 1. If P is NULL, + use malloc. */ + +void * +rpl_realloc (void *p, size_t n) +{ + void *result; + +#if NEED_REALLOC_GNU + if (n == 0) + { + n = 1; + + /* In theory realloc might fail, so don't rely on it to free. */ + free (p); + p = NULL; + } +#endif + + if (p == NULL) + { +#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE + if (n == 0) + n = 1; +#endif + result = malloc (n); + } + else + result = realloc (p, n); + +#if !HAVE_REALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/grub-core/gnulib/ref-add.sin b/grub-core/gnulib/ref-add.sin new file mode 100644 index 000000000..dbb61df3d --- /dev/null +++ b/grub-core/gnulib/ref-add.sin @@ -0,0 +1,30 @@ +# Add this package to a list of references stored in a text file. +# +# Copyright (C) 2000, 2009, 2010 Free Software Foundation, Inc. +# +# This program 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, or (at your option) +# any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + ta + :a + s/ @PACKAGE@ / @PACKAGE@ / + tb + s/ $/ @PACKAGE@ / + :b + s/^/# Packages using this file:/ +} diff --git a/grub-core/gnulib/ref-del.sin b/grub-core/gnulib/ref-del.sin new file mode 100644 index 000000000..4c31a6eaf --- /dev/null +++ b/grub-core/gnulib/ref-del.sin @@ -0,0 +1,25 @@ +# Remove this package from a list of references stored in a text file. +# +# Copyright (C) 2000, 2009, 2010 Free Software Foundation, Inc. +# +# This program 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, or (at your option) +# any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + s/ @PACKAGE@ / / + s/^/# Packages using this file:/ +} diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c index 7eff56925..86ca02b0c 100644 --- a/grub-core/gnulib/regcomp.c +++ b/grub-core/gnulib/regcomp.c @@ -6,7 +6,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c index 904fe62c8..ba0eebee7 100644 --- a/grub-core/gnulib/regex.c +++ b/grub-core/gnulib/regex.c @@ -6,7 +6,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/regex.h b/grub-core/gnulib/regex.h index 89a8143d4..e8bd5496c 100644 --- a/grub-core/gnulib/regex.h +++ b/grub-core/gnulib/regex.h @@ -7,7 +7,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/regex_internal.c b/grub-core/gnulib/regex_internal.c index 787a3a627..98b8d5d21 100644 --- a/grub-core/gnulib/regex_internal.c +++ b/grub-core/gnulib/regex_internal.c @@ -6,7 +6,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/regex_internal.h b/grub-core/gnulib/regex_internal.h index dc94e2cbc..5aa5aa287 100644 --- a/grub-core/gnulib/regex_internal.h +++ b/grub-core/gnulib/regex_internal.h @@ -6,7 +6,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c index 9388ac12b..dc449ce52 100644 --- a/grub-core/gnulib/regexec.c +++ b/grub-core/gnulib/regexec.c @@ -6,7 +6,7 @@ This program 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 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/grub-core/gnulib/size_max.h b/grub-core/gnulib/size_max.h new file mode 100644 index 000000000..56d5a9b1c --- /dev/null +++ b/grub-core/gnulib/size_max.h @@ -0,0 +1,31 @@ +/* size_max.h -- declare SIZE_MAX through system headers + Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef GNULIB_SIZE_MAX_H +#define GNULIB_SIZE_MAX_H + +/* Get SIZE_MAX declaration on systems like Solaris 7/8/9. */ +# include +/* Get SIZE_MAX declaration on systems like glibc 2. */ +# if HAVE_STDINT_H +# include +# endif +/* On systems where these include files don't define it, SIZE_MAX is defined + in config.h. */ + +#endif /* GNULIB_SIZE_MAX_H */ diff --git a/grub-core/gnulib/sleep.c b/grub-core/gnulib/sleep.c new file mode 100644 index 000000000..213e5bd29 --- /dev/null +++ b/grub-core/gnulib/sleep.c @@ -0,0 +1,75 @@ +/* Pausing execution of the current thread. + Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2007. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#include "verify.h" + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +unsigned int +sleep (unsigned int seconds) +{ + unsigned int remaining; + + /* Sleep for 1 second many times, because + 1. Sleep is not interruptiple by Ctrl-C, + 2. we want to avoid arithmetic overflow while multiplying with 1000. */ + for (remaining = seconds; remaining > 0; remaining--) + Sleep (1000); + + return remaining; +} + +#elif HAVE_SLEEP + +# undef sleep + +/* Guarantee unlimited sleep and a reasonable return value. Cygwin + 1.5.x rejects attempts to sleep more than 49.7 days (2**32 + milliseconds), but uses uninitialized memory which results in a + garbage answer. */ +unsigned int +rpl_sleep (unsigned int seconds) +{ + /* This requires int larger than 16 bits. */ + verify (UINT_MAX / 49 / 24 / 60 / 60); + const unsigned int limit = 49 * 24 * 60 * 60; + while (limit < seconds) + { + unsigned int result; + seconds -= limit; + result = sleep (limit); + if (result) + return seconds + result; + } + return sleep (seconds); +} + +#else /* !HAVE_SLEEP */ + + #error "Please port gnulib sleep.c to your platform, possibly using usleep() or select(), then report this to bug-gnulib." + +#endif diff --git a/grub-core/gnulib/stdbool.in.h b/grub-core/gnulib/stdbool.in.h new file mode 100644 index 000000000..574c281a8 --- /dev/null +++ b/grub-core/gnulib/stdbool.in.h @@ -0,0 +1,122 @@ +/* Copyright (C) 2001-2003, 2006-2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STDBOOL_H +#define _GL_STDBOOL_H + +/* ISO C 99 for platforms that lack it. */ + +/* Usage suggestions: + + Programs that use should be aware of some limitations + and standards compliance issues. + + Standards compliance: + + - must be #included before 'bool', 'false', 'true' + can be used. + + - You cannot assume that sizeof (bool) == 1. + + - Programs should not undefine the macros bool, true, and false, + as C99 lists that as an "obsolescent feature". + + Limitations of this substitute, when used in a C89 environment: + + - must be #included before the '_Bool' type can be used. + + - You cannot assume that _Bool is a typedef; it might be a macro. + + - Bit-fields of type 'bool' are not supported. Portable code + should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'. + + - In C99, casts and automatic conversions to '_Bool' or 'bool' are + performed in such a way that every nonzero value gets converted + to 'true', and zero gets converted to 'false'. This doesn't work + with this substitute. With this substitute, only the values 0 and 1 + give the expected result when converted to _Bool' or 'bool'. + + - C99 allows the use of (_Bool)0.0 in constant expressions, but + this substitute cannot always provide this property. + + Also, it is suggested that programs use 'bool' rather than '_Bool'; + this isn't required, but 'bool' is more common. */ + + +/* 7.16. Boolean type and values */ + +/* BeOS already #defines false 0, true 1. We use the same + definitions below, but temporarily we have to #undef them. */ +#if defined __BEOS__ && !defined __HAIKU__ +# include /* defines bool but not _Bool */ +# undef false +# undef true +#endif + +/* For the sake of symbolic names in gdb, we define true and false as + enum constants, not only as macros. + It is tempting to write + typedef enum { false = 0, true = 1 } _Bool; + so that gdb prints values of type 'bool' symbolically. But if we do + this, values of type '_Bool' may promote to 'int' or 'unsigned int' + (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' + (see ISO C 99 6.3.1.1.(2)). So we add a negative value to the + enum; this ensures that '_Bool' promotes to 'int'. */ +#if defined __cplusplus || (defined __BEOS__ && !defined __HAIKU__) + /* A compiler known to have 'bool'. */ + /* If the compiler already has both 'bool' and '_Bool', we can assume they + are the same types. */ +# if !@HAVE__BOOL@ +typedef bool _Bool; +# endif +#else +# if !defined __GNUC__ + /* If @HAVE__BOOL@: + Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when + the built-in _Bool type is used. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + Similar bugs are likely with other compilers as well; this file + wouldn't be used if was working. + So we override the _Bool type. + If !@HAVE__BOOL@: + Need to define _Bool ourselves. As 'signed char' or as an enum type? + Use of a typedef, with SunPRO C, leads to a stupid + "warning: _Bool is a keyword in ISO C99". + Use of an enum type, with IRIX cc, leads to a stupid + "warning(1185): enumerated type mixed with another type". + Even the existence of an enum type, without a typedef, + "Invalid enumerator. (badenum)" with HP-UX cc on Tru64. + The only benefit of the enum, debuggability, is not important + with these compilers. So use 'signed char' and no enum. */ +# define _Bool signed char +# else + /* With this compiler, trust the _Bool type if the compiler has it. */ +# if !@HAVE__BOOL@ +typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; +# endif +# endif +#endif +#define bool _Bool + +/* The other macros must be usable in preprocessor directives. */ +#define false 0 +#define true 1 +#define __bool_true_false_are_defined 1 + +#endif /* _GL_STDBOOL_H */ diff --git a/grub-core/gnulib/stddef.in.h b/grub-core/gnulib/stddef.in.h new file mode 100644 index 000000000..08778a233 --- /dev/null +++ b/grub-core/gnulib/stddef.in.h @@ -0,0 +1,86 @@ +/* A substitute for POSIX 2008 , for platforms that have issues. + + Copyright (C) 2009, 2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Eric Blake. */ + +/* + * POSIX 2008 for platforms that have issues. + * + */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if defined __need_wchar_t || defined __need_size_t \ + || defined __need_ptrdiff_t || defined __need_NULL \ + || defined __need_wint_t +/* Special invocation convention inside gcc header files. In + particular, gcc provides a version of that blindly + redefines NULL even when __need_wint_t was defined, even though + wint_t is not normally provided by . Hence, we must + remember if special invocation has ever been used to obtain wint_t, + in which case we need to clean up NULL yet again. */ + +# if !(defined _GL_STDDEF_H && defined _GL_STDDEF_WINT_T) +# ifdef __need_wint_t +# undef _GL_STDDEF_H +# define _GL_STDDEF_WINT_T +# endif +# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ +# endif + +#else +/* Normal invocation convention. */ + +# ifndef _GL_STDDEF_H + +/* The include_next requires a split double-inclusion guard. */ + +# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ + +# ifndef _GL_STDDEF_H +# define _GL_STDDEF_H + +/* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ +#if @REPLACE_NULL@ +# undef NULL +# ifdef __cplusplus + /* ISO C++ says that the macro NULL must expand to an integer constant + expression, hence '((void *) 0)' is not allowed in C++. */ +# if __GNUG__ >= 3 + /* GNU C++ has a __null macro that behaves like an integer ('int' or + 'long') but has the same size as a pointer. Use that, to avoid + warnings. */ +# define NULL __null +# else +# define NULL 0L +# endif +# else +# define NULL ((void *) 0) +# endif +#endif + +/* Some platforms lack wchar_t. */ +#if !@HAVE_WCHAR_T@ +# define wchar_t int +#endif + +# endif /* _GL_STDDEF_H */ +# endif /* _GL_STDDEF_H */ +#endif /* __need_XXX */ diff --git a/grub-core/gnulib/stdint.in.h b/grub-core/gnulib/stdint.in.h new file mode 100644 index 000000000..5da5f1788 --- /dev/null +++ b/grub-core/gnulib/stdint.in.h @@ -0,0 +1,568 @@ +/* Copyright (C) 2001-2002, 2004-2010 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. + This file is part of gnulib. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* + * ISO C 99 for platforms that lack it. + * + */ + +#ifndef _GL_STDINT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* When including a system file that in turn includes , + use the system , not our substitute. This avoids + problems with (for example) VMS, whose includes + . */ +#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* Get those types that are already defined in other system include + files, so that we can "#define int8_t signed char" below without + worrying about a later system include file containing a "typedef + signed char int8_t;" that will get messed up by our macro. Our + macros should all be consistent with the system versions, except + for the "fast" types and macros, which we recommend against using + in public interfaces due to compiler differences. */ + +#if @HAVE_STDINT_H@ +# if defined __sgi && ! defined __c99 + /* Bypass IRIX's if in C89 mode, since it merely annoys users + with "This header file is to be used only for c99 mode compilations" + diagnostics. */ +# define __STDINT_H__ +# endif + /* Other systems may have an incomplete or buggy . + Include it before , since any "#include " + in would reinclude us, skipping our contents because + _GL_STDINT_H is defined. + The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_STDINT_H@ +#endif + +#if ! defined _GL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H +#define _GL_STDINT_H + +/* defines some of the stdint.h types as well, on glibc, + IRIX 6.5, and OpenBSD 3.8 (via ). + AIX 5.2 isn't needed and causes troubles. + MacOS X 10.4.6 includes (which is us), but + relies on the system definitions, so include + after @NEXT_STDINT_H@. */ +#if @HAVE_SYS_TYPES_H@ && ! defined _AIX +# include +#endif + +/* Get LONG_MIN, LONG_MAX, ULONG_MAX. */ +#include + +#if @HAVE_INTTYPES_H@ + /* In OpenBSD 3.8, includes , which defines + int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. + also defines intptr_t and uintptr_t. */ +# include +#elif @HAVE_SYS_INTTYPES_H@ + /* Solaris 7 has the types except the *_fast*_t types, and + the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +# include +#endif + +#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ + /* Linux libc4 >= 4.6.7 and libc5 have a that defines + int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is + included by . */ +# include +#endif + +#undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +/* Minimum and maximum values for a integer type under the usual assumption. + Return an unspecified value if BITS == 0, adding a check to pacify + picky compilers. */ + +#define _STDINT_MIN(signed, bits, zero) \ + ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) + +#define _STDINT_MAX(signed, bits, zero) \ + ((signed) \ + ? ~ _STDINT_MIN (signed, bits, zero) \ + : /* The expression for the unsigned case. The subtraction of (signed) \ + is a nop in the unsigned case and avoids "signed integer overflow" \ + warnings in the signed case. */ \ + ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) + +/* 7.18.1.1. Exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +#undef int8_t +#undef uint8_t +typedef signed char gl_int8_t; +typedef unsigned char gl_uint8_t; +#define int8_t gl_int8_t +#define uint8_t gl_uint8_t + +#undef int16_t +#undef uint16_t +typedef short int gl_int16_t; +typedef unsigned short int gl_uint16_t; +#define int16_t gl_int16_t +#define uint16_t gl_uint16_t + +#undef int32_t +#undef uint32_t +typedef int gl_int32_t; +typedef unsigned int gl_uint32_t; +#define int32_t gl_int32_t +#define uint32_t gl_uint32_t + +/* Do not undefine int64_t if gnulib is not being used with 64-bit + types, since otherwise it breaks platforms like Tandem/NSK. */ +#if LONG_MAX >> 31 >> 31 == 1 +# undef int64_t +typedef long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +#elif defined _MSC_VER +# undef int64_t +typedef __int64 gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +#elif @HAVE_LONG_LONG_INT@ +# undef int64_t +typedef long long int gl_int64_t; +# define int64_t gl_int64_t +# define GL_INT64_T +#endif + +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# undef uint64_t +typedef unsigned long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +#elif defined _MSC_VER +# undef uint64_t +typedef unsigned __int64 gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# undef uint64_t +typedef unsigned long long int gl_uint64_t; +# define uint64_t gl_uint64_t +# define GL_UINT64_T +#endif + +/* Avoid collision with Solaris 2.5.1 etc. */ +#define _UINT8_T +#define _UINT32_T +#define _UINT64_T + + +/* 7.18.1.2. Minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +#undef int_least8_t +#undef uint_least8_t +#undef int_least16_t +#undef uint_least16_t +#undef int_least32_t +#undef uint_least32_t +#undef int_least64_t +#undef uint_least64_t +#define int_least8_t int8_t +#define uint_least8_t uint8_t +#define int_least16_t int16_t +#define uint_least16_t uint16_t +#define int_least32_t int32_t +#define uint_least32_t uint32_t +#ifdef GL_INT64_T +# define int_least64_t int64_t +#endif +#ifdef GL_UINT64_T +# define uint_least64_t uint64_t +#endif + +/* 7.18.1.3. Fastest minimum-width integer types */ + +/* Note: Other substitutes may define these types differently. + It is not recommended to use these types in public header files. */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. Assume that 'long int' + is fast enough for all narrower integers. */ + +#undef int_fast8_t +#undef uint_fast8_t +#undef int_fast16_t +#undef uint_fast16_t +#undef int_fast32_t +#undef uint_fast32_t +#undef int_fast64_t +#undef uint_fast64_t +typedef long int gl_int_fast8_t; +typedef unsigned long int gl_uint_fast8_t; +typedef long int gl_int_fast16_t; +typedef unsigned long int gl_uint_fast16_t; +typedef long int gl_int_fast32_t; +typedef unsigned long int gl_uint_fast32_t; +#define int_fast8_t gl_int_fast8_t +#define uint_fast8_t gl_uint_fast8_t +#define int_fast16_t gl_int_fast16_t +#define uint_fast16_t gl_uint_fast16_t +#define int_fast32_t gl_int_fast32_t +#define uint_fast32_t gl_uint_fast32_t +#ifdef GL_INT64_T +# define int_fast64_t int64_t +#endif +#ifdef GL_UINT64_T +# define uint_fast64_t uint64_t +#endif + +/* 7.18.1.4. Integer types capable of holding object pointers */ + +#undef intptr_t +#undef uintptr_t +typedef long int gl_intptr_t; +typedef unsigned long int gl_uintptr_t; +#define intptr_t gl_intptr_t +#define uintptr_t gl_uintptr_t + +/* 7.18.1.5. Greatest-width integer types */ + +/* Note: These types are compiler dependent. It may be unwise to use them in + public header files. */ + +#undef intmax_t +#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +typedef long long int gl_intmax_t; +# define intmax_t gl_intmax_t +#elif defined GL_INT64_T +# define intmax_t int64_t +#else +typedef long int gl_intmax_t; +# define intmax_t gl_intmax_t +#endif + +#undef uintmax_t +#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +typedef unsigned long long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +#elif defined GL_UINT64_T +# define uintmax_t uint64_t +#else +typedef unsigned long int gl_uintmax_t; +# define uintmax_t gl_uintmax_t +#endif + +/* Verify that intmax_t and uintmax_t have the same size. Too much code + breaks if this is not the case. If this check fails, the reason is likely + to be found in the autoconf macros. */ +typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - 1]; + +/* 7.18.2. Limits of specified-width integer types */ + +#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS + +/* 7.18.2.1. Limits of exact-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. */ + +#undef INT8_MIN +#undef INT8_MAX +#undef UINT8_MAX +#define INT8_MIN (~ INT8_MAX) +#define INT8_MAX 127 +#define UINT8_MAX 255 + +#undef INT16_MIN +#undef INT16_MAX +#undef UINT16_MAX +#define INT16_MIN (~ INT16_MAX) +#define INT16_MAX 32767 +#define UINT16_MAX 65535 + +#undef INT32_MIN +#undef INT32_MAX +#undef UINT32_MAX +#define INT32_MIN (~ INT32_MAX) +#define INT32_MAX 2147483647 +#define UINT32_MAX 4294967295U + +#undef INT64_MIN +#undef INT64_MAX +#ifdef GL_INT64_T +/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 + evaluates the latter incorrectly in preprocessor expressions. */ +# define INT64_MIN (- INTMAX_C (1) << 63) +# define INT64_MAX INTMAX_C (9223372036854775807) +#endif + +#undef UINT64_MAX +#ifdef GL_UINT64_T +# define UINT64_MAX UINTMAX_C (18446744073709551615) +#endif + +/* 7.18.2.2. Limits of minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types + are the same as the corresponding N_t types. */ + +#undef INT_LEAST8_MIN +#undef INT_LEAST8_MAX +#undef UINT_LEAST8_MAX +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define UINT_LEAST8_MAX UINT8_MAX + +#undef INT_LEAST16_MIN +#undef INT_LEAST16_MAX +#undef UINT_LEAST16_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define UINT_LEAST16_MAX UINT16_MAX + +#undef INT_LEAST32_MIN +#undef INT_LEAST32_MAX +#undef UINT_LEAST32_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST32_MAX UINT32_MAX + +#undef INT_LEAST64_MIN +#undef INT_LEAST64_MAX +#ifdef GL_INT64_T +# define INT_LEAST64_MIN INT64_MIN +# define INT_LEAST64_MAX INT64_MAX +#endif + +#undef UINT_LEAST64_MAX +#ifdef GL_UINT64_T +# define UINT_LEAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.3. Limits of fastest minimum-width integer types */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types + are taken from the same list of types. */ + +#undef INT_FAST8_MIN +#undef INT_FAST8_MAX +#undef UINT_FAST8_MAX +#define INT_FAST8_MIN LONG_MIN +#define INT_FAST8_MAX LONG_MAX +#define UINT_FAST8_MAX ULONG_MAX + +#undef INT_FAST16_MIN +#undef INT_FAST16_MAX +#undef UINT_FAST16_MAX +#define INT_FAST16_MIN LONG_MIN +#define INT_FAST16_MAX LONG_MAX +#define UINT_FAST16_MAX ULONG_MAX + +#undef INT_FAST32_MIN +#undef INT_FAST32_MAX +#undef UINT_FAST32_MAX +#define INT_FAST32_MIN LONG_MIN +#define INT_FAST32_MAX LONG_MAX +#define UINT_FAST32_MAX ULONG_MAX + +#undef INT_FAST64_MIN +#undef INT_FAST64_MAX +#ifdef GL_INT64_T +# define INT_FAST64_MIN INT64_MIN +# define INT_FAST64_MAX INT64_MAX +#endif + +#undef UINT_FAST64_MAX +#ifdef GL_UINT64_T +# define UINT_FAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.4. Limits of integer types capable of holding object pointers */ + +#undef INTPTR_MIN +#undef INTPTR_MAX +#undef UINTPTR_MAX +#define INTPTR_MIN LONG_MIN +#define INTPTR_MAX LONG_MAX +#define UINTPTR_MAX ULONG_MAX + +/* 7.18.2.5. Limits of greatest-width integer types */ + +#undef INTMAX_MIN +#undef INTMAX_MAX +#ifdef INT64_MAX +# define INTMAX_MIN INT64_MIN +# define INTMAX_MAX INT64_MAX +#else +# define INTMAX_MIN INT32_MIN +# define INTMAX_MAX INT32_MAX +#endif + +#undef UINTMAX_MAX +#ifdef UINT64_MAX +# define UINTMAX_MAX UINT64_MAX +#else +# define UINTMAX_MAX UINT32_MAX +#endif + +/* 7.18.3. Limits of other integer types */ + +/* ptrdiff_t limits */ +#undef PTRDIFF_MIN +#undef PTRDIFF_MAX +#if @APPLE_UNIVERSAL_BUILD@ +# ifdef _LP64 +# define PTRDIFF_MIN _STDINT_MIN (1, 64, 0l) +# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +# else +# define PTRDIFF_MIN _STDINT_MIN (1, 32, 0) +# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) +# endif +#else +# define PTRDIFF_MIN \ + _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +# define PTRDIFF_MAX \ + _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +#endif + +/* sig_atomic_t limits */ +#undef SIG_ATOMIC_MIN +#undef SIG_ATOMIC_MAX +#define SIG_ATOMIC_MIN \ + _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) +#define SIG_ATOMIC_MAX \ + _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ + 0@SIG_ATOMIC_T_SUFFIX@) + + +/* size_t limit */ +#undef SIZE_MAX +#if @APPLE_UNIVERSAL_BUILD@ +# ifdef _LP64 +# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +# else +# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +# endif +#else +# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) +#endif + +/* wchar_t limits */ +/* Get WCHAR_MIN, WCHAR_MAX. + This include is not on the top, above, because on OSF/1 4.0 we have a sequence of nested + includes -> -> -> , and the latter includes + and assumes its types are already defined. */ +#if ! (defined WCHAR_MIN && defined WCHAR_MAX) +# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +# include +# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +#endif +#undef WCHAR_MIN +#undef WCHAR_MAX +#define WCHAR_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +#define WCHAR_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) + +/* wint_t limits */ +#undef WINT_MIN +#undef WINT_MAX +#define WINT_MIN \ + _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +#define WINT_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) + +#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */ + +/* 7.18.4. Macros for integer constants */ + +#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS + +/* 7.18.4.1. Macros for minimum-width integer constants */ +/* According to ISO C 99 Technical Corrigendum 1 */ + +/* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ + +#undef INT8_C +#undef UINT8_C +#define INT8_C(x) x +#define UINT8_C(x) x + +#undef INT16_C +#undef UINT16_C +#define INT16_C(x) x +#define UINT16_C(x) x + +#undef INT32_C +#undef UINT32_C +#define INT32_C(x) x +#define UINT32_C(x) x ## U + +#undef INT64_C +#undef UINT64_C +#if LONG_MAX >> 31 >> 31 == 1 +# define INT64_C(x) x##L +#elif defined _MSC_VER +# define INT64_C(x) x##i64 +#elif @HAVE_LONG_LONG_INT@ +# define INT64_C(x) x##LL +#endif +#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +# define UINT64_C(x) x##UL +#elif defined _MSC_VER +# define UINT64_C(x) x##ui64 +#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +# define UINT64_C(x) x##ULL +#endif + +/* 7.18.4.2. Macros for greatest-width integer constants */ + +#undef INTMAX_C +#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +# define INTMAX_C(x) x##LL +#elif defined GL_INT64_T +# define INTMAX_C(x) INT64_C(x) +#else +# define INTMAX_C(x) x##L +#endif + +#undef UINTMAX_C +#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +# define UINTMAX_C(x) x##ULL +#elif defined GL_UINT64_T +# define UINTMAX_C(x) UINT64_C(x) +#else +# define UINTMAX_C(x) x##UL +#endif + +#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */ + +#endif /* _GL_STDINT_H */ +#endif /* !defined _GL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/grub-core/gnulib/stdio-write.c b/grub-core/gnulib/stdio-write.c new file mode 100644 index 000000000..a6a0eb143 --- /dev/null +++ b/grub-core/gnulib/stdio-write.c @@ -0,0 +1,148 @@ +/* POSIX compatible FILE stream write function. + Copyright (C) 2008-2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Replace these functions only if module 'sigpipe' is requested. */ +#if GNULIB_SIGPIPE + +/* On native Windows platforms, SIGPIPE does not exist. When write() is + called on a pipe with no readers, WriteFile() fails with error + GetLastError() = ERROR_NO_DATA, and write() in consequence fails with + error EINVAL. This write() function is at the basis of the function + which flushes the buffer of a FILE stream. */ + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# include +# include +# include + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \ + if (ferror (stream)) \ + return (EXPRESSION); \ + else \ + { \ + RETTYPE ret; \ + SetLastError (0); \ + ret = (EXPRESSION); \ + if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream)) \ + { \ + int fd = fileno (stream); \ + if (fd >= 0 \ + && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\ + { \ + /* Try to raise signal SIGPIPE. */ \ + raise (SIGPIPE); \ + /* If it is currently blocked or ignored, change errno from \ + EINVAL to EPIPE. */ \ + errno = EPIPE; \ + } \ + } \ + return ret; \ + } + +# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */ +int +printf (const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfprintf (stdout, format, args); + va_end (args); + + return retval; +} +# endif + +# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */ +int +fprintf (FILE *stream, const char *format, ...) +{ + int retval; + va_list args; + + va_start (args, format); + retval = vfprintf (stream, format, args); + va_end (args); + + return retval; +} +# endif + +# if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */ +int +vprintf (const char *format, va_list args) +{ + return vfprintf (stdout, format, args); +} +# endif + +# if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */ +int +vfprintf (FILE *stream, const char *format, va_list args) +#undef vfprintf +{ + CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF) +} +# endif + +int +putchar (int c) +{ + return fputc (c, stdout); +} + +int +fputc (int c, FILE *stream) +#undef fputc +{ + CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF) +} + +int +fputs (const char *string, FILE *stream) +#undef fputs +{ + CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF) +} + +int +puts (const char *string) +#undef puts +{ + FILE *stream = stdout; + CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF) +} + +size_t +fwrite (const void *ptr, size_t s, size_t n, FILE *stream) +#undef fwrite +{ + CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n) +} + +# endif +#endif diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h new file mode 100644 index 000000000..80b9dbfda --- /dev/null +++ b/grub-core/gnulib/stdio.in.h @@ -0,0 +1,1071 @@ +/* A GNU-like . + + Copyright (C) 2004, 2007-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if defined __need_FILE || defined __need___FILE +/* Special invocation convention inside glibc header files. */ + +#@INCLUDE_NEXT@ @NEXT_STDIO_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _GL_STDIO_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDIO_H@ + +#ifndef _GL_STDIO_H +#define _GL_STDIO_H + +/* Get va_list. Needed on many systems, including glibc 2.8. */ +#include + +#include + +/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8. */ +#include + +#ifndef __attribute__ +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable __attribute__ only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(Spec) /* empty */ +# endif +#endif + + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Macros for stringification. */ +#define _GL_STDIO_STRINGIZE(token) #token +#define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token) + + +#if @GNULIB_DPRINTF@ +# if @REPLACE_DPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dprintf rpl_dprintf +# endif +_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *format, ...)); +# else +# if !@HAVE_DPRINTF@ +_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *format, ...)); +# endif +_GL_CXXALIASWARN (dprintf); +#elif defined GNULIB_POSIXCHECK +# undef dprintf +# if HAVE_RAW_DECL_DPRINTF +_GL_WARN_ON_USE (dprintf, "dprintf is unportable - " + "use gnulib module dprintf for portability"); +# endif +#endif + +#if @GNULIB_FCLOSE@ +/* Close STREAM and its underlying file descriptor. */ +# if @REPLACE_FCLOSE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fclose rpl_fclose +# endif +_GL_FUNCDECL_RPL (fclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (fclose, int, (FILE *stream)); +# else +_GL_CXXALIAS_SYS (fclose, int, (FILE *stream)); +# endif +_GL_CXXALIASWARN (fclose); +#elif defined GNULIB_POSIXCHECK +# undef fclose +/* Assume fclose is always declared. */ +_GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " + "use gnulib module fclose for portable POSIX compliance"); +#endif + +#if @GNULIB_FFLUSH@ +/* Flush all pending data on STREAM according to POSIX rules. Both + output and seekable input streams are supported. + Note! LOSS OF DATA can occur if fflush is applied on an input stream + that is _not_seekable_ or on an update stream that is _not_seekable_ + and in which the most recent operation was input. Seekability can + be tested with lseek(fileno(fp),0,SEEK_CUR). */ +# if @REPLACE_FFLUSH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fflush rpl_fflush +# endif +_GL_FUNCDECL_RPL (fflush, int, (FILE *gl_stream)); +_GL_CXXALIAS_RPL (fflush, int, (FILE *gl_stream)); +# else +_GL_CXXALIAS_SYS (fflush, int, (FILE *gl_stream)); +# endif +_GL_CXXALIASWARN (fflush); +#elif defined GNULIB_POSIXCHECK +# undef fflush +/* Assume fflush is always declared. */ +_GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " + "use gnulib module fflush for portable POSIX compliance"); +#endif + +/* It is very rare that the developer ever has full control of stdin, + so any use of gets warrants an unconditional warning. Assume it is + always declared, since it is required by C89. */ +#undef gets +_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); + +#if @GNULIB_FOPEN@ +# if @REPLACE_FOPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fopen +# define fopen rpl_fopen +# endif +_GL_FUNCDECL_RPL (fopen, FILE *, (const char *filename, const char *mode) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fopen, FILE *, (const char *filename, const char *mode)); +# else +_GL_CXXALIAS_SYS (fopen, FILE *, (const char *filename, const char *mode)); +# endif +_GL_CXXALIASWARN (fopen); +#elif defined GNULIB_POSIXCHECK +# undef fopen +/* Assume fopen is always declared. */ +_GL_WARN_ON_USE (fopen, "fopen on Win32 platforms is not POSIX compatible - " + "use gnulib module fopen for portability"); +#endif + +#if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@ +# if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \ + || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fprintf rpl_fprintf +# endif +# define GNULIB_overrides_fprintf 1 +_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fprintf, int, (FILE *fp, const char *format, ...)); +# else +_GL_CXXALIAS_SYS (fprintf, int, (FILE *fp, const char *format, ...)); +# endif +_GL_CXXALIASWARN (fprintf); +#endif +#if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK +# if !GNULIB_overrides_fprintf +# undef fprintf +# endif +/* Assume fprintf is always declared. */ +_GL_WARN_ON_USE (fprintf, "fprintf is not always POSIX compliant - " + "use gnulib module fprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_FPURGE@ +/* Discard all pending buffered I/O data on STREAM. + STREAM must not be wide-character oriented. + When discarding pending output, the file position is set back to where it + was before the write calls. When discarding pending input, the file + position is advanced to match the end of the previously read input. + Return 0 if successful. Upon error, return -1 and set errno. */ +# if @REPLACE_FPURGE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define fpurge rpl_fpurge +# endif +_GL_FUNCDECL_RPL (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (fpurge, int, (FILE *gl_stream)); +# else +# if !@HAVE_DECL_FPURGE@ +_GL_FUNCDECL_SYS (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (fpurge, int, (FILE *gl_stream)); +# endif +_GL_CXXALIASWARN (fpurge); +#elif defined GNULIB_POSIXCHECK +# undef fpurge +# if HAVE_RAW_DECL_FPURGE +_GL_WARN_ON_USE (fpurge, "fpurge is not always present - " + "use gnulib module fpurge for portability"); +# endif +#endif + +#if @GNULIB_FPUTC@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fputc +# define fputc rpl_fputc +# endif +_GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (fputc, int, (int c, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fputc, int, (int c, FILE *stream)); +# endif +_GL_CXXALIASWARN (fputc); +#endif + +#if @GNULIB_FPUTS@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fputs +# define fputs rpl_fputs +# endif +_GL_FUNCDECL_RPL (fputs, int, (const char *string, FILE *stream) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (fputs, int, (const char *string, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream)); +# endif +_GL_CXXALIASWARN (fputs); +#endif + +#if @GNULIB_FREOPEN@ +# if @REPLACE_FREOPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef freopen +# define freopen rpl_freopen +# endif +_GL_FUNCDECL_RPL (freopen, FILE *, + (const char *filename, const char *mode, FILE *stream) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (freopen, FILE *, + (const char *filename, const char *mode, FILE *stream)); +# else +_GL_CXXALIAS_SYS (freopen, FILE *, + (const char *filename, const char *mode, FILE *stream)); +# endif +_GL_CXXALIASWARN (freopen); +#elif defined GNULIB_POSIXCHECK +# undef freopen +/* Assume freopen is always declared. */ +_GL_WARN_ON_USE (freopen, "freopen on Win32 platforms is not POSIX compatible - " + "use gnulib module freopen for portability"); +#endif + + +/* Set up the following warnings, based on which modules are in use. + GNU Coding Standards discourage the use of fseek, since it imposes + an arbitrary limitation on some 32-bit hosts. Remember that the + fseek module depends on the fseeko module, so we only have three + cases to consider: + + 1. The developer is not using either module. Issue a warning under + GNULIB_POSIXCHECK for both functions, to remind them that both + functions have bugs on some systems. _GL_NO_LARGE_FILES has no + impact on this warning. + + 2. The developer is using both modules. They may be unaware of the + arbitrary limitations of fseek, so issue a warning under + GNULIB_POSIXCHECK. On the other hand, they may be using both + modules intentionally, so the developer can define + _GL_NO_LARGE_FILES in the compilation units where the use of fseek + is safe, to silence the warning. + + 3. The developer is using the fseeko module, but not fseek. Gnulib + guarantees that fseek will still work around platform bugs in that + case, but we presume that the developer is aware of the pitfalls of + fseek and was trying to avoid it, so issue a warning even when + GNULIB_POSIXCHECK is undefined. Again, _GL_NO_LARGE_FILES can be + defined to silence the warning in particular compilation units. + In C++ compilations with GNULIB_NAMESPACE, in order to avoid that + fseek gets defined as a macro, it is recommended that the developer + uses the fseek module, even if he is not calling the fseek function. + + Most gnulib clients that perform stream operations should fall into + category 3. */ + +#if @GNULIB_FSEEK@ +# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES +# define _GL_FSEEK_WARN /* Category 2, above. */ +# undef fseek +# endif +# if @REPLACE_FSEEK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fseek +# define fseek rpl_fseek +# endif +_GL_FUNCDECL_RPL (fseek, int, (FILE *fp, long offset, int whence) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (fseek, int, (FILE *fp, long offset, int whence)); +# else +_GL_CXXALIAS_SYS (fseek, int, (FILE *fp, long offset, int whence)); +# endif +_GL_CXXALIASWARN (fseek); +#endif + +#if @GNULIB_FSEEKO@ +# if !@GNULIB_FSEEK@ && !defined _GL_NO_LARGE_FILES +# define _GL_FSEEK_WARN /* Category 3, above. */ +# undef fseek +# endif +# if @REPLACE_FSEEKO@ +/* Provide an fseeko function that is aware of a preceding fflush(), and which + detects pipes. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fseeko +# define fseeko rpl_fseeko +# endif +_GL_FUNCDECL_RPL (fseeko, int, (FILE *fp, off_t offset, int whence) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (fseeko, int, (FILE *fp, off_t offset, int whence)); +# else +# if ! @HAVE_FSEEKO@ +_GL_FUNCDECL_SYS (fseeko, int, (FILE *fp, off_t offset, int whence) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (fseeko, int, (FILE *fp, off_t offset, int whence)); +# endif +_GL_CXXALIASWARN (fseeko); +# if (@REPLACE_FSEEKO@ || !@HAVE_FSEEKO@) && !@GNULIB_FSEEK@ + /* Provide an fseek function that is consistent with fseeko. */ + /* In order to avoid that fseek gets defined as a macro here, the + developer can request the 'fseek' module. */ +# undef fseek +# define fseek rpl_fseek +static inline int _GL_ARG_NONNULL ((1)) +rpl_fseek (FILE *fp, long offset, int whence) +{ +# if @REPLACE_FSEEKO@ + return rpl_fseeko (fp, offset, whence); +# else + return fseeko (fp, offset, whence); +# endif +} +# endif +#elif defined GNULIB_POSIXCHECK +# define _GL_FSEEK_WARN /* Category 1, above. */ +# undef fseek +# undef fseeko +# if HAVE_RAW_DECL_FSEEKO +_GL_WARN_ON_USE (fseeko, "fseeko is unportable - " + "use gnulib module fseeko for portability"); +# endif +#endif + +#ifdef _GL_FSEEK_WARN +# undef _GL_FSEEK_WARN +/* Here, either fseek is undefined (but C89 guarantees that it is + declared), or it is defined as rpl_fseek (declared above). */ +_GL_WARN_ON_USE (fseek, "fseek cannot handle files larger than 4 GB " + "on 32-bit platforms - " + "use fseeko function for handling of large files"); +#endif + + +/* ftell, ftello. See the comments on fseek/fseeko. */ + +#if @GNULIB_FTELL@ +# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES +# define _GL_FTELL_WARN /* Category 2, above. */ +# undef ftell +# endif +# if @REPLACE_FTELL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ftell +# define ftell rpl_ftell +# endif +_GL_FUNCDECL_RPL (ftell, long, (FILE *fp) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (ftell, long, (FILE *fp)); +# else +_GL_CXXALIAS_SYS (ftell, long, (FILE *fp)); +# endif +_GL_CXXALIASWARN (ftell); +#endif + +#if @GNULIB_FTELLO@ +# if !@GNULIB_FTELL@ && !defined _GL_NO_LARGE_FILES +# define _GL_FTELL_WARN /* Category 3, above. */ +# undef ftell +# endif +# if @REPLACE_FTELLO@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ftello +# define ftello rpl_ftello +# endif +_GL_FUNCDECL_RPL (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (ftello, off_t, (FILE *fp)); +# else +# if ! @HAVE_FTELLO@ +_GL_FUNCDECL_SYS (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (ftello, off_t, (FILE *fp)); +# endif +_GL_CXXALIASWARN (ftello); +# if (@REPLACE_FTELLO@ || !@HAVE_FTELLO@) && !@GNULIB_FTELL@ + /* Provide an ftell function that is consistent with ftello. */ + /* In order to avoid that ftell gets defined as a macro here, the + developer can request the 'ftell' module. */ +# undef ftell +# define ftell rpl_ftell +static inline long _GL_ARG_NONNULL ((1)) +rpl_ftell (FILE *f) +{ +# if @REPLACE_FTELLO@ + return rpl_ftello (f); +# else + return ftello (f); +# endif +} +# endif +#elif defined GNULIB_POSIXCHECK +# define _GL_FTELL_WARN /* Category 1, above. */ +# undef ftell +# undef ftello +# if HAVE_RAW_DECL_FTELLO +_GL_WARN_ON_USE (ftello, "ftello is unportable - " + "use gnulib module ftello for portability"); +# endif +#endif + +#ifdef _GL_FTELL_WARN +# undef _GL_FTELL_WARN +/* Here, either ftell is undefined (but C89 guarantees that it is + declared), or it is defined as rpl_ftell (declared above). */ +_GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " + "on 32-bit platforms - " + "use ftello function for handling of large files"); +#endif + + +#if @GNULIB_FWRITE@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fwrite +# define fwrite rpl_fwrite +# endif +_GL_FUNCDECL_RPL (fwrite, size_t, + (const void *ptr, size_t s, size_t n, FILE *stream) + _GL_ARG_NONNULL ((1, 4))); +_GL_CXXALIAS_RPL (fwrite, size_t, + (const void *ptr, size_t s, size_t n, FILE *stream)); +# else +_GL_CXXALIAS_SYS (fwrite, size_t, + (const void *ptr, size_t s, size_t n, FILE *stream)); +# endif +_GL_CXXALIASWARN (fwrite); +#endif + +#if @GNULIB_GETDELIM@ +/* Read input, up to (and including) the next occurrence of DELIMITER, from + STREAM, store it in *LINEPTR (and NUL-terminate it). + *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE + bytes of space. It is realloc'd as necessary. + Return the number of bytes read and stored at *LINEPTR (not including the + NUL terminator), or -1 on error or EOF. */ +# if @REPLACE_GETDELIM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getdelim +# define getdelim rpl_getdelim +# endif +_GL_FUNCDECL_RPL (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *stream) + _GL_ARG_NONNULL ((1, 2, 4))); +_GL_CXXALIAS_RPL (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *stream)); +# else +# if !@HAVE_DECL_GETDELIM@ +_GL_FUNCDECL_SYS (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *stream) + _GL_ARG_NONNULL ((1, 2, 4))); +# endif +_GL_CXXALIAS_SYS (getdelim, ssize_t, + (char **lineptr, size_t *linesize, int delimiter, + FILE *stream)); +# endif +_GL_CXXALIASWARN (getdelim); +#elif defined GNULIB_POSIXCHECK +# undef getdelim +# if HAVE_RAW_DECL_GETDELIM +_GL_WARN_ON_USE (getdelim, "getdelim is unportable - " + "use gnulib module getdelim for portability"); +# endif +#endif + +#if @GNULIB_GETLINE@ +/* Read a line, up to (and including) the next newline, from STREAM, store it + in *LINEPTR (and NUL-terminate it). + *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE + bytes of space. It is realloc'd as necessary. + Return the number of bytes read and stored at *LINEPTR (not including the + NUL terminator), or -1 on error or EOF. */ +# if @REPLACE_GETLINE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getline +# define getline rpl_getline +# endif +_GL_FUNCDECL_RPL (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *stream) + _GL_ARG_NONNULL ((1, 2, 3))); +_GL_CXXALIAS_RPL (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *stream)); +# else +# if !@HAVE_DECL_GETLINE@ +_GL_FUNCDECL_SYS (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *stream) + _GL_ARG_NONNULL ((1, 2, 3))); +# endif +_GL_CXXALIAS_SYS (getline, ssize_t, + (char **lineptr, size_t *linesize, FILE *stream)); +# endif +# if @HAVE_DECL_GETLINE@ +_GL_CXXALIASWARN (getline); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getline +# if HAVE_RAW_DECL_GETLINE +_GL_WARN_ON_USE (getline, "getline is unportable - " + "use gnulib module getline for portability"); +# endif +#endif + +#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ +struct obstack; +/* Grow an obstack with formatted output. Return the number of + bytes added to OBS. No trailing nul byte is added, and the + object should be closed with obstack_finish before use. Upon + memory allocation error, call obstack_alloc_failed_handler. Upon + other error, return -1. */ +# if @REPLACE_OBSTACK_PRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define obstack_printf rpl_obstack_printf +# endif +_GL_FUNCDECL_RPL (obstack_printf, int, + (struct obstack *obs, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (obstack_printf, int, + (struct obstack *obs, const char *format, ...)); +# else +# if !@HAVE_DECL_OBSTACK_PRINTF@ +_GL_FUNCDECL_SYS (obstack_printf, int, + (struct obstack *obs, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (obstack_printf, int, + (struct obstack *obs, const char *format, ...)); +# endif +_GL_CXXALIASWARN (obstack_printf); +# if @REPLACE_OBSTACK_PRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define obstack_vprintf rpl_obstack_vprintf +# endif +_GL_FUNCDECL_RPL (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args)); +# else +# if !@HAVE_DECL_OBSTACK_PRINTF@ +_GL_FUNCDECL_SYS (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (obstack_vprintf); +#endif + +#if @GNULIB_PERROR@ +/* Print a message to standard error, describing the value of ERRNO, + (if STRING is not NULL and not empty) prefixed with STRING and ": ", + and terminated with a newline. */ +# if @REPLACE_PERROR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define perror rpl_perror +# endif +_GL_FUNCDECL_RPL (perror, void, (const char *string)); +_GL_CXXALIAS_RPL (perror, void, (const char *string)); +# else +_GL_CXXALIAS_SYS (perror, void, (const char *string)); +# endif +_GL_CXXALIASWARN (perror); +#elif defined GNULIB_POSIXCHECK +# undef perror +/* Assume perror is always declared. */ +_GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - " + "use gnulib module perror for portability"); +#endif + +#if @GNULIB_POPEN@ +# if @REPLACE_POPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef popen +# define popen rpl_popen +# endif +_GL_FUNCDECL_RPL (popen, FILE *, (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); +# else +_GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); +# endif +_GL_CXXALIASWARN (popen); +#elif defined GNULIB_POSIXCHECK +# undef popen +# if HAVE_RAW_DECL_POPEN +_GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " + "use gnulib module popen or pipe for more portability"); +# endif +#endif + +#if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ +# if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ + || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) +# if defined __GNUC__ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +/* Don't break __attribute__((format(printf,M,N))). */ +# define printf __printf__ +# endif +_GL_FUNCDECL_RPL_1 (__printf__, int, + (const char *format, ...) + __asm__ (@ASM_SYMBOL_PREFIX@ + _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) + __attribute__ ((__format__ (__printf__, 1, 2))) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...)); +# else +_GL_FUNCDECL_RPL (printf, int, + (const char *format, ...) + __attribute__ ((__format__ (__printf__, 1, 2))) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (printf, int, (const char *format, ...)); +# endif +# define GNULIB_overrides_printf 1 +# else +_GL_CXXALIAS_SYS (printf, int, (const char *format, ...)); +# endif +_GL_CXXALIASWARN (printf); +#endif +#if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK +# if !GNULIB_overrides_printf +# undef printf +# endif +/* Assume printf is always declared. */ +_GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - " + "use gnulib module printf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_PUTC@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putc +# define putc rpl_fputc +# endif +_GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL_1 (putc, rpl_fputc, int, (int c, FILE *stream)); +# else +_GL_CXXALIAS_SYS (putc, int, (int c, FILE *stream)); +# endif +_GL_CXXALIASWARN (putc); +#endif + +#if @GNULIB_PUTCHAR@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putchar +# define putchar rpl_putchar +# endif +_GL_FUNCDECL_RPL (putchar, int, (int c)); +_GL_CXXALIAS_RPL (putchar, int, (int c)); +# else +_GL_CXXALIAS_SYS (putchar, int, (int c)); +# endif +_GL_CXXALIASWARN (putchar); +#endif + +#if @GNULIB_PUTS@ +# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef puts +# define puts rpl_puts +# endif +_GL_FUNCDECL_RPL (puts, int, (const char *string) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (puts, int, (const char *string)); +# else +_GL_CXXALIAS_SYS (puts, int, (const char *string)); +# endif +_GL_CXXALIASWARN (puts); +#endif + +#if @GNULIB_REMOVE@ +# if @REPLACE_REMOVE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef remove +# define remove rpl_remove +# endif +_GL_FUNCDECL_RPL (remove, int, (const char *name) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (remove, int, (const char *name)); +# else +_GL_CXXALIAS_SYS (remove, int, (const char *name)); +# endif +_GL_CXXALIASWARN (remove); +#elif defined GNULIB_POSIXCHECK +# undef remove +/* Assume remove is always declared. */ +_GL_WARN_ON_USE (remove, "remove cannot handle directories on some platforms - " + "use gnulib module remove for more portability"); +#endif + +#if @GNULIB_RENAME@ +# if @REPLACE_RENAME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef rename +# define rename rpl_rename +# endif +_GL_FUNCDECL_RPL (rename, int, + (const char *old_filename, const char *new_filename) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (rename, int, + (const char *old_filename, const char *new_filename)); +# else +_GL_CXXALIAS_SYS (rename, int, + (const char *old_filename, const char *new_filename)); +# endif +_GL_CXXALIASWARN (rename); +#elif defined GNULIB_POSIXCHECK +# undef rename +/* Assume rename is always declared. */ +_GL_WARN_ON_USE (rename, "rename is buggy on some platforms - " + "use gnulib module rename for more portability"); +#endif + +#if @GNULIB_RENAMEAT@ +# if @REPLACE_RENAMEAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef renameat +# define renameat rpl_renameat +# endif +_GL_FUNCDECL_RPL (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2) + _GL_ARG_NONNULL ((2, 4))); +_GL_CXXALIAS_RPL (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2)); +# else +# if !@HAVE_RENAMEAT@ +_GL_FUNCDECL_SYS (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2) + _GL_ARG_NONNULL ((2, 4))); +# endif +_GL_CXXALIAS_SYS (renameat, int, + (int fd1, char const *file1, int fd2, char const *file2)); +# endif +_GL_CXXALIASWARN (renameat); +#elif defined GNULIB_POSIXCHECK +# undef renameat +# if HAVE_RAW_DECL_RENAMEAT +_GL_WARN_ON_USE (renameat, "renameat is not portable - " + "use gnulib module renameat for portability"); +# endif +#endif + +#if @GNULIB_SNPRINTF@ +# if @REPLACE_SNPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define snprintf rpl_snprintf +# endif +_GL_FUNCDECL_RPL (snprintf, int, + (char *str, size_t size, const char *format, ...) + __attribute__ ((__format__ (__printf__, 3, 4))) + _GL_ARG_NONNULL ((3))); +_GL_CXXALIAS_RPL (snprintf, int, + (char *str, size_t size, const char *format, ...)); +# else +# if !@HAVE_DECL_SNPRINTF@ +_GL_FUNCDECL_SYS (snprintf, int, + (char *str, size_t size, const char *format, ...) + __attribute__ ((__format__ (__printf__, 3, 4))) + _GL_ARG_NONNULL ((3))); +# endif +_GL_CXXALIAS_SYS (snprintf, int, + (char *str, size_t size, const char *format, ...)); +# endif +_GL_CXXALIASWARN (snprintf); +#elif defined GNULIB_POSIXCHECK +# undef snprintf +# if HAVE_RAW_DECL_SNPRINTF +_GL_WARN_ON_USE (snprintf, "snprintf is unportable - " + "use gnulib module snprintf for portability"); +# endif +#endif + +/* Some people would argue that sprintf should be handled like gets + (for example, OpenBSD issues a link warning for both functions), + since both can cause security holes due to buffer overruns. + However, we believe that sprintf can be used safely, and is more + efficient than snprintf in those safe cases; and as proof of our + belief, we use sprintf in several gnulib modules. So this header + intentionally avoids adding a warning to sprintf except when + GNULIB_POSIXCHECK is defined. */ + +#if @GNULIB_SPRINTF_POSIX@ +# if @REPLACE_SPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define sprintf rpl_sprintf +# endif +_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...)); +# else +_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...)); +# endif +_GL_CXXALIASWARN (sprintf); +#elif defined GNULIB_POSIXCHECK +# undef sprintf +/* Assume sprintf is always declared. */ +_GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - " + "use gnulib module sprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_TMPFILE@ +# if @REPLACE_TMPFILE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define tmpfile rpl_tmpfile +# endif +_GL_FUNCDECL_RPL (tmpfile, FILE *, (void)); +_GL_CXXALIAS_RPL (tmpfile, FILE *, (void)); +# else +_GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); +# endif +_GL_CXXALIASWARN (tmpfile); +#elif defined GNULIB_POSIXCHECK +# undef tmpfile +# if HAVE_RAW_DECL_TMPFILE +_GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " + "use gnulib module tmpfile for portability"); +# endif +#endif + +#if @GNULIB_VASPRINTF@ +/* Write formatted output to a string dynamically allocated with malloc(). + If the memory allocation succeeds, store the address of the string in + *RESULT and return the number of resulting bytes, excluding the trailing + NUL. Upon memory allocation error, or some other error, return -1. */ +# if @REPLACE_VASPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define asprintf rpl_asprintf +# endif +_GL_FUNCDECL_RPL (asprintf, int, + (char **result, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (asprintf, int, + (char **result, const char *format, ...)); +# else +# if !@HAVE_VASPRINTF@ +_GL_FUNCDECL_SYS (asprintf, int, + (char **result, const char *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (asprintf, int, + (char **result, const char *format, ...)); +# endif +_GL_CXXALIASWARN (asprintf); +# if @REPLACE_VASPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vasprintf rpl_vasprintf +# endif +_GL_FUNCDECL_RPL (vasprintf, int, + (char **result, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (vasprintf, int, + (char **result, const char *format, va_list args)); +# else +# if !@HAVE_VASPRINTF@ +_GL_FUNCDECL_SYS (vasprintf, int, + (char **result, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (vasprintf, int, + (char **result, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vasprintf); +#endif + +#if @GNULIB_VDPRINTF@ +# if @REPLACE_VDPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vdprintf rpl_vdprintf +# endif +_GL_FUNCDECL_RPL (vdprintf, int, (int fd, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (vdprintf, int, (int fd, const char *format, va_list args)); +# else +# if !@HAVE_VDPRINTF@ +_GL_FUNCDECL_SYS (vdprintf, int, (int fd, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((2))); +# endif +/* Need to cast, because on Solaris, the third parameter will likely be + __va_list args. */ +_GL_CXXALIAS_SYS_CAST (vdprintf, int, + (int fd, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vdprintf); +#elif defined GNULIB_POSIXCHECK +# undef vdprintf +# if HAVE_RAW_DECL_VDPRINTF +_GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " + "use gnulib module vdprintf for portability"); +# endif +#endif + +#if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@ +# if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \ + || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vfprintf rpl_vfprintf +# endif +# define GNULIB_overrides_vfprintf 1 +_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)); +# else +/* Need to cast, because on Solaris, the third parameter is + __va_list args + and GCC's fixincludes did not change this to __gnuc_va_list. */ +_GL_CXXALIAS_SYS_CAST (vfprintf, int, + (FILE *fp, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vfprintf); +#endif +#if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK +# if !GNULIB_overrides_vfprintf +# undef vfprintf +# endif +/* Assume vfprintf is always declared. */ +_GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " + "use gnulib module vfprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ +# if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ + || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vprintf rpl_vprintf +# endif +# define GNULIB_overrides_vprintf 1 +_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 1, 0))) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (vprintf, int, (const char *format, va_list args)); +# else +/* Need to cast, because on Solaris, the second parameter is + __va_list args + and GCC's fixincludes did not change this to __gnuc_va_list. */ +_GL_CXXALIAS_SYS_CAST (vprintf, int, (const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vprintf); +#endif +#if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK +# if !GNULIB_overrides_vprintf +# undef vprintf +# endif +/* Assume vprintf is always declared. */ +_GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " + "use gnulib module vprintf-posix for portable " + "POSIX compliance"); +#endif + +#if @GNULIB_VSNPRINTF@ +# if @REPLACE_VSNPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vsnprintf rpl_vsnprintf +# endif +_GL_FUNCDECL_RPL (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))) + _GL_ARG_NONNULL ((3))); +_GL_CXXALIAS_RPL (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args)); +# else +# if !@HAVE_DECL_VSNPRINTF@ +_GL_FUNCDECL_SYS (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))) + _GL_ARG_NONNULL ((3))); +# endif +_GL_CXXALIAS_SYS (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vsnprintf); +#elif defined GNULIB_POSIXCHECK +# undef vsnprintf +# if HAVE_RAW_DECL_VSNPRINTF +_GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " + "use gnulib module vsnprintf for portability"); +# endif +#endif + +#if @GNULIB_VSPRINTF_POSIX@ +# if @REPLACE_VSPRINTF@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define vsprintf rpl_vsprintf +# endif +_GL_FUNCDECL_RPL (vsprintf, int, + (char *str, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (vsprintf, int, + (char *str, const char *format, va_list args)); +# else +/* Need to cast, because on Solaris, the third parameter is + __va_list args + and GCC's fixincludes did not change this to __gnuc_va_list. */ +_GL_CXXALIAS_SYS_CAST (vsprintf, int, + (char *str, const char *format, va_list args)); +# endif +_GL_CXXALIASWARN (vsprintf); +#elif defined GNULIB_POSIXCHECK +# undef vsprintf +/* Assume vsprintf is always declared. */ +_GL_WARN_ON_USE (vsprintf, "vsprintf is not always POSIX compliant - " + "use gnulib module vsprintf-posix for portable " + "POSIX compliance"); +#endif + + +#endif /* _GL_STDIO_H */ +#endif /* _GL_STDIO_H */ +#endif diff --git a/grub-core/gnulib/stdlib.in.h b/grub-core/gnulib/stdlib.in.h new file mode 100644 index 000000000..f4309ed73 --- /dev/null +++ b/grub-core/gnulib/stdlib.in.h @@ -0,0 +1,715 @@ +/* A GNU-like . + + Copyright (C) 1995, 2001-2004, 2006-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if defined __need_malloc_and_calloc +/* Special invocation convention inside glibc header files. */ + +#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _GL_STDLIB_H + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +#ifndef _GL_STDLIB_H +#define _GL_STDLIB_H + +/* NetBSD 5.0 mis-defines NULL. */ +#include + +/* MirBSD 10 defines WEXITSTATUS in , not in . */ +#ifndef WEXITSTATUS +# include +#endif + +/* Solaris declares getloadavg() in . */ +#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@ +# include +#endif + +/* OSF/1 5.1 declares 'struct random_data' in , which is included + from if _REENTRANT is defined. Include it always. */ +#if @HAVE_RANDOM_H@ +# include +#endif + +#if !@HAVE_STRUCT_RANDOM_DATA@ || (@GNULIB_RANDOM_R@ && !@HAVE_RANDOM_R@) \ + || defined GNULIB_POSIXCHECK +# include +#endif + +#if !@HAVE_STRUCT_RANDOM_DATA@ +struct random_data +{ + int32_t *fptr; /* Front pointer. */ + int32_t *rptr; /* Rear pointer. */ + int32_t *state; /* Array of state values. */ + int rand_type; /* Type of random number generator. */ + int rand_deg; /* Degree of random number generator. */ + int rand_sep; /* Distance between front and rear. */ + int32_t *end_ptr; /* Pointer behind state table. */ +}; +#endif + +#if (@GNULIB_MKSTEMP@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +/* On MacOS X 10.3, only declares mkstemp. */ +/* On Cygwin 1.7.1, only declares getsubopt. */ +/* But avoid namespace pollution on glibc systems and native Windows. */ +# include +#endif + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Some systems do not define EXIT_*, despite otherwise supporting C89. */ +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif +/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere + with proper operation of xargs. */ +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +#elif EXIT_FAILURE != 1 +# undef EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif + + +#if @GNULIB__EXIT@ +/* Terminate the current process with the given return code, without running + the 'atexit' handlers. */ +# if !@HAVE__EXIT@ +_GL_FUNCDECL_SYS (_Exit, void, (int status) __attribute__ ((__noreturn__))); +# endif +_GL_CXXALIAS_SYS (_Exit, void, (int status)); +_GL_CXXALIASWARN (_Exit); +#elif defined GNULIB_POSIXCHECK +# undef _Exit +# if HAVE_RAW_DECL__EXIT +_GL_WARN_ON_USE (_Exit, "_Exit is unportable - " + "use gnulib module _Exit for portability"); +# endif +#endif + + +#if @GNULIB_ATOLL@ +/* Parse a signed decimal integer. + Returns the value of the integer. Errors are not detected. */ +# if !@HAVE_ATOLL@ +_GL_FUNCDECL_SYS (atoll, long long, (const char *string) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (atoll, long long, (const char *string)); +_GL_CXXALIASWARN (atoll); +#elif defined GNULIB_POSIXCHECK +# undef atoll +# if HAVE_RAW_DECL_ATOLL +_GL_WARN_ON_USE (atoll, "atoll is unportable - " + "use gnulib module atoll for portability"); +# endif +#endif + +#if @GNULIB_CALLOC_POSIX@ +# if @REPLACE_CALLOC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef calloc +# define calloc rpl_calloc +# endif +_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size)); +_GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); +# else +_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); +# endif +_GL_CXXALIASWARN (calloc); +#elif defined GNULIB_POSIXCHECK +# undef calloc +/* Assume calloc is always declared. */ +_GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - " + "use gnulib module calloc-posix for portability"); +#endif + +#if @GNULIB_CANONICALIZE_FILE_NAME@ +# if @REPLACE_CANONICALIZE_FILE_NAME@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define canonicalize_file_name rpl_canonicalize_file_name +# endif +_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); +# else +# if !@HAVE_CANONICALIZE_FILE_NAME@ +_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); +# endif +_GL_CXXALIASWARN (canonicalize_file_name); +#elif defined GNULIB_POSIXCHECK +# undef canonicalize_file_name +# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME +_GL_WARN_ON_USE (canonicalize_file_name, "canonicalize_file_name is unportable - " + "use gnulib module canonicalize-lgpl for portability"); +# endif +#endif + +#if @GNULIB_GETLOADAVG@ +/* Store max(NELEM,3) load average numbers in LOADAVG[]. + The three numbers are the load average of the last 1 minute, the last 5 + minutes, and the last 15 minutes, respectively. + LOADAVG is an array of NELEM numbers. */ +# if !@HAVE_DECL_GETLOADAVG@ +_GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem)); +_GL_CXXALIASWARN (getloadavg); +#elif defined GNULIB_POSIXCHECK +# undef getloadavg +# if HAVE_RAW_DECL_GETLOADAVG +_GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - " + "use gnulib module getloadavg for portability"); +# endif +#endif + +#if @GNULIB_GETSUBOPT@ +/* Assuming *OPTIONP is a comma separated list of elements of the form + "token" or "token=value", getsubopt parses the first of these elements. + If the first element refers to a "token" that is member of the given + NULL-terminated array of tokens: + - It replaces the comma with a NUL byte, updates *OPTIONP to point past + the first option and the comma, sets *VALUEP to the value of the + element (or NULL if it doesn't contain an "=" sign), + - It returns the index of the "token" in the given array of tokens. + Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined. + For more details see the POSIX:2001 specification. + http://www.opengroup.org/susv3xsh/getsubopt.html */ +# if !@HAVE_GETSUBOPT@ +_GL_FUNCDECL_SYS (getsubopt, int, + (char **optionp, char *const *tokens, char **valuep) + _GL_ARG_NONNULL ((1, 2, 3))); +# endif +_GL_CXXALIAS_SYS (getsubopt, int, + (char **optionp, char *const *tokens, char **valuep)); +_GL_CXXALIASWARN (getsubopt); +#elif defined GNULIB_POSIXCHECK +# undef getsubopt +# if HAVE_RAW_DECL_GETSUBOPT +_GL_WARN_ON_USE (getsubopt, "getsubopt is unportable - " + "use gnulib module getsubopt for portability"); +# endif +#endif + +#if @GNULIB_GRANTPT@ +/* Change the ownership and access permission of the slave side of the + pseudo-terminal whose master side is specified by FD. */ +# if !@HAVE_GRANTPT@ +_GL_FUNCDECL_SYS (grantpt, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (grantpt, int, (int fd)); +_GL_CXXALIASWARN (grantpt); +#elif defined GNULIB_POSIXCHECK +# undef grantpt +# if HAVE_RAW_DECL_GRANTPT +_GL_WARN_ON_USE (ptsname, "grantpt is not portable - " + "use gnulib module grantpt for portability"); +# endif +#endif + +#if @GNULIB_MALLOC_POSIX@ +# if @REPLACE_MALLOC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef malloc +# define malloc rpl_malloc +# endif +_GL_FUNCDECL_RPL (malloc, void *, (size_t size)); +_GL_CXXALIAS_RPL (malloc, void *, (size_t size)); +# else +_GL_CXXALIAS_SYS (malloc, void *, (size_t size)); +# endif +_GL_CXXALIASWARN (malloc); +#elif defined GNULIB_POSIXCHECK +# undef malloc +/* Assume malloc is always declared. */ +_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " + "use gnulib module malloc-posix for portability"); +#endif + +#if @GNULIB_MKDTEMP@ +/* Create a unique temporary directory from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the directory name unique. + Returns TEMPLATE, or a null pointer if it cannot get a unique name. + The directory is created mode 700. */ +# if !@HAVE_MKDTEMP@ +_GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/)); +_GL_CXXALIASWARN (mkdtemp); +#elif defined GNULIB_POSIXCHECK +# undef mkdtemp +# if HAVE_RAW_DECL_MKDTEMP +_GL_WARN_ON_USE (mkdtemp, "mkdtemp is unportable - " + "use gnulib module mkdtemp for portability"); +# endif +#endif + +#if @GNULIB_MKOSTEMP@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + The file is then created, with the specified flags, ensuring it didn't exist + before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if !@HAVE_MKOSTEMP@ +_GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)); +_GL_CXXALIASWARN (mkostemp); +#elif defined GNULIB_POSIXCHECK +# undef mkostemp +# if HAVE_RAW_DECL_MKOSTEMP +_GL_WARN_ON_USE (mkostemp, "mkostemp is unportable - " + "use gnulib module mkostemp for portability"); +# endif +#endif + +#if @GNULIB_MKOSTEMPS@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE before a suffix of length + SUFFIXLEN must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + The file is then created, with the specified flags, ensuring it didn't exist + before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if !@HAVE_MKOSTEMPS@ +_GL_FUNCDECL_SYS (mkostemps, int, + (char * /*template*/, int /*suffixlen*/, int /*flags*/) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkostemps, int, + (char * /*template*/, int /*suffixlen*/, int /*flags*/)); +_GL_CXXALIASWARN (mkostemps); +#elif defined GNULIB_POSIXCHECK +# undef mkostemps +# if HAVE_RAW_DECL_MKOSTEMPS +_GL_WARN_ON_USE (mkostemps, "mkostemps is unportable - " + "use gnulib module mkostemps for portability"); +# endif +#endif + +#if @GNULIB_MKSTEMP@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The file is then created, ensuring it didn't exist before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if @REPLACE_MKSTEMP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mkstemp rpl_mkstemp +# endif +_GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/)); +# else +# if ! @HAVE_MKSTEMP@ +_GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/)); +# endif +_GL_CXXALIASWARN (mkstemp); +#elif defined GNULIB_POSIXCHECK +# undef mkstemp +# if HAVE_RAW_DECL_MKSTEMP +_GL_WARN_ON_USE (mkstemp, "mkstemp is unportable - " + "use gnulib module mkstemp for portability"); +# endif +#endif + +#if @GNULIB_MKSTEMPS@ +/* Create a unique temporary file from TEMPLATE. + The last six characters of TEMPLATE prior to a suffix of length + SUFFIXLEN must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + The file is then created, ensuring it didn't exist before. + The file is created read-write (mask at least 0600 & ~umask), but it may be + world-readable and world-writable (mask 0666 & ~umask), depending on the + implementation. + Returns the open file descriptor if successful, otherwise -1 and errno + set. */ +# if !@HAVE_MKSTEMPS@ +_GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)); +_GL_CXXALIASWARN (mkstemps); +#elif defined GNULIB_POSIXCHECK +# undef mkstemps +# if HAVE_RAW_DECL_MKSTEMPS +_GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - " + "use gnulib module mkstemps for portability"); +# endif +#endif + +#if @GNULIB_PTSNAME@ +/* Return the pathname of the pseudo-terminal slave associated with + the master FD is open on, or NULL on errors. */ +# if !@HAVE_PTSNAME@ +_GL_FUNCDECL_SYS (ptsname, char *, (int fd)); +# endif +_GL_CXXALIAS_SYS (ptsname, char *, (int fd)); +_GL_CXXALIASWARN (ptsname); +#elif defined GNULIB_POSIXCHECK +# undef ptsname +# if HAVE_RAW_DECL_PTSNAME +_GL_WARN_ON_USE (ptsname, "ptsname is not portable - " + "use gnulib module ptsname for portability"); +# endif +#endif + +#if @GNULIB_PUTENV@ +# if @REPLACE_PUTENV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef putenv +# define putenv rpl_putenv +# endif +_GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (putenv, int, (char *string)); +# else +_GL_CXXALIAS_SYS (putenv, int, (char *string)); +# endif +_GL_CXXALIASWARN (putenv); +#endif + + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ +# ifndef RAND_MAX +# define RAND_MAX 2147483647 +# endif +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result)); +_GL_CXXALIASWARN (random_r); +#elif defined GNULIB_POSIXCHECK +# undef random_r +# if HAVE_RAW_DECL_RANDOM_R +_GL_WARN_ON_USE (random_r, "random_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (srandom_r, int, + (unsigned int seed, struct random_data *rand_state) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (srandom_r, int, + (unsigned int seed, struct random_data *rand_state)); +_GL_CXXALIASWARN (srandom_r); +#elif defined GNULIB_POSIXCHECK +# undef srandom_r +# if HAVE_RAW_DECL_SRANDOM_R +_GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state) + _GL_ARG_NONNULL ((2, 4))); +# endif +_GL_CXXALIAS_SYS (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state)); +_GL_CXXALIASWARN (initstate_r); +#elif defined GNULIB_POSIXCHECK +# undef initstate_r +# if HAVE_RAW_DECL_INITSTATE_R +_GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + +#if @GNULIB_RANDOM_R@ +# if !@HAVE_RANDOM_R@ +_GL_FUNCDECL_SYS (setstate_r, int, + (char *arg_state, struct random_data *rand_state) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (setstate_r, int, + (char *arg_state, struct random_data *rand_state)); +_GL_CXXALIASWARN (setstate_r); +#elif defined GNULIB_POSIXCHECK +# undef setstate_r +# if HAVE_RAW_DECL_SETSTATE_R +_GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " + "use gnulib module random_r for portability"); +# endif +#endif + + +#if @GNULIB_REALLOC_POSIX@ +# if @REPLACE_REALLOC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef realloc +# define realloc rpl_realloc +# endif +_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size)); +_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); +# else +_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); +# endif +_GL_CXXALIASWARN (realloc); +#elif defined GNULIB_POSIXCHECK +# undef realloc +/* Assume realloc is always declared. */ +_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " + "use gnulib module realloc-posix for portability"); +#endif + +#if @GNULIB_REALPATH@ +# if @REPLACE_REALPATH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define realpath rpl_realpath +# endif +_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved)); +# else +# if !@HAVE_REALPATH@ +_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved)); +# endif +_GL_CXXALIASWARN (realpath); +#elif defined GNULIB_POSIXCHECK +# undef realpath +# if HAVE_RAW_DECL_REALPATH +_GL_WARN_ON_USE (realpath, "realpath is unportable - use gnulib module " + "canonicalize or canonicalize-lgpl for portability"); +# endif +#endif + +#if @GNULIB_RPMATCH@ +/* Test a user response to a question. + Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */ +# if !@HAVE_RPMATCH@ +_GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (rpmatch, int, (const char *response)); +_GL_CXXALIASWARN (rpmatch); +#elif defined GNULIB_POSIXCHECK +# undef rpmatch +# if HAVE_RAW_DECL_RPMATCH +_GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - " + "use gnulib module rpmatch for portability"); +# endif +#endif + +#if @GNULIB_SETENV@ +/* Set NAME to VALUE in the environment. + If REPLACE is nonzero, overwrite an existing value. */ +# if @REPLACE_SETENV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef setenv +# define setenv rpl_setenv +# endif +_GL_FUNCDECL_RPL (setenv, int, + (const char *name, const char *value, int replace) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (setenv, int, + (const char *name, const char *value, int replace)); +# else +# if !@HAVE_SETENV@ +_GL_FUNCDECL_SYS (setenv, int, + (const char *name, const char *value, int replace) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (setenv, int, + (const char *name, const char *value, int replace)); +# endif +_GL_CXXALIASWARN (setenv); +#elif defined GNULIB_POSIXCHECK +# undef setenv +# if HAVE_RAW_DECL_SETENV +_GL_WARN_ON_USE (setenv, "setenv is unportable - " + "use gnulib module setenv for portability"); +# endif +#endif + +#if @GNULIB_STRTOD@ + /* Parse a double from STRING, updating ENDP if appropriate. */ +# if @REPLACE_STRTOD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strtod rpl_strtod +# endif +_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp)); +# else +# if !@HAVE_STRTOD@ +_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp)); +# endif +_GL_CXXALIASWARN (strtod); +#elif defined GNULIB_POSIXCHECK +# undef strtod +# if HAVE_RAW_DECL_STRTOD +_GL_WARN_ON_USE (strtod, "strtod is unportable - " + "use gnulib module strtod for portability"); +# endif +#endif + +#if @GNULIB_STRTOLL@ +/* Parse a signed integer whose textual representation starts at STRING. + The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, + it may be decimal or octal (with prefix "0") or hexadecimal (with prefix + "0x"). + If ENDPTR is not NULL, the address of the first byte after the integer is + stored in *ENDPTR. + Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set + to ERANGE. */ +# if !@HAVE_STRTOLL@ +_GL_FUNCDECL_SYS (strtoll, long long, + (const char *string, char **endptr, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoll, long long, + (const char *string, char **endptr, int base)); +_GL_CXXALIASWARN (strtoll); +#elif defined GNULIB_POSIXCHECK +# undef strtoll +# if HAVE_RAW_DECL_STRTOLL +_GL_WARN_ON_USE (strtoll, "strtoll is unportable - " + "use gnulib module strtoll for portability"); +# endif +#endif + +#if @GNULIB_STRTOULL@ +/* Parse an unsigned integer whose textual representation starts at STRING. + The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, + it may be decimal or octal (with prefix "0") or hexadecimal (with prefix + "0x"). + If ENDPTR is not NULL, the address of the first byte after the integer is + stored in *ENDPTR. + Upon overflow, the return value is ULLONG_MAX, and errno is set to + ERANGE. */ +# if !@HAVE_STRTOULL@ +_GL_FUNCDECL_SYS (strtoull, unsigned long long, + (const char *string, char **endptr, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strtoull, unsigned long long, + (const char *string, char **endptr, int base)); +_GL_CXXALIASWARN (strtoull); +#elif defined GNULIB_POSIXCHECK +# undef strtoull +# if HAVE_RAW_DECL_STRTOULL +_GL_WARN_ON_USE (strtoull, "strtoull is unportable - " + "use gnulib module strtoull for portability"); +# endif +#endif + +#if @GNULIB_UNLOCKPT@ +/* Unlock the slave side of the pseudo-terminal whose master side is specified + by FD, so that it can be opened. */ +# if !@HAVE_UNLOCKPT@ +_GL_FUNCDECL_SYS (unlockpt, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (unlockpt, int, (int fd)); +_GL_CXXALIASWARN (unlockpt); +#elif defined GNULIB_POSIXCHECK +# undef unlockpt +# if HAVE_RAW_DECL_UNLOCKPT +_GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - " + "use gnulib module unlockpt for portability"); +# endif +#endif + +#if @GNULIB_UNSETENV@ +/* Remove the variable NAME from the environment. */ +# if @REPLACE_UNSETENV@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unsetenv +# define unsetenv rpl_unsetenv +# endif +_GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (unsetenv, int, (const char *name)); +# else +# if !@HAVE_UNSETENV@ +_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (unsetenv, int, (const char *name)); +# endif +_GL_CXXALIASWARN (unsetenv); +#elif defined GNULIB_POSIXCHECK +# undef unsetenv +# if HAVE_RAW_DECL_UNSETENV +_GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - " + "use gnulib module unsetenv for portability"); +# endif +#endif + + +#endif /* _GL_STDLIB_H */ +#endif /* _GL_STDLIB_H */ +#endif diff --git a/grub-core/gnulib/strcasecmp.c b/grub-core/gnulib/strcasecmp.c new file mode 100644 index 000000000..612c80fdc --- /dev/null +++ b/grub-core/gnulib/strcasecmp.c @@ -0,0 +1,63 @@ +/* Case-insensitive string comparison function. + Copyright (C) 1998-1999, 2005-2007, 2009-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +#include +#include + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. + Note: This function does not work with multibyte strings! */ + +int +strcasecmp (const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = TOLOWER (*p1); + c2 = TOLOWER (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* On machines where 'char' and 'int' are types of the same size, the + difference of two 'unsigned char' values - including the sign bit - + doesn't fit in an 'int'. */ + return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/grub-core/gnulib/strchrnul.c b/grub-core/gnulib/strchrnul.c new file mode 100644 index 000000000..f834d3434 --- /dev/null +++ b/grub-core/gnulib/strchrnul.c @@ -0,0 +1,142 @@ +/* Searching in a string. + Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +/* Find the first occurrence of C in S or the final NUL byte. */ +char * +strchrnul (const char *s, int c_in) +{ + /* On 32-bit hardware, choosing longword to be a 32-bit unsigned + long instead of a 64-bit uintmax_t tends to give better + performance. On 64-bit hardware, unsigned long is generally 64 + bits already. Change this typedef to experiment with + performance. */ + typedef unsigned long int longword; + + const unsigned char *char_ptr; + const longword *longword_ptr; + longword repeated_one; + longword repeated_c; + unsigned char c; + + c = (unsigned char) c_in; + if (!c) + return rawmemchr (s, 0); + + /* Handle the first few bytes by reading one byte at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = (const unsigned char *) s; + (size_t) char_ptr % sizeof (longword) != 0; + ++char_ptr) + if (!*char_ptr || *char_ptr == c) + return (char *) char_ptr; + + longword_ptr = (const longword *) char_ptr; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to any size longwords. */ + + /* Compute auxiliary longword values: + repeated_one is a value which has a 1 in every byte. + repeated_c has c in every byte. */ + repeated_one = 0x01010101; + repeated_c = c | (c << 8); + repeated_c |= repeated_c << 16; + if (0xffffffffU < (longword) -1) + { + repeated_one |= repeated_one << 31 << 1; + repeated_c |= repeated_c << 31 << 1; + if (8 < sizeof (longword)) + { + size_t i; + + for (i = 64; i < sizeof (longword) * 8; i *= 2) + { + repeated_one |= repeated_one << i; + repeated_c |= repeated_c << i; + } + } + } + + /* Instead of the traditional loop which tests each byte, we will + test a longword at a time. The tricky part is testing if *any of + the four* bytes in the longword in question are equal to NUL or + c. We first use an xor with repeated_c. This reduces the task + to testing whether *any of the four* bytes in longword1 or + longword2 is zero. + + Let's consider longword1. We compute tmp = + ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). + That is, we perform the following operations: + 1. Subtract repeated_one. + 2. & ~longword1. + 3. & a mask consisting of 0x80 in every byte. + Consider what happens in each byte: + - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, + and step 3 transforms it into 0x80. A carry can also be propagated + to more significant bytes. + - If a byte of longword1 is nonzero, let its lowest 1 bit be at + position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, + the byte ends in a single bit of value 0 and k bits of value 1. + After step 2, the result is just k bits of value 1: 2^k - 1. After + step 3, the result is 0. And no carry is produced. + So, if longword1 has only non-zero bytes, tmp is zero. + Whereas if longword1 has a zero byte, call j the position of the least + significant zero byte. Then the result has a zero at positions 0, ..., + j-1 and a 0x80 at position j. We cannot predict the result at the more + significant bytes (positions j+1..3), but it does not matter since we + already have a non-zero bit at position 8*j+7. + + The test whether any byte in longword1 or longword2 is zero is equivalent + to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine + this into a single test, whether (tmp1 | tmp2) is nonzero. + + This test can read more than one byte beyond the end of a string, + depending on where the terminating NUL is encountered. However, + this is considered safe since the initialization phase ensured + that the read will be aligned, therefore, the read will not cross + page boundaries and will not cause a fault. */ + + while (1) + { + longword longword1 = *longword_ptr ^ repeated_c; + longword longword2 = *longword_ptr; + + if (((((longword1 - repeated_one) & ~longword1) + | ((longword2 - repeated_one) & ~longword2)) + & (repeated_one << 7)) != 0) + break; + longword_ptr++; + } + + char_ptr = (const unsigned char *) longword_ptr; + + /* At this point, we know that one of the sizeof (longword) bytes + starting at char_ptr is == 0 or == c. On little-endian machines, + we could determine the first such byte without any further memory + accesses, just by looking at the tmp result from the last loop + iteration. But this does not work on big-endian machines. + Choose code that works in both cases. */ + + char_ptr = (unsigned char *) longword_ptr; + while (*char_ptr && (*char_ptr != c)) + char_ptr++; + return (char *) char_ptr; +} diff --git a/grub-core/gnulib/strchrnul.valgrind b/grub-core/gnulib/strchrnul.valgrind new file mode 100644 index 000000000..b14fa1304 --- /dev/null +++ b/grub-core/gnulib/strchrnul.valgrind @@ -0,0 +1,12 @@ +# Suppress a valgrind message about use of uninitialized memory in strchrnul(). +# This use is OK because it provides only a speedup. +{ + strchrnul-value4 + Memcheck:Value4 + fun:strchrnul +} +{ + strchrnul-value8 + Memcheck:Value8 + fun:strchrnul +} diff --git a/grub-core/gnulib/streq.h b/grub-core/gnulib/streq.h new file mode 100644 index 000000000..aa65bb8e1 --- /dev/null +++ b/grub-core/gnulib/streq.h @@ -0,0 +1,176 @@ +/* Optimized string comparison. + Copyright (C) 2001-2002, 2007, 2009-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible . */ + +#ifndef _GL_STREQ_H +#define _GL_STREQ_H + +#include + +/* STREQ allows to optimize string comparison with a small literal string. + STREQ (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + is semantically equivalent to + strcmp (s, "EUC-KR") == 0 + just faster. */ + +/* Help GCC to generate good code for string comparisons with + immediate strings. */ +#if defined (__GNUC__) && defined (__OPTIMIZE__) + +static inline int +streq9 (const char *s1, const char *s2) +{ + return strcmp (s1 + 9, s2 + 9) == 0; +} + +static inline int +streq8 (const char *s1, const char *s2, char s28) +{ + if (s1[8] == s28) + { + if (s28 == 0) + return 1; + else + return streq9 (s1, s2); + } + else + return 0; +} + +static inline int +streq7 (const char *s1, const char *s2, char s27, char s28) +{ + if (s1[7] == s27) + { + if (s27 == 0) + return 1; + else + return streq8 (s1, s2, s28); + } + else + return 0; +} + +static inline int +streq6 (const char *s1, const char *s2, char s26, char s27, char s28) +{ + if (s1[6] == s26) + { + if (s26 == 0) + return 1; + else + return streq7 (s1, s2, s27, s28); + } + else + return 0; +} + +static inline int +streq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) +{ + if (s1[5] == s25) + { + if (s25 == 0) + return 1; + else + return streq6 (s1, s2, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[4] == s24) + { + if (s24 == 0) + return 1; + else + return streq5 (s1, s2, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[3] == s23) + { + if (s23 == 0) + return 1; + else + return streq4 (s1, s2, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[2] == s22) + { + if (s22 == 0) + return 1; + else + return streq3 (s1, s2, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[1] == s21) + { + if (s21 == 0) + return 1; + else + return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +static inline int +streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +{ + if (s1[0] == s20) + { + if (s20 == 0) + return 1; + else + return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); + } + else + return 0; +} + +#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) + +#else + +#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + (strcmp (s1, s2) == 0) + +#endif + +#endif /* _GL_STREQ_H */ diff --git a/grub-core/gnulib/strerror.c b/grub-core/gnulib/strerror.c new file mode 100644 index 000000000..46153abf5 --- /dev/null +++ b/grub-core/gnulib/strerror.c @@ -0,0 +1,350 @@ +/* strerror.c --- POSIX compatible system error routine + + Copyright (C) 2007-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +#include + +#if REPLACE_STRERROR + +# include +# include + +# if GNULIB_defined_ESOCK /* native Windows platforms */ +# if HAVE_WINSOCK2_H +# include +# endif +# endif + +# include "intprops.h" + +/* Use the system functions, not the gnulib overrides in this file. */ +# undef sprintf + +# undef strerror +# if ! HAVE_DECL_STRERROR +# define strerror(n) NULL +# endif + +char * +rpl_strerror (int n) +{ + char const *msg = NULL; + /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ + switch (n) + { +# if GNULIB_defined_ETXTBSY + case ETXTBSY: + msg = "Text file busy"; + break; +# endif + +# if GNULIB_defined_ESOCK /* native Windows platforms */ + /* EWOULDBLOCK is the same as EAGAIN. */ + case EINPROGRESS: + msg = "Operation now in progress"; + break; + case EALREADY: + msg = "Operation already in progress"; + break; + case ENOTSOCK: + msg = "Socket operation on non-socket"; + break; + case EDESTADDRREQ: + msg = "Destination address required"; + break; + case EMSGSIZE: + msg = "Message too long"; + break; + case EPROTOTYPE: + msg = "Protocol wrong type for socket"; + break; + case ENOPROTOOPT: + msg = "Protocol not available"; + break; + case EPROTONOSUPPORT: + msg = "Protocol not supported"; + break; + case ESOCKTNOSUPPORT: + msg = "Socket type not supported"; + break; + case EOPNOTSUPP: + msg = "Operation not supported"; + break; + case EPFNOSUPPORT: + msg = "Protocol family not supported"; + break; + case EAFNOSUPPORT: + msg = "Address family not supported by protocol"; + break; + case EADDRINUSE: + msg = "Address already in use"; + break; + case EADDRNOTAVAIL: + msg = "Cannot assign requested address"; + break; + case ENETDOWN: + msg = "Network is down"; + break; + case ENETUNREACH: + msg = "Network is unreachable"; + break; + case ENETRESET: + msg = "Network dropped connection on reset"; + break; + case ECONNABORTED: + msg = "Software caused connection abort"; + break; + case ECONNRESET: + msg = "Connection reset by peer"; + break; + case ENOBUFS: + msg = "No buffer space available"; + break; + case EISCONN: + msg = "Transport endpoint is already connected"; + break; + case ENOTCONN: + msg = "Transport endpoint is not connected"; + break; + case ESHUTDOWN: + msg = "Cannot send after transport endpoint shutdown"; + break; + case ETOOMANYREFS: + msg = "Too many references: cannot splice"; + break; + case ETIMEDOUT: + msg = "Connection timed out"; + break; + case ECONNREFUSED: + msg = "Connection refused"; + break; + case ELOOP: + msg = "Too many levels of symbolic links"; + break; + case EHOSTDOWN: + msg = "Host is down"; + break; + case EHOSTUNREACH: + msg = "No route to host"; + break; + case EPROCLIM: + msg = "Too many processes"; + break; + case EUSERS: + msg = "Too many users"; + break; + case EDQUOT: + msg = "Disk quota exceeded"; + break; + case ESTALE: + msg = "Stale NFS file handle"; + break; + case EREMOTE: + msg = "Object is remote"; + break; +# if HAVE_WINSOCK2_H + /* WSA_INVALID_HANDLE maps to EBADF */ + /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ + /* WSA_INVALID_PARAMETER maps to EINVAL */ + case WSA_OPERATION_ABORTED: + msg = "Overlapped operation aborted"; + break; + case WSA_IO_INCOMPLETE: + msg = "Overlapped I/O event object not in signaled state"; + break; + case WSA_IO_PENDING: + msg = "Overlapped operations will complete later"; + break; + /* WSAEINTR maps to EINTR */ + /* WSAEBADF maps to EBADF */ + /* WSAEACCES maps to EACCES */ + /* WSAEFAULT maps to EFAULT */ + /* WSAEINVAL maps to EINVAL */ + /* WSAEMFILE maps to EMFILE */ + /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ + /* WSAEINPROGRESS is EINPROGRESS */ + /* WSAEALREADY is EALREADY */ + /* WSAENOTSOCK is ENOTSOCK */ + /* WSAEDESTADDRREQ is EDESTADDRREQ */ + /* WSAEMSGSIZE is EMSGSIZE */ + /* WSAEPROTOTYPE is EPROTOTYPE */ + /* WSAENOPROTOOPT is ENOPROTOOPT */ + /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */ + /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ + /* WSAEOPNOTSUPP is EOPNOTSUPP */ + /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ + /* WSAEAFNOSUPPORT is EAFNOSUPPORT */ + /* WSAEADDRINUSE is EADDRINUSE */ + /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */ + /* WSAENETDOWN is ENETDOWN */ + /* WSAENETUNREACH is ENETUNREACH */ + /* WSAENETRESET is ENETRESET */ + /* WSAECONNABORTED is ECONNABORTED */ + /* WSAECONNRESET is ECONNRESET */ + /* WSAENOBUFS is ENOBUFS */ + /* WSAEISCONN is EISCONN */ + /* WSAENOTCONN is ENOTCONN */ + /* WSAESHUTDOWN is ESHUTDOWN */ + /* WSAETOOMANYREFS is ETOOMANYREFS */ + /* WSAETIMEDOUT is ETIMEDOUT */ + /* WSAECONNREFUSED is ECONNREFUSED */ + /* WSAELOOP is ELOOP */ + /* WSAENAMETOOLONG maps to ENAMETOOLONG */ + /* WSAEHOSTDOWN is EHOSTDOWN */ + /* WSAEHOSTUNREACH is EHOSTUNREACH */ + /* WSAENOTEMPTY maps to ENOTEMPTY */ + /* WSAEPROCLIM is EPROCLIM */ + /* WSAEUSERS is EUSERS */ + /* WSAEDQUOT is EDQUOT */ + /* WSAESTALE is ESTALE */ + /* WSAEREMOTE is EREMOTE */ + case WSASYSNOTREADY: + msg = "Network subsystem is unavailable"; + break; + case WSAVERNOTSUPPORTED: + msg = "Winsock.dll version out of range"; + break; + case WSANOTINITIALISED: + msg = "Successful WSAStartup not yet performed"; + break; + case WSAEDISCON: + msg = "Graceful shutdown in progress"; + break; + case WSAENOMORE: case WSA_E_NO_MORE: + msg = "No more results"; + break; + case WSAECANCELLED: case WSA_E_CANCELLED: + msg = "Call was canceled"; + break; + case WSAEINVALIDPROCTABLE: + msg = "Procedure call table is invalid"; + break; + case WSAEINVALIDPROVIDER: + msg = "Service provider is invalid"; + break; + case WSAEPROVIDERFAILEDINIT: + msg = "Service provider failed to initialize"; + break; + case WSASYSCALLFAILURE: + msg = "System call failure"; + break; + case WSASERVICE_NOT_FOUND: + msg = "Service not found"; + break; + case WSATYPE_NOT_FOUND: + msg = "Class type not found"; + break; + case WSAEREFUSED: + msg = "Database query was refused"; + break; + case WSAHOST_NOT_FOUND: + msg = "Host not found"; + break; + case WSATRY_AGAIN: + msg = "Nonauthoritative host not found"; + break; + case WSANO_RECOVERY: + msg = "Nonrecoverable error"; + break; + case WSANO_DATA: + msg = "Valid name, no data record of requested type"; + break; + /* WSA_QOS_* omitted */ +# endif +# endif + +# if GNULIB_defined_ENOMSG + case ENOMSG: + msg = "No message of desired type"; + break; +# endif + +# if GNULIB_defined_EIDRM + case EIDRM: + msg = "Identifier removed"; + break; +# endif + +# if GNULIB_defined_ENOLINK + case ENOLINK: + msg = "Link has been severed"; + break; +# endif + +# if GNULIB_defined_EPROTO + case EPROTO: + msg = "Protocol error"; + break; +# endif + +# if GNULIB_defined_EMULTIHOP + case EMULTIHOP: + msg = "Multihop attempted"; + break; +# endif + +# if GNULIB_defined_EBADMSG + case EBADMSG: + msg = "Bad message"; + break; +# endif + +# if GNULIB_defined_EOVERFLOW + case EOVERFLOW: + msg = "Value too large for defined data type"; + break; +# endif + +# if GNULIB_defined_ENOTSUP + case ENOTSUP: + msg = "Not supported"; + break; +# endif + +# if GNULIB_defined_ESTALE + case ESTALE: + msg = "Stale NFS file handle"; + break; +# endif + +# if GNULIB_defined_ECANCELED + case ECANCELED: + msg = "Operation canceled"; + break; +# endif + } + + if (msg) + return (char *) msg; + + { + char *result = strerror (n); + + if (result == NULL || result[0] == '\0') + { + static char const fmt[] = "Unknown error (%d)"; + static char msg_buf[sizeof fmt + INT_STRLEN_BOUND (n)]; + sprintf (msg_buf, fmt, n); + return msg_buf; + } + + return result; + } +} + +#endif diff --git a/grub-core/gnulib/string.in.h b/grub-core/gnulib/string.in.h new file mode 100644 index 000000000..49c711d8f --- /dev/null +++ b/grub-core/gnulib/string.in.h @@ -0,0 +1,945 @@ +/* A GNU-like . + + Copyright (C) 1995-1996, 2001-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STRING_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STRING_H@ + +#ifndef _GL_STRING_H +#define _GL_STRING_H + +/* NetBSD 5.0 mis-defines NULL. */ +#include + +/* MirBSD defines mbslen as a macro. */ +#if @GNULIB_MBSLEN@ && defined __MirBSD__ +# include +#endif + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +# define __attribute__(Spec) /* empty */ +# endif +#endif +/* The attribute __pure__ was added in gcc 2.96. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define _GL_ATTRIBUTE_PURE /* empty */ +#endif + +/* NetBSD 5.0 declares strsignal in , not in . */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) \ + && ! defined __GLIBC__ +# include +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Return the first instance of C within N bytes of S, or NULL. */ +#if @GNULIB_MEMCHR@ +# if @REPLACE_MEMCHR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define memchr rpl_memchr +# endif +_GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); +# else +# if ! @HAVE_MEMCHR@ +_GL_FUNCDECL_SYS (memchr, void *, (void const *__s, int __c, size_t __n) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C" { const void * std::memchr (const void *, int, size_t); } + extern "C++" { void * std::memchr (void *, int, size_t); } */ +_GL_CXXALIAS_SYS_CAST2 (memchr, + void *, (void const *__s, int __c, size_t __n), + void const *, (void const *__s, int __c, size_t __n)); +# endif +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n)); +_GL_CXXALIASWARN1 (memchr, void const *, + (void const *__s, int __c, size_t __n)); +# else +_GL_CXXALIASWARN (memchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memchr +/* Assume memchr is always declared. */ +_GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " + "use gnulib module memchr for portability" ); +#endif + +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +#if @GNULIB_MEMMEM@ +# if @REPLACE_MEMMEM@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define memmem rpl_memmem +# endif +_GL_FUNCDECL_RPL (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 3))); +_GL_CXXALIAS_RPL (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len)); +# else +# if ! @HAVE_DECL_MEMMEM@ +_GL_FUNCDECL_SYS (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 3))); +# endif +_GL_CXXALIAS_SYS (memmem, void *, + (void const *__haystack, size_t __haystack_len, + void const *__needle, size_t __needle_len)); +# endif +_GL_CXXALIASWARN (memmem); +#elif defined GNULIB_POSIXCHECK +# undef memmem +# if HAVE_RAW_DECL_MEMMEM +_GL_WARN_ON_USE (memmem, "memmem is unportable and often quadratic - " + "use gnulib module memmem-simple for portability, " + "and module memmem for speed" ); +# endif +#endif + +/* Copy N bytes of SRC to DEST, return pointer to bytes after the + last written byte. */ +#if @GNULIB_MEMPCPY@ +# if ! @HAVE_MEMPCPY@ +_GL_FUNCDECL_SYS (mempcpy, void *, + (void *restrict __dest, void const *restrict __src, + size_t __n) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (mempcpy, void *, + (void *restrict __dest, void const *restrict __src, + size_t __n)); +_GL_CXXALIASWARN (mempcpy); +#elif defined GNULIB_POSIXCHECK +# undef mempcpy +# if HAVE_RAW_DECL_MEMPCPY +_GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - " + "use gnulib module mempcpy for portability"); +# endif +#endif + +/* Search backwards through a block for a byte (specified as an int). */ +#if @GNULIB_MEMRCHR@ +# if ! @HAVE_DECL_MEMRCHR@ +_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const void * std::memrchr (const void *, int, size_t); } + extern "C++" { void * std::memrchr (void *, int, size_t); } */ +_GL_CXXALIAS_SYS_CAST2 (memrchr, + void *, (void const *, int, size_t), + void const *, (void const *, int, size_t)); +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t)); +_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t)); +# else +_GL_CXXALIASWARN (memrchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memrchr +# if HAVE_RAW_DECL_MEMRCHR +_GL_WARN_ON_USE (memrchr, "memrchr is unportable - " + "use gnulib module memrchr for portability"); +# endif +#endif + +/* Find the first occurrence of C in S. More efficient than + memchr(S,C,N), at the expense of undefined behavior if C does not + occur within N bytes. */ +#if @GNULIB_RAWMEMCHR@ +# if ! @HAVE_RAWMEMCHR@ +_GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const void * std::rawmemchr (const void *, int); } + extern "C++" { void * std::rawmemchr (void *, int); } */ +_GL_CXXALIAS_SYS_CAST2 (rawmemchr, + void *, (void const *__s, int __c_in), + void const *, (void const *__s, int __c_in)); +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in)); +_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in)); +# else +_GL_CXXALIASWARN (rawmemchr); +# endif +#elif defined GNULIB_POSIXCHECK +# undef rawmemchr +# if HAVE_RAW_DECL_RAWMEMCHR +_GL_WARN_ON_USE (rawmemchr, "rawmemchr is unportable - " + "use gnulib module rawmemchr for portability"); +# endif +#endif + +/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */ +#if @GNULIB_STPCPY@ +# if ! @HAVE_STPCPY@ +_GL_FUNCDECL_SYS (stpcpy, char *, + (char *restrict __dst, char const *restrict __src) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (stpcpy, char *, + (char *restrict __dst, char const *restrict __src)); +_GL_CXXALIASWARN (stpcpy); +#elif defined GNULIB_POSIXCHECK +# undef stpcpy +# if HAVE_RAW_DECL_STPCPY +_GL_WARN_ON_USE (stpcpy, "stpcpy is unportable - " + "use gnulib module stpcpy for portability"); +# endif +#endif + +/* Copy no more than N bytes of SRC to DST, returning a pointer past the + last non-NUL byte written into DST. */ +#if @GNULIB_STPNCPY@ +# if @REPLACE_STPNCPY@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef stpncpy +# define stpncpy rpl_stpncpy +# endif +_GL_FUNCDECL_RPL (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n)); +# else +# if ! @HAVE_STPNCPY@ +_GL_FUNCDECL_SYS (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (stpncpy, char *, + (char *restrict __dst, char const *restrict __src, + size_t __n)); +# endif +_GL_CXXALIASWARN (stpncpy); +#elif defined GNULIB_POSIXCHECK +# undef stpncpy +# if HAVE_RAW_DECL_STPNCPY +_GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " + "use gnulib module stpncpy for portability"); +# endif +#endif + +#if defined GNULIB_POSIXCHECK +/* strchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +# undef strchr +/* Assume strchr is always declared. */ +_GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings " + "in some multibyte locales - " + "use mbschr if you care about internationalization"); +#endif + +/* Find the first occurrence of C in S or the final NUL byte. */ +#if @GNULIB_STRCHRNUL@ +# if ! @HAVE_STRCHRNUL@ +_GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * std::strchrnul (const char *, int); } + extern "C++" { char * std::strchrnul (char *, int); } */ +_GL_CXXALIAS_SYS_CAST2 (strchrnul, + char *, (char const *__s, int __c_in), + char const *, (char const *__s, int __c_in)); +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in)); +_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in)); +# else +_GL_CXXALIASWARN (strchrnul); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strchrnul +# if HAVE_RAW_DECL_STRCHRNUL +_GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - " + "use gnulib module strchrnul for portability"); +# endif +#endif + +/* Duplicate S, returning an identical malloc'd string. */ +#if @GNULIB_STRDUP@ +# if @REPLACE_STRDUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strdup +# define strdup rpl_strdup +# endif +_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strdup, char *, (char const *__s)); +# else +# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup + /* strdup exists as a function and as a macro. Get rid of the macro. */ +# undef strdup +# endif +# if !(@HAVE_DECL_STRDUP@ || defined strdup) +_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); +# endif +_GL_CXXALIASWARN (strdup); +#elif defined GNULIB_POSIXCHECK +# undef strdup +# if HAVE_RAW_DECL_STRDUP +_GL_WARN_ON_USE (strdup, "strdup is unportable - " + "use gnulib module strdup for portability"); +# endif +#endif + +/* Append no more than N characters from SRC onto DEST. */ +#if @GNULIB_STRNCAT@ +# if @REPLACE_STRNCAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strncat +# define strncat rpl_strncat +# endif +_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n)); +# else +_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n)); +# endif +_GL_CXXALIASWARN (strncat); +#elif defined GNULIB_POSIXCHECK +# undef strncat +# if HAVE_RAW_DECL_STRNCAT +_GL_WARN_ON_USE (strncat, "strncat is unportable - " + "use gnulib module strncat for portability"); +# endif +#endif + +/* Return a newly allocated copy of at most N bytes of STRING. */ +#if @GNULIB_STRNDUP@ +# if @REPLACE_STRNDUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strndup +# define strndup rpl_strndup +# endif +_GL_FUNCDECL_RPL (strndup, char *, (char const *__string, size_t __n) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strndup, char *, (char const *__string, size_t __n)); +# else +# if ! @HAVE_DECL_STRNDUP@ +_GL_FUNCDECL_SYS (strndup, char *, (char const *__string, size_t __n) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strndup, char *, (char const *__string, size_t __n)); +# endif +_GL_CXXALIASWARN (strndup); +#elif defined GNULIB_POSIXCHECK +# undef strndup +# if HAVE_RAW_DECL_STRNDUP +_GL_WARN_ON_USE (strndup, "strndup is unportable - " + "use gnulib module strndup for portability"); +# endif +#endif + +/* Find the length (number of bytes) of STRING, but scan at most + MAXLEN bytes. If no '\0' terminator is found in that many bytes, + return MAXLEN. */ +#if @GNULIB_STRNLEN@ +# if @REPLACE_STRNLEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strnlen +# define strnlen rpl_strnlen +# endif +_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__string, size_t __maxlen) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__string, size_t __maxlen)); +# else +# if ! @HAVE_DECL_STRNLEN@ +_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__string, size_t __maxlen) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__string, size_t __maxlen)); +# endif +_GL_CXXALIASWARN (strnlen); +#elif defined GNULIB_POSIXCHECK +# undef strnlen +# if HAVE_RAW_DECL_STRNLEN +_GL_WARN_ON_USE (strnlen, "strnlen is unportable - " + "use gnulib module strnlen for portability"); +# endif +#endif + +#if defined GNULIB_POSIXCHECK +/* strcspn() assumes the second argument is a list of single-byte characters. + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +# undef strcspn +/* Assume strcspn is always declared. */ +_GL_WARN_ON_USE (strcspn, "strcspn cannot work correctly on character strings " + "in multibyte locales - " + "use mbscspn if you care about internationalization"); +#endif + +/* Find the first occurrence in S of any character in ACCEPT. */ +#if @GNULIB_STRPBRK@ +# if ! @HAVE_STRPBRK@ +_GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C" { const char * strpbrk (const char *, const char *); } + extern "C++" { char * strpbrk (char *, const char *); } */ +_GL_CXXALIAS_SYS_CAST2 (strpbrk, + char *, (char const *__s, char const *__accept), + const char *, (char const *__s, char const *__accept)); +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept)); +_GL_CXXALIASWARN1 (strpbrk, char const *, + (char const *__s, char const *__accept)); +# else +_GL_CXXALIASWARN (strpbrk); +# endif +# if defined GNULIB_POSIXCHECK +/* strpbrk() assumes the second argument is a list of single-byte characters. + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +# undef strpbrk +_GL_WARN_ON_USE (strpbrk, "strpbrk cannot work correctly on character strings " + "in multibyte locales - " + "use mbspbrk if you care about internationalization"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strpbrk +# if HAVE_RAW_DECL_STRPBRK +_GL_WARN_ON_USE (strpbrk, "strpbrk is unportable - " + "use gnulib module strpbrk for portability"); +# endif +#endif + +#if defined GNULIB_POSIXCHECK +/* strspn() assumes the second argument is a list of single-byte characters. + Even in this simple case, it cannot work with multibyte strings. */ +# undef strspn +/* Assume strspn is always declared. */ +_GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " + "in multibyte locales - " + "use mbsspn if you care about internationalization"); +#endif + +#if defined GNULIB_POSIXCHECK +/* strrchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +# undef strrchr +/* Assume strrchr is always declared. */ +_GL_WARN_ON_USE (strrchr, "strrchr cannot work correctly on character strings " + "in some multibyte locales - " + "use mbsrchr if you care about internationalization"); +#endif + +/* Search the next delimiter (char listed in DELIM) starting at *STRINGP. + If one is found, overwrite it with a NUL, and advance *STRINGP + to point to the next char after it. Otherwise, set *STRINGP to NULL. + If *STRINGP was already NULL, nothing happens. + Return the old value of *STRINGP. + + This is a variant of strtok() that is multithread-safe and supports + empty fields. + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + Caveat: It doesn't work with multibyte strings unless all of the delimiter + characters are ASCII characters < 0x30. + + See also strtok_r(). */ +#if @GNULIB_STRSEP@ +# if ! @HAVE_STRSEP@ +_GL_FUNCDECL_SYS (strsep, char *, + (char **restrict __stringp, char const *restrict __delim) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (strsep, char *, + (char **restrict __stringp, char const *restrict __delim)); +_GL_CXXALIASWARN (strsep); +# if defined GNULIB_POSIXCHECK +# undef strsep +_GL_WARN_ON_USE (strsep, "strsep cannot work correctly on character strings " + "in multibyte locales - " + "use mbssep if you care about internationalization"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strsep +# if HAVE_RAW_DECL_STRSEP +_GL_WARN_ON_USE (strsep, "strsep is unportable - " + "use gnulib module strsep for portability"); +# endif +#endif + +#if @GNULIB_STRSTR@ +# if @REPLACE_STRSTR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strstr rpl_strstr +# endif +_GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle)); +# else + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * strstr (const char *, const char *); } + extern "C++" { char * strstr (char *, const char *); } */ +_GL_CXXALIAS_SYS_CAST2 (strstr, + char *, (const char *haystack, const char *needle), + const char *, (const char *haystack, const char *needle)); +# endif +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle)); +_GL_CXXALIASWARN1 (strstr, const char *, + (const char *haystack, const char *needle)); +# else +_GL_CXXALIASWARN (strstr); +# endif +#elif defined GNULIB_POSIXCHECK +/* strstr() does not work with multibyte strings if the locale encoding is + different from UTF-8: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strstr +/* Assume strstr is always declared. */ +_GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot " + "work correctly on character strings in most " + "multibyte locales - " + "use mbsstr if you care about internationalization, " + "or use strstr if you care about speed"); +#endif + +/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive + comparison. */ +#if @GNULIB_STRCASESTR@ +# if @REPLACE_STRCASESTR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strcasestr rpl_strcasestr +# endif +_GL_FUNCDECL_RPL (strcasestr, char *, + (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (strcasestr, char *, + (const char *haystack, const char *needle)); +# else +# if ! @HAVE_STRCASESTR@ +_GL_FUNCDECL_SYS (strcasestr, char *, + (const char *haystack, const char *needle) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); +# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * strcasestr (const char *, const char *); } + extern "C++" { char * strcasestr (char *, const char *); } */ +_GL_CXXALIAS_SYS_CAST2 (strcasestr, + char *, (const char *haystack, const char *needle), + const char *, (const char *haystack, const char *needle)); +# endif +# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle)); +_GL_CXXALIASWARN1 (strcasestr, const char *, + (const char *haystack, const char *needle)); +# else +_GL_CXXALIASWARN (strcasestr); +# endif +#elif defined GNULIB_POSIXCHECK +/* strcasestr() does not work with multibyte strings: + It is a glibc extension, and glibc implements it only for unibyte + locales. */ +# undef strcasestr +# if HAVE_RAW_DECL_STRCASESTR +_GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character " + "strings in multibyte locales - " + "use mbscasestr if you care about " + "internationalization, or use c-strcasestr if you want " + "a locale independent function"); +# endif +#endif + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = strtok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" + + This is a variant of strtok() that is multithread-safe. + + For the POSIX documentation for this function, see: + http://www.opengroup.org/susv3xsh/strtok.html + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + Caveat: It doesn't work with multibyte strings unless all of the delimiter + characters are ASCII characters < 0x30. + + See also strsep(). */ +#if @GNULIB_STRTOK_R@ +# if @REPLACE_STRTOK_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strtok_r +# define strtok_r rpl_strtok_r +# endif +_GL_FUNCDECL_RPL (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr) + _GL_ARG_NONNULL ((2, 3))); +_GL_CXXALIAS_RPL (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr)); +# else +# if @UNDEFINE_STRTOK_R@ || defined GNULIB_POSIXCHECK +# undef strtok_r +# endif +# if ! @HAVE_DECL_STRTOK_R@ +_GL_FUNCDECL_SYS (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (strtok_r, char *, + (char *restrict s, char const *restrict delim, + char **restrict save_ptr)); +# endif +_GL_CXXALIASWARN (strtok_r); +# if defined GNULIB_POSIXCHECK +_GL_WARN_ON_USE (strtok_r, "strtok_r cannot work correctly on character " + "strings in multibyte locales - " + "use mbstok_r if you care about internationalization"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strtok_r +# if HAVE_RAW_DECL_STRTOK_R +_GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " + "use gnulib module strtok_r for portability"); +# endif +#endif + + +/* The following functions are not specified by POSIX. They are gnulib + extensions. */ + +#if @GNULIB_MBSLEN@ +/* Return the number of multibyte characters in the character string STRING. + This considers multibyte characters, unlike strlen, which counts bytes. */ +# ifdef __MirBSD__ /* MirBSD defines mbslen as a macro. Override it. */ +# undef mbslen +# endif +# if @HAVE_MBSLEN@ /* AIX, OSF/1, MirBSD define mbslen already in libc. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbslen rpl_mbslen +# endif +_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); +# else +_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string)); +# endif +_GL_CXXALIASWARN (mbslen); +#endif + +#if @GNULIB_MBSNLEN@ +/* Return the number of multibyte characters in the character string starting + at STRING and ending at STRING + LEN. */ +_GL_EXTERN_C size_t mbsnlen (const char *string, size_t len) + _GL_ARG_NONNULL ((1)); +#endif + +#if @GNULIB_MBSCHR@ +/* Locate the first single-byte character C in the character string STRING, + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +# if defined __hpux +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbschr rpl_mbschr /* avoid collision with HP-UX function */ +# endif +_GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c)); +# else +_GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c)); +# endif +_GL_CXXALIASWARN (mbschr); +#endif + +#if @GNULIB_MBSRCHR@ +/* Locate the last single-byte character C in the character string STRING, + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strrchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +# if defined __hpux +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbsrchr rpl_mbsrchr /* avoid collision with HP-UX function */ +# endif +_GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c)); +# else +_GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c)); +# endif +_GL_CXXALIASWARN (mbsrchr); +#endif + +#if @GNULIB_MBSSTR@ +/* Find the first occurrence of the character string NEEDLE in the character + string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK. + Unlike strstr(), this function works correctly in multibyte locales with + encodings different from UTF-8. */ +_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSCASECMP@ +/* Compare the character strings S1 and S2, ignoring case, returning less than, + equal to or greater than zero if S1 is lexicographically less than, equal to + or greater than S2. + Note: This function may, in multibyte locales, return 0 for strings of + different lengths! + Unlike strcasecmp(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSNCASECMP@ +/* Compare the initial segment of the character string S1 consisting of at most + N characters with the initial segment of the character string S2 consisting + of at most N characters, ignoring case, returning less than, equal to or + greater than zero if the initial segment of S1 is lexicographically less + than, equal to or greater than the initial segment of S2. + Note: This function may, in multibyte locales, return 0 for initial segments + of different lengths! + Unlike strncasecmp(), this function works correctly in multibyte locales. + But beware that N is not a byte count but a character count! */ +_GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSPCASECMP@ +/* Compare the initial segment of the character string STRING consisting of + at most mbslen (PREFIX) characters with the character string PREFIX, + ignoring case. If the two match, return a pointer to the first byte + after this prefix in STRING. Otherwise, return NULL. + Note: This function may, in multibyte locales, return non-NULL if STRING + is of smaller length than PREFIX! + Unlike strncasecmp(), this function works correctly in multibyte + locales. */ +_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSCASESTR@ +/* Find the first occurrence of the character string NEEDLE in the character + string HAYSTACK, using case-insensitive comparison. + Note: This function may, in multibyte locales, return success even if + strlen (haystack) < strlen (needle) ! + Unlike strcasestr(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSCSPN@ +/* Find the first occurrence in the character string STRING of any character + in the character string ACCEPT. Return the number of bytes from the + beginning of the string to this occurrence, or to the end of the string + if none exists. + Unlike strcspn(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C size_t mbscspn (const char *string, const char *accept) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSPBRK@ +/* Find the first occurrence in the character string STRING of any character + in the character string ACCEPT. Return the pointer to it, or NULL if none + exists. + Unlike strpbrk(), this function works correctly in multibyte locales. */ +# if defined __hpux +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ +# endif +_GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept)); +# else +_GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept)); +# endif +_GL_CXXALIASWARN (mbspbrk); +#endif + +#if @GNULIB_MBSSPN@ +/* Find the first occurrence in the character string STRING of any character + not in the character string REJECT. Return the number of bytes from the + beginning of the string to this occurrence, or to the end of the string + if none exists. + Unlike strspn(), this function works correctly in multibyte locales. */ +_GL_EXTERN_C size_t mbsspn (const char *string, const char *reject) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSSEP@ +/* Search the next delimiter (multibyte character listed in the character + string DELIM) starting at the character string *STRINGP. + If one is found, overwrite it with a NUL, and advance *STRINGP to point + to the next multibyte character after it. Otherwise, set *STRINGP to NULL. + If *STRINGP was already NULL, nothing happens. + Return the old value of *STRINGP. + + This is a variant of mbstok_r() that supports empty fields. + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + + See also mbstok_r(). */ +_GL_EXTERN_C char * mbssep (char **stringp, const char *delim) + _GL_ARG_NONNULL ((1, 2)); +#endif + +#if @GNULIB_MBSTOK_R@ +/* Parse the character string STRING into tokens separated by characters in + the character string DELIM. + If STRING is NULL, the saved pointer in SAVE_PTR is used as + the next starting point. For example: + char s[] = "-abc-=-def"; + char *sp; + x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def" + x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL + x = mbstok_r(NULL, "=", &sp); // x = NULL + // s = "abc\0-def\0" + + Caveat: It modifies the original string. + Caveat: These functions cannot be used on constant strings. + Caveat: The identity of the delimiting character is lost. + + See also mbssep(). */ +_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr) + _GL_ARG_NONNULL ((2, 3)); +#endif + +/* Map any int, typically from errno, into an error message. */ +#if @GNULIB_STRERROR@ +# if @REPLACE_STRERROR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strerror +# define strerror rpl_strerror +# endif +_GL_FUNCDECL_RPL (strerror, char *, (int)); +_GL_CXXALIAS_RPL (strerror, char *, (int)); +# else +_GL_CXXALIAS_SYS (strerror, char *, (int)); +# endif +_GL_CXXALIASWARN (strerror); +#elif defined GNULIB_POSIXCHECK +# undef strerror +/* Assume strerror is always declared. */ +_GL_WARN_ON_USE (strerror, "strerror is unportable - " + "use gnulib module strerror to guarantee non-NULL result"); +#endif + +#if @GNULIB_STRSIGNAL@ +# if @REPLACE_STRSIGNAL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define strsignal rpl_strsignal +# endif +_GL_FUNCDECL_RPL (strsignal, char *, (int __sig)); +_GL_CXXALIAS_RPL (strsignal, char *, (int __sig)); +# else +# if ! @HAVE_DECL_STRSIGNAL@ +_GL_FUNCDECL_SYS (strsignal, char *, (int __sig)); +# endif +/* Need to cast, because on Cygwin 1.5.x systems, the return type is + 'const char *'. */ +_GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig)); +# endif +_GL_CXXALIASWARN (strsignal); +#elif defined GNULIB_POSIXCHECK +# undef strsignal +# if HAVE_RAW_DECL_STRSIGNAL +_GL_WARN_ON_USE (strsignal, "strsignal is unportable - " + "use gnulib module strsignal for portability"); +# endif +#endif + +#if @GNULIB_STRVERSCMP@ +# if !@HAVE_STRVERSCMP@ +_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *)); +_GL_CXXALIASWARN (strverscmp); +#elif defined GNULIB_POSIXCHECK +# undef strverscmp +# if HAVE_RAW_DECL_STRVERSCMP +_GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " + "use gnulib module strverscmp for portability"); +# endif +#endif + + +#endif /* _GL_STRING_H */ +#endif /* _GL_STRING_H */ diff --git a/grub-core/gnulib/strings.in.h b/grub-core/gnulib/strings.in.h new file mode 100644 index 000000000..c726a1623 --- /dev/null +++ b/grub-core/gnulib/strings.in.h @@ -0,0 +1,93 @@ +/* A substitute . + + Copyright (C) 2007-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _GL_STRINGS_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#@INCLUDE_NEXT@ @NEXT_STRINGS_H@ + +#ifndef _GL_STRINGS_H +#define _GL_STRINGS_H + + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. + Note: This function does not work in multibyte locales. */ +#if ! @HAVE_STRCASECMP@ +extern int strcasecmp (char const *s1, char const *s2) + _GL_ARG_NONNULL ((1, 2)); +#endif +#if defined GNULIB_POSIXCHECK +/* strcasecmp() does not work with multibyte strings: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strcasecmp +# if HAVE_RAW_DECL_STRCASECMP +_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " + "strings in multibyte locales - " + "use mbscasecmp if you care about " + "internationalization, or use c_strcasecmp , " + "gnulib module c-strcase) if you want a locale " + "independent function"); +# endif +#endif + +/* Compare no more than N bytes of strings S1 and S2, ignoring case, + returning less than, equal to or greater than zero if S1 is + lexicographically less than, equal to or greater than S2. + Note: This function cannot work correctly in multibyte locales. */ +#if ! @HAVE_DECL_STRNCASECMP@ +extern int strncasecmp (char const *s1, char const *s2, size_t n) + _GL_ARG_NONNULL ((1, 2)); +#endif +#if defined GNULIB_POSIXCHECK +/* strncasecmp() does not work with multibyte strings: + POSIX says that it operates on "strings", and "string" in POSIX is defined + as a sequence of bytes, not of characters. */ +# undef strncasecmp +# if HAVE_RAW_DECL_STRNCASECMP +_GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " + "strings in multibyte locales - " + "use mbsncasecmp or mbspcasecmp if you care about " + "internationalization, or use c_strncasecmp , " + "gnulib module c-strcase) if you want a locale " + "independent function"); +# endif +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _GL_STRING_H */ +#endif /* _GL_STRING_H */ diff --git a/grub-core/gnulib/strncasecmp.c b/grub-core/gnulib/strncasecmp.c new file mode 100644 index 000000000..8c806a6b0 --- /dev/null +++ b/grub-core/gnulib/strncasecmp.c @@ -0,0 +1,63 @@ +/* strncasecmp.c -- case insensitive string comparator + Copyright (C) 1998-1999, 2005-2007, 2009-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +#include +#include + +#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) + +/* Compare no more than N bytes of strings S1 and S2, ignoring case, + returning less than, equal to or greater than zero if S1 is + lexicographically less than, equal to or greater than S2. + Note: This function cannot work correctly in multibyte locales. */ + +int +strncasecmp (const char *s1, const char *s2, size_t n) +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2 || n == 0) + return 0; + + do + { + c1 = TOLOWER (*p1); + c2 = TOLOWER (*p2); + + if (--n == 0 || c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* On machines where 'char' and 'int' are types of the same size, the + difference of two 'unsigned char' values - including the sign bit - + doesn't fit in an 'int'. */ + return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); +} diff --git a/grub-core/gnulib/strndup.c b/grub-core/gnulib/strndup.c new file mode 100644 index 000000000..3de3dbc5a --- /dev/null +++ b/grub-core/gnulib/strndup.c @@ -0,0 +1,37 @@ +/* A replacement function, for systems that lack strndup. + + Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007, 2009, + 2010 Free Software Foundation, Inc. + + This program 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, or (at your option) any + later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +#include + +#include + +char * +strndup (char const *s, size_t n) +{ + size_t len = strnlen (s, n); + char *new = malloc (len + 1); + + if (new == NULL) + return NULL; + + new[len] = '\0'; + return memcpy (new, s, len); +} diff --git a/grub-core/gnulib/strnlen.c b/grub-core/gnulib/strnlen.c new file mode 100644 index 000000000..f1ec356dc --- /dev/null +++ b/grub-core/gnulib/strnlen.c @@ -0,0 +1,31 @@ +/* Find the length of STRING, but scan at most MAXLEN characters. + Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +#include + +/* Find the length of STRING, but scan at most MAXLEN characters. + If no '\0' terminator is found in that many characters, return MAXLEN. */ + +size_t +strnlen (const char *string, size_t maxlen) +{ + const char *end = memchr (string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} diff --git a/grub-core/gnulib/argp-version-etc.c b/grub-core/gnulib/strnlen1.c similarity index 52% rename from grub-core/gnulib/argp-version-etc.c rename to grub-core/gnulib/strnlen1.c index f500a8f56..b8cd2bff0 100644 --- a/grub-core/gnulib/argp-version-etc.c +++ b/grub-core/gnulib/strnlen1.c @@ -1,5 +1,5 @@ -/* Version hook for Argp. - Copyright (C) 2009, 2010 Free Software Foundation, Inc. +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,24 +15,21 @@ along with this program. If not, see . */ #include -#include -#include -#include -static const char *program_canonical_name; -static const char * const *program_authors; +/* Specification. */ +#include "strnlen1.h" -static void -version_etc_hook (FILE *stream, struct argp_state *state) +#include + +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + If no '\0' terminator is found in that many characters, return MAXLEN. */ +/* This is the same as strnlen (string, maxlen - 1) + 1. */ +size_t +strnlen1 (const char *string, size_t maxlen) { - version_etc_ar (stream, program_canonical_name, PACKAGE_NAME, VERSION, - program_authors); -} - -void -argp_version_setup (const char *name, const char * const *authors) -{ - argp_program_version_hook = version_etc_hook; - program_canonical_name = name; - program_authors = authors; + const char *end = (const char *) memchr (string, '\0', maxlen); + if (end != NULL) + return end - string + 1; + else + return maxlen; } diff --git a/grub-core/gnulib/argp-version-etc.h b/grub-core/gnulib/strnlen1.h similarity index 52% rename from grub-core/gnulib/argp-version-etc.h rename to grub-core/gnulib/strnlen1.h index 7c12c0181..dfaf62dcb 100644 --- a/grub-core/gnulib/argp-version-etc.h +++ b/grub-core/gnulib/strnlen1.h @@ -1,5 +1,5 @@ -/* Version hook for Argp. - Copyright (C) 2009, 2010 Free Software Foundation, Inc. +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,27 +14,26 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef _ARGP_VERSION_ETC_H -#define _ARGP_VERSION_ETC_H +#ifndef _STRNLEN1_H +#define _STRNLEN1_H + +#include + #ifdef __cplusplus extern "C" { #endif -/* Setup standard display of the version information for the `--version' - option. NAME is the canonical program name, and AUTHORS is a NULL- - terminated array of author names. At least one author name must be - given. - If NAME is NULL, the package name (as given by the PACKAGE macro) - is asumed to be the name of the program. +/* Find the length of STRING + 1, but scan at most MAXLEN bytes. + If no '\0' terminator is found in that many characters, return MAXLEN. */ +/* This is the same as strnlen (string, maxlen - 1) + 1. */ +extern size_t strnlen1 (const char *string, size_t maxlen); - This function is intended to be called before argp_parse(). -*/ -extern void argp_version_setup (const char *name, const char * const *authors); #ifdef __cplusplus } #endif -#endif /* _ARGP_VERSION_ETC_H */ + +#endif /* _STRNLEN1_H */ diff --git a/grub-core/gnulib/sys_wait.in.h b/grub-core/gnulib/sys_wait.in.h new file mode 100644 index 000000000..009fa219b --- /dev/null +++ b/grub-core/gnulib/sys_wait.in.h @@ -0,0 +1,106 @@ +/* A POSIX-like . + Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + + +#ifndef _GL_SYS_WAIT_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* The include_next requires a split double-inclusion guard. */ +#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +# @INCLUDE_NEXT@ @NEXT_SYS_WAIT_H@ +#endif + +#ifndef _GL_SYS_WAIT_H +#define _GL_SYS_WAIT_H + +#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +/* Unix API. */ + +/* The following macros apply to an argument x, that is a status of a process, + as returned by waitpid(). + On nearly all systems, including Linux/x86, WEXITSTATUS are bits 15..8 and + WTERMSIG are bits 7..0, while BeOS uses the opposite. Therefore programs + have to use the abstract macros. */ + +/* For valid x, exactly one of WIFSIGNALED(x), WIFEXITED(x), WIFSTOPPED(x) + is true. */ +# ifndef WIFSIGNALED +# define WIFSIGNALED(x) (WTERMSIG (x) != 0 && WTERMSIG(x) != 0x7f) +# endif +# ifndef WIFEXITED +# define WIFEXITED(x) (WTERMSIG (x) == 0) +# endif +# ifndef WIFSTOPPED +# define WIFSTOPPED(x) (WTERMSIG (x) == 0x7f) +# endif + +/* The termination signal. Only to be accessed if WIFSIGNALED(x) is true. */ +# ifndef WTERMSIG +# define WTERMSIG(x) ((x) & 0x7f) +# endif + +/* The exit status. Only to be accessed if WIFEXITED(x) is true. */ +# ifndef WEXITSTATUS +# define WEXITSTATUS(x) (((x) >> 8) & 0xff) +# endif + +/* True if the process dumped core. Not standardized by POSIX. */ +# ifndef WCOREDUMP +# define WCOREDUMP(x) ((x) & 0x80) +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* Declarations of functions. */ + +# ifdef __cplusplus +} +# endif + +#else +/* Native Windows API. */ + +# include + +# define waitpid(pid,statusp,options) _cwait (statusp, pid, WAIT_CHILD) + +/* The following macros apply to an argument x, that is a status of a process, + as returned by waitpid() or, equivalently, _cwait() or GetExitCodeProcess(). + This value is simply an 'int', not composed of bit fields. */ + +/* When an unhandled fatal signal terminates a process, the exit code is 3. */ +# define WIFSIGNALED(x) ((x) == 3) +# define WIFEXITED(x) ((x) != 3) +# define WIFSTOPPED(x) 0 + +/* The signal that terminated a process is not known posthum. */ +# define WTERMSIG(x) SIGTERM + +# define WEXITSTATUS(x) (x) + +/* There are no core dumps. */ +# define WCOREDUMP(x) 0 + +#endif + +#endif /* _GL_SYS_WAIT_H */ +#endif /* _GL_SYS_WAIT_H */ diff --git a/grub-core/gnulib/sysexits.in.h b/grub-core/gnulib/sysexits.in.h new file mode 100644 index 000000000..45255dfa5 --- /dev/null +++ b/grub-core/gnulib/sysexits.in.h @@ -0,0 +1,71 @@ +/* exit() exit codes for some BSD system programs. + Copyright (C) 2003, 2006-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +/* Written by Simon Josefsson based on sysexits(3) man page */ + +#ifndef _GL_SYSEXITS_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if @HAVE_SYSEXITS_H@ + +/* IRIX 6.5 has an that defines a macro EX_OK with a nonzero + value. Override it. See + */ +# ifdef __sgi +# include +# undef EX_OK +# endif + +/* The include_next requires a split double-inclusion guard. */ +# @INCLUDE_NEXT@ @NEXT_SYSEXITS_H@ + +/* HP-UX 11 ends at EX_NOPERM. */ +# ifndef EX_CONFIG +# define EX_CONFIG 78 +# endif + +#endif + +#ifndef _GL_SYSEXITS_H +#define _GL_SYSEXITS_H + +#if !@HAVE_SYSEXITS_H@ + +# define EX_OK 0 /* same value as EXIT_SUCCESS */ + +# define EX_USAGE 64 +# define EX_DATAERR 65 +# define EX_NOINPUT 66 +# define EX_NOUSER 67 +# define EX_NOHOST 68 +# define EX_UNAVAILABLE 69 +# define EX_SOFTWARE 70 +# define EX_OSERR 71 +# define EX_OSFILE 72 +# define EX_CANTCREAT 73 +# define EX_IOERR 74 +# define EX_TEMPFAIL 75 +# define EX_PROTOCOL 76 +# define EX_NOPERM 77 +# define EX_CONFIG 78 + +#endif + +#endif /* _GL_SYSEXITS_H */ +#endif /* _GL_SYSEXITS_H */ diff --git a/grub-core/gnulib/unistd.in.h b/grub-core/gnulib/unistd.in.h new file mode 100644 index 000000000..26a4cbd6a --- /dev/null +++ b/grub-core/gnulib/unistd.in.h @@ -0,0 +1,1326 @@ +/* Substitute for and wrapper around . + Copyright (C) 2003-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +/* Special invocation convention: + - On mingw, several headers, including , include , + but we need to ensure that both the system and + are completely included before we replace gethostname. */ +#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ + && !defined _GL_WINSOCK2_H_WITNESS && defined _WINSOCK2_H +/* is being indirectly included for the first time from + ; avoid declaring any overrides. */ +# if @HAVE_UNISTD_H@ +# @INCLUDE_NEXT@ @NEXT_UNISTD_H@ +# else +# error unexpected; report this to bug-gnulib@gnu.org +# endif +# define _GL_WINSOCK2_H_WITNESS + +/* Normal invocation. */ +#elif !defined _GL_UNISTD_H + +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_UNISTD_H@ +# @INCLUDE_NEXT@ @NEXT_UNISTD_H@ +#endif + +/* Get all possible declarations of gethostname(). */ +#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ + && !defined _GL_INCLUDING_WINSOCK2_H +# define _GL_INCLUDING_WINSOCK2_H +# include +# undef _GL_INCLUDING_WINSOCK2_H +#endif + +#if !defined _GL_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H +#define _GL_UNISTD_H + +/* NetBSD 5.0 mis-defines NULL. Also get size_t. */ +#include + +/* mingw doesn't define the SEEK_* or *_FILENO macros in . */ +/* Cygwin 1.7.1 declares symlinkat in , not in . */ +/* But avoid namespace pollution on glibc systems. */ +#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \ + || (@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK)) \ + && ! defined __GLIBC__ +# include +#endif + +/* Cygwin 1.7.1 declares unlinkat in , not in . */ +/* But avoid namespace pollution on glibc systems. */ +#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ +# include +#endif + +/* mingw fails to declare _exit in . */ +/* mingw, BeOS, Haiku declare environ in , not in . */ +/* Solaris declares getcwd not only in but also in . */ +/* But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include +#endif + +/* mingw declares getcwd in , not in . */ +#if ((@GNULIB_GETCWD@ || defined GNULIB_POSIXCHECK) \ + && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) +# include +#endif + +#if (@GNULIB_WRITE@ || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \ + || @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK) +/* Get ssize_t. */ +# include +#endif + +/* Get getopt(), optarg, optind, opterr, optopt. + But avoid namespace pollution on glibc systems. */ +#if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT +# include +#endif + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +#if @GNULIB_GETHOSTNAME@ +/* Get all possible declarations of gethostname(). */ +# if @UNISTD_H_HAVE_WINSOCK2_H@ +# if !defined _GL_SYS_SOCKET_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef socket +# define socket socket_used_without_including_sys_socket_h +# undef connect +# define connect connect_used_without_including_sys_socket_h +# undef accept +# define accept accept_used_without_including_sys_socket_h +# undef bind +# define bind bind_used_without_including_sys_socket_h +# undef getpeername +# define getpeername getpeername_used_without_including_sys_socket_h +# undef getsockname +# define getsockname getsockname_used_without_including_sys_socket_h +# undef getsockopt +# define getsockopt getsockopt_used_without_including_sys_socket_h +# undef listen +# define listen listen_used_without_including_sys_socket_h +# undef recv +# define recv recv_used_without_including_sys_socket_h +# undef send +# define send send_used_without_including_sys_socket_h +# undef recvfrom +# define recvfrom recvfrom_used_without_including_sys_socket_h +# undef sendto +# define sendto sendto_used_without_including_sys_socket_h +# undef setsockopt +# define setsockopt setsockopt_used_without_including_sys_socket_h +# undef shutdown +# define shutdown shutdown_used_without_including_sys_socket_h +# else + _GL_WARN_ON_USE (socket, + "socket() used without including "); + _GL_WARN_ON_USE (connect, + "connect() used without including "); + _GL_WARN_ON_USE (accept, + "accept() used without including "); + _GL_WARN_ON_USE (bind, + "bind() used without including "); + _GL_WARN_ON_USE (getpeername, + "getpeername() used without including "); + _GL_WARN_ON_USE (getsockname, + "getsockname() used without including "); + _GL_WARN_ON_USE (getsockopt, + "getsockopt() used without including "); + _GL_WARN_ON_USE (listen, + "listen() used without including "); + _GL_WARN_ON_USE (recv, + "recv() used without including "); + _GL_WARN_ON_USE (send, + "send() used without including "); + _GL_WARN_ON_USE (recvfrom, + "recvfrom() used without including "); + _GL_WARN_ON_USE (sendto, + "sendto() used without including "); + _GL_WARN_ON_USE (setsockopt, + "setsockopt() used without including "); + _GL_WARN_ON_USE (shutdown, + "shutdown() used without including "); +# endif +# endif +# if !defined _GL_SYS_SELECT_H +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef select +# define select select_used_without_including_sys_select_h +# else + _GL_WARN_ON_USE (select, + "select() used without including "); +# endif +# endif +# endif +#endif + + +/* OS/2 EMX lacks these macros. */ +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO +# define STDERR_FILENO 2 +#endif + +/* Ensure *_OK macros exist. */ +#ifndef F_OK +# define F_OK 0 +# define X_OK 1 +# define W_OK 2 +# define R_OK 4 +#endif + + +/* Declare overridden functions. */ + + +#if defined GNULIB_POSIXCHECK +/* The access() function is a security risk. */ +_GL_WARN_ON_USE (access, "the access function is a security risk - " + "use the gnulib module faccessat instead"); +#endif + + +#if @GNULIB_CHOWN@ +/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE + to GID (if GID is not -1). Follow symbolic links. + Return 0 if successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if @REPLACE_CHOWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef chown +# define chown rpl_chown +# endif +_GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)); +# else +# if !@HAVE_CHOWN@ +_GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)); +# endif +_GL_CXXALIASWARN (chown); +#elif defined GNULIB_POSIXCHECK +# undef chown +# if HAVE_RAW_DECL_CHOWN +_GL_WARN_ON_USE (chown, "chown fails to follow symlinks on some systems and " + "doesn't treat a uid or gid of -1 on some systems - " + "use gnulib module chown for portability"); +# endif +#endif + + +#if @GNULIB_CLOSE@ +# if @REPLACE_CLOSE@ +/* Automatically included by modules that need a replacement for close. */ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef close +# define close rpl_close +# endif +_GL_FUNCDECL_RPL (close, int, (int fd)); +_GL_CXXALIAS_RPL (close, int, (int fd)); +# else +_GL_CXXALIAS_SYS (close, int, (int fd)); +# endif +_GL_CXXALIASWARN (close); +#elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ +# undef close +# define close close_used_without_requesting_gnulib_module_close +#elif defined GNULIB_POSIXCHECK +# undef close +/* Assume close is always declared. */ +_GL_WARN_ON_USE (close, "close does not portably work on sockets - " + "use gnulib module close for portability"); +#endif + + +#if @REPLACE_DUP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dup rpl_dup +# endif +_GL_FUNCDECL_RPL (dup, int, (int oldfd)); +_GL_CXXALIAS_RPL (dup, int, (int oldfd)); +#else +_GL_CXXALIAS_SYS (dup, int, (int oldfd)); +#endif +_GL_CXXALIASWARN (dup); + + +#if @GNULIB_DUP2@ +/* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if + NEWFD = OLDFD, otherwise close NEWFD first if it is open. + Return newfd if successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if @REPLACE_DUP2@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dup2 rpl_dup2 +# endif +_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd)); +_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); +# else +# if !@HAVE_DUP2@ +_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd)); +# endif +_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd)); +# endif +_GL_CXXALIASWARN (dup2); +#elif defined GNULIB_POSIXCHECK +# undef dup2 +# if HAVE_RAW_DECL_DUP2 +_GL_WARN_ON_USE (dup2, "dup2 is unportable - " + "use gnulib module dup2 for portability"); +# endif +#endif + + +#if @GNULIB_DUP3@ +/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the + specified flags. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + Close NEWFD first if it is open. + Return newfd if successful, otherwise -1 and errno set. + See the Linux man page at + . */ +# if @HAVE_DUP3@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define dup3 rpl_dup3 +# endif +_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags)); +_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags)); +# else +_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags)); +_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags)); +# endif +_GL_CXXALIASWARN (dup3); +#elif defined GNULIB_POSIXCHECK +# undef dup3 +# if HAVE_RAW_DECL_DUP3 +_GL_WARN_ON_USE (dup3, "dup3 is unportable - " + "use gnulib module dup3 for portability"); +# endif +#endif + + +#if @GNULIB_ENVIRON@ +# if !@HAVE_DECL_ENVIRON@ +/* Set of environment variables and values. An array of strings of the form + "VARIABLE=VALUE", terminated with a NULL. */ +# if defined __APPLE__ && defined __MACH__ +# include +# define environ (*_NSGetEnviron ()) +# else +# ifdef __cplusplus +extern "C" { +# endif +extern char **environ; +# ifdef __cplusplus +} +# endif +# endif +# endif +#elif defined GNULIB_POSIXCHECK +# if HAVE_RAW_DECL_ENVIRON +static inline char *** +rpl_environ (void) +{ + return &environ; +} +_GL_WARN_ON_USE (rpl_environ, "environ is unportable - " + "use gnulib module environ for portability"); +# undef environ +# define environ (*rpl_environ ()) +# endif +#endif + + +#if @GNULIB_EUIDACCESS@ +/* Like access(), except that it uses the effective user id and group id of + the current process. */ +# if !@HAVE_EUIDACCESS@ +_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode)); +_GL_CXXALIASWARN (euidaccess); +# if defined GNULIB_POSIXCHECK +/* Like access(), this function is a security risk. */ +_GL_WARN_ON_USE (euidaccess, "the euidaccess function is a security risk - " + "use the gnulib module faccessat instead"); +# endif +#elif defined GNULIB_POSIXCHECK +# undef euidaccess +# if HAVE_RAW_DECL_EUIDACCESS +_GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - " + "use gnulib module euidaccess for portability"); +# endif +#endif + + +#if @GNULIB_FACCESSAT@ +# if !@HAVE_FACCESSAT@ +_GL_FUNCDECL_SYS (faccessat, int, + (int fd, char const *file, int mode, int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (faccessat, int, + (int fd, char const *file, int mode, int flag)); +_GL_CXXALIASWARN (faccessat); +#elif defined GNULIB_POSIXCHECK +# undef faccessat +# if HAVE_RAW_DECL_FACCESSAT +_GL_WARN_ON_USE (faccessat, "faccessat is not portable - " + "use gnulib module faccessat for portability"); +# endif +#endif + + +#if @GNULIB_FCHDIR@ +/* Change the process' current working directory to the directory on which + the given file descriptor is open. + Return 0 if successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if ! @HAVE_FCHDIR@ +_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); + +/* Gnulib internal hooks needed to maintain the fchdir metadata. */ +_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename) + _GL_ARG_NONNULL ((2)); +_GL_EXTERN_C void _gl_unregister_fd (int fd); +_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd); +_GL_EXTERN_C const char *_gl_directory_name (int fd); + +# endif +_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/)); +_GL_CXXALIASWARN (fchdir); +#elif defined GNULIB_POSIXCHECK +# undef fchdir +# if HAVE_RAW_DECL_FCHDIR +_GL_WARN_ON_USE (fchdir, "fchdir is unportable - " + "use gnulib module fchdir for portability"); +# endif +#endif + + +#if @GNULIB_FCHOWNAT@ +# if @REPLACE_FCHOWNAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fchownat +# define fchownat rpl_fchownat +# endif +_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag)); +# else +# if !@HAVE_FCHOWNAT@ +_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file, + uid_t owner, gid_t group, int flag)); +# endif +_GL_CXXALIASWARN (fchownat); +#elif defined GNULIB_POSIXCHECK +# undef fchownat +# if HAVE_RAW_DECL_FCHOWNAT +_GL_WARN_ON_USE (fchownat, "fchownat is not portable - " + "use gnulib module openat for portability"); +# endif +#endif + + +#if @GNULIB_FSYNC@ +/* Synchronize changes to a file. + Return 0 if successful, otherwise -1 and errno set. + See POSIX:2001 specification + . */ +# if !@HAVE_FSYNC@ +_GL_FUNCDECL_SYS (fsync, int, (int fd)); +# endif +_GL_CXXALIAS_SYS (fsync, int, (int fd)); +_GL_CXXALIASWARN (fsync); +#elif defined GNULIB_POSIXCHECK +# undef fsync +# if HAVE_RAW_DECL_FSYNC +_GL_WARN_ON_USE (fsync, "fsync is unportable - " + "use gnulib module fsync for portability"); +# endif +#endif + + +#if @GNULIB_FTRUNCATE@ +/* Change the size of the file to which FD is opened to become equal to LENGTH. + Return 0 if successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if !@HAVE_FTRUNCATE@ +_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); +# endif +_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); +_GL_CXXALIASWARN (ftruncate); +#elif defined GNULIB_POSIXCHECK +# undef ftruncate +# if HAVE_RAW_DECL_FTRUNCATE +_GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " + "use gnulib module ftruncate for portability"); +# endif +#endif + + +#if @GNULIB_GETCWD@ +/* Get the name of the current working directory, and put it in SIZE bytes + of BUF. + Return BUF if successful, or NULL if the directory couldn't be determined + or SIZE was too small. + See the POSIX:2001 specification + . + Additionally, the gnulib module 'getcwd' guarantees the following GNU + extension: If BUF is NULL, an array is allocated with 'malloc'; the array + is SIZE bytes long, unless SIZE == 0, in which case it is as big as + necessary. */ +# if @REPLACE_GETCWD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getcwd rpl_getcwd +# endif +_GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size)); +_GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size)); +# else +/* Need to cast, because on mingw, the second parameter is + int size. */ +_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size)); +# endif +_GL_CXXALIASWARN (getcwd); +#elif defined GNULIB_POSIXCHECK +# undef getcwd +# if HAVE_RAW_DECL_GETCWD +_GL_WARN_ON_USE (getcwd, "getcwd is unportable - " + "use gnulib module getcwd for portability"); +# endif +#endif + + +#if @GNULIB_GETDOMAINNAME@ +/* Return the NIS domain name of the machine. + WARNING! The NIS domain name is unrelated to the fully qualified host name + of the machine. It is also unrelated to email addresses. + WARNING! The NIS domain name is usually the empty string or "(none)" when + not using NIS. + + Put up to LEN bytes of the NIS domain name into NAME. + Null terminate it if the name is shorter than LEN. + If the NIS domain name is longer than LEN, set errno = EINVAL and return -1. + Return 0 if successful, otherwise set errno and return -1. */ +# if !@HAVE_GETDOMAINNAME@ +_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on MacOS X 10.5 systems, the second parameter is + int len. */ +_GL_CXXALIAS_SYS_CAST (getdomainname, int, (char *name, size_t len)); +_GL_CXXALIASWARN (getdomainname); +#elif defined GNULIB_POSIXCHECK +# undef getdomainname +# if HAVE_RAW_DECL_GETDOMAINNAME +_GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - " + "use gnulib module getdomainname for portability"); +# endif +#endif + + +#if @GNULIB_GETDTABLESIZE@ +/* Return the maximum number of file descriptors in the current process. + In POSIX, this is same as sysconf (_SC_OPEN_MAX). */ +# if !@HAVE_GETDTABLESIZE@ +_GL_FUNCDECL_SYS (getdtablesize, int, (void)); +# endif +_GL_CXXALIAS_SYS (getdtablesize, int, (void)); +_GL_CXXALIASWARN (getdtablesize); +#elif defined GNULIB_POSIXCHECK +# undef getdtablesize +# if HAVE_RAW_DECL_GETDTABLESIZE +_GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - " + "use gnulib module getdtablesize for portability"); +# endif +#endif + + +#if @GNULIB_GETGROUPS@ +/* Return the supplemental groups that the current process belongs to. + It is unspecified whether the effective group id is in the list. + If N is 0, return the group count; otherwise, N describes how many + entries are available in GROUPS. Return -1 and set errno if N is + not 0 and not large enough. Fails with ENOSYS on some systems. */ +# if @REPLACE_GETGROUPS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getgroups +# define getgroups rpl_getgroups +# endif +_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups)); +_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups)); +# else +# if !@HAVE_GETGROUPS@ +_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups)); +# endif +_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups)); +# endif +_GL_CXXALIASWARN (getgroups); +#elif defined GNULIB_POSIXCHECK +# undef getgroups +# if HAVE_RAW_DECL_GETGROUPS +_GL_WARN_ON_USE (getgroups, "getgroups is unportable - " + "use gnulib module getgroups for portability"); +# endif +#endif + + +#if @GNULIB_GETHOSTNAME@ +/* Return the standard host name of the machine. + WARNING! The host name may or may not be fully qualified. + + Put up to LEN bytes of the host name into NAME. + Null terminate it if the name is shorter than LEN. + If the host name is longer than LEN, set errno = EINVAL and return -1. + Return 0 if successful, otherwise set errno and return -1. */ +# if @UNISTD_H_HAVE_WINSOCK2_H@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef gethostname +# define gethostname rpl_gethostname +# endif +_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); +# else +# if !@HAVE_GETHOSTNAME@ +_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on Solaris 10 systems, the second parameter is + int len. */ +_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len)); +# endif +_GL_CXXALIASWARN (gethostname); +#elif @UNISTD_H_HAVE_WINSOCK2_H@ +# undef gethostname +# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname +#elif defined GNULIB_POSIXCHECK +# undef gethostname +# if HAVE_RAW_DECL_GETHOSTNAME +_GL_WARN_ON_USE (gethostname, "gethostname is unportable - " + "use gnulib module gethostname for portability"); +# endif +#endif + + +#if @GNULIB_GETLOGIN@ +/* Returns the user's login name, or NULL if it cannot be found. Upon error, + returns NULL with errno set. + + See . + + Most programs don't need to use this function, because the information is + available through environment variables: + ${LOGNAME-$USER} on Unix platforms, + $USERNAME on native Windows platforms. + */ +# if !@HAVE_GETLOGIN@ +_GL_FUNCDECL_SYS (getlogin, char *, (void)); +# endif +_GL_CXXALIAS_SYS (getlogin, char *, (void)); +_GL_CXXALIASWARN (getlogin); +#elif defined GNULIB_POSIXCHECK +# undef getlogin +# if HAVE_RAW_DECL_GETLOGIN +_GL_WARN_ON_USE (getlogin, "getlogin is unportable - " + "use gnulib module getlogin for portability"); +# endif +#endif + + +#if @GNULIB_GETLOGIN_R@ +/* Copies the user's login name to NAME. + The array pointed to by NAME has room for SIZE bytes. + + Returns 0 if successful. Upon error, an error number is returned, or -1 in + the case that the login name cannot be found but no specific error is + provided (this case is hopefully rare but is left open by the POSIX spec). + + See . + + Most programs don't need to use this function, because the information is + available through environment variables: + ${LOGNAME-$USER} on Unix platforms, + $USERNAME on native Windows platforms. + */ +# if !@HAVE_DECL_GETLOGIN_R@ +_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size) + _GL_ARG_NONNULL ((1))); +# endif +/* Need to cast, because on Solaris 10 systems, the second argument is + int size. */ +_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size)); +_GL_CXXALIASWARN (getlogin_r); +#elif defined GNULIB_POSIXCHECK +# undef getlogin_r +# if HAVE_RAW_DECL_GETLOGIN_R +_GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - " + "use gnulib module getlogin_r for portability"); +# endif +#endif + + +#if @GNULIB_GETPAGESIZE@ +# if @REPLACE_GETPAGESIZE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getpagesize rpl_getpagesize +# endif +_GL_FUNCDECL_RPL (getpagesize, int, (void)); +_GL_CXXALIAS_RPL (getpagesize, int, (void)); +# else +# if !@HAVE_GETPAGESIZE@ +# if !defined getpagesize +/* This is for POSIX systems. */ +# if !defined _gl_getpagesize && defined _SC_PAGESIZE +# if ! (defined __VMS && __VMS_VER < 70000000) +# define _gl_getpagesize() sysconf (_SC_PAGESIZE) +# endif +# endif +/* This is for older VMS. */ +# if !defined _gl_getpagesize && defined __VMS +# ifdef __ALPHA +# define _gl_getpagesize() 8192 +# else +# define _gl_getpagesize() 512 +# endif +# endif +/* This is for BeOS. */ +# if !defined _gl_getpagesize && @HAVE_OS_H@ +# include +# if defined B_PAGE_SIZE +# define _gl_getpagesize() B_PAGE_SIZE +# endif +# endif +/* This is for AmigaOS4.0. */ +# if !defined _gl_getpagesize && defined __amigaos4__ +# define _gl_getpagesize() 2048 +# endif +/* This is for older Unix systems. */ +# if !defined _gl_getpagesize && @HAVE_SYS_PARAM_H@ +# include +# ifdef EXEC_PAGESIZE +# define _gl_getpagesize() EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define CLSIZE 1 +# endif +# define _gl_getpagesize() (NBPG * CLSIZE) +# else +# ifdef NBPC +# define _gl_getpagesize() NBPC +# endif +# endif +# endif +# endif +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getpagesize() _gl_getpagesize () +# else +static inline int +getpagesize () +{ + return _gl_getpagesize (); +} +# endif +# endif +# endif +/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t. */ +_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void)); +# endif +# if @HAVE_DECL_GETPAGESIZE@ +_GL_CXXALIASWARN (getpagesize); +# endif +#elif defined GNULIB_POSIXCHECK +# undef getpagesize +# if HAVE_RAW_DECL_GETPAGESIZE +_GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - " + "use gnulib module getpagesize for portability"); +# endif +#endif + + +#if @GNULIB_GETUSERSHELL@ +/* Return the next valid login shell on the system, or NULL when the end of + the list has been reached. */ +# if !@HAVE_DECL_GETUSERSHELL@ +_GL_FUNCDECL_SYS (getusershell, char *, (void)); +# endif +_GL_CXXALIAS_SYS (getusershell, char *, (void)); +_GL_CXXALIASWARN (getusershell); +#elif defined GNULIB_POSIXCHECK +# undef getusershell +# if HAVE_RAW_DECL_GETUSERSHELL +_GL_WARN_ON_USE (getusershell, "getusershell is unportable - " + "use gnulib module getusershell for portability"); +# endif +#endif + +#if @GNULIB_GETUSERSHELL@ +/* Rewind to pointer that is advanced at each getusershell() call. */ +# if !@HAVE_DECL_GETUSERSHELL@ +_GL_FUNCDECL_SYS (setusershell, void, (void)); +# endif +_GL_CXXALIAS_SYS (setusershell, void, (void)); +_GL_CXXALIASWARN (setusershell); +#elif defined GNULIB_POSIXCHECK +# undef setusershell +# if HAVE_RAW_DECL_SETUSERSHELL +_GL_WARN_ON_USE (setusershell, "setusershell is unportable - " + "use gnulib module getusershell for portability"); +# endif +#endif + +#if @GNULIB_GETUSERSHELL@ +/* Free the pointer that is advanced at each getusershell() call and + associated resources. */ +# if !@HAVE_DECL_GETUSERSHELL@ +_GL_FUNCDECL_SYS (endusershell, void, (void)); +# endif +_GL_CXXALIAS_SYS (endusershell, void, (void)); +_GL_CXXALIASWARN (endusershell); +#elif defined GNULIB_POSIXCHECK +# undef endusershell +# if HAVE_RAW_DECL_ENDUSERSHELL +_GL_WARN_ON_USE (endusershell, "endusershell is unportable - " + "use gnulib module getusershell for portability"); +# endif +#endif + + +#if @GNULIB_LCHOWN@ +/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE + to GID (if GID is not -1). Do not follow symbolic links. + Return 0 if successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if @REPLACE_LCHOWN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef lchown +# define lchown rpl_lchown +# endif +_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)); +# else +# if !@HAVE_LCHOWN@ +_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)); +# endif +_GL_CXXALIASWARN (lchown); +#elif defined GNULIB_POSIXCHECK +# undef lchown +# if HAVE_RAW_DECL_LCHOWN +_GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - " + "use gnulib module lchown for portability"); +# endif +#endif + + +#if @GNULIB_LINK@ +/* Create a new hard link for an existing file. + Return 0 if successful, otherwise -1 and errno set. + See POSIX:2001 specification + . */ +# if @REPLACE_LINK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define link rpl_link +# endif +_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2)); +# else +# if !@HAVE_LINK@ +_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2)); +# endif +_GL_CXXALIASWARN (link); +#elif defined GNULIB_POSIXCHECK +# undef link +# if HAVE_RAW_DECL_LINK +_GL_WARN_ON_USE (link, "link is unportable - " + "use gnulib module link for portability"); +# endif +#endif + + +#if @GNULIB_LINKAT@ +/* Create a new hard link for an existing file, relative to two + directories. FLAG controls whether symlinks are followed. + Return 0 if successful, otherwise -1 and errno set. */ +# if @REPLACE_LINKAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef linkat +# define linkat rpl_linkat +# endif +_GL_FUNCDECL_RPL (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag) + _GL_ARG_NONNULL ((2, 4))); +_GL_CXXALIAS_RPL (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag)); +# else +# if !@HAVE_LINKAT@ +_GL_FUNCDECL_SYS (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag) + _GL_ARG_NONNULL ((2, 4))); +# endif +_GL_CXXALIAS_SYS (linkat, int, + (int fd1, const char *path1, int fd2, const char *path2, + int flag)); +# endif +_GL_CXXALIASWARN (linkat); +#elif defined GNULIB_POSIXCHECK +# undef linkat +# if HAVE_RAW_DECL_LINKAT +_GL_WARN_ON_USE (linkat, "linkat is unportable - " + "use gnulib module linkat for portability"); +# endif +#endif + + +#if @GNULIB_LSEEK@ +/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END. + Return the new offset if successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if @REPLACE_LSEEK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define lseek rpl_lseek +# endif +_GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence)); +_GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence)); +# else +_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence)); +# endif +_GL_CXXALIASWARN (lseek); +#elif defined GNULIB_POSIXCHECK +# undef lseek +# if HAVE_RAW_DECL_LSEEK +_GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some " + "systems - use gnulib module lseek for portability"); +# endif +#endif + + +#if @GNULIB_PIPE2@ +/* Create a pipe, applying the given flags when opening the read-end of the + pipe and the write-end of the pipe. + The flags are a bitmask, possibly including O_CLOEXEC (defined in ) + and O_TEXT, O_BINARY (defined in "binary-io.h"). + Store the read-end as fd[0] and the write-end as fd[1]. + Return 0 upon success, or -1 with errno set upon failure. + See also the Linux man page at + . */ +# if @HAVE_PIPE2@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define pipe2 rpl_pipe2 +# endif +_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags)); +# else +_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags)); +# endif +_GL_CXXALIASWARN (pipe2); +#elif defined GNULIB_POSIXCHECK +# undef pipe2 +# if HAVE_RAW_DECL_PIPE2 +_GL_WARN_ON_USE (pipe2, "pipe2 is unportable - " + "use gnulib module pipe2 for portability"); +# endif +#endif + + +#if @GNULIB_PREAD@ +/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET. + Return the number of bytes placed into BUF if successful, otherwise + set errno and return -1. 0 indicates EOF. See the POSIX:2001 + specification . */ +# if @REPLACE_PREAD@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define pread rpl_pread +# endif +_GL_FUNCDECL_RPL (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset)); +# else +# if !@HAVE_PREAD@ +_GL_FUNCDECL_SYS (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (pread, ssize_t, + (int fd, void *buf, size_t bufsize, off_t offset)); +# endif +_GL_CXXALIASWARN (pread); +#elif defined GNULIB_POSIXCHECK +# undef pread +# if HAVE_RAW_DECL_PREAD +_GL_WARN_ON_USE (pread, "pread is unportable - " + "use gnulib module pread for portability"); +# endif +#endif + + +#if @GNULIB_PWRITE@ +/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET. + Return the number of bytes written if successful, otherwise + set errno and return -1. 0 indicates nothing written. See the + POSIX:2001 specification + . */ +# if @REPLACE_PWRITE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define pwrite rpl_pwrite +# endif +_GL_FUNCDECL_RPL (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset)); +# else +# if !@HAVE_PWRITE@ +_GL_FUNCDECL_SYS (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (pwrite, ssize_t, + (int fd, const void *buf, size_t bufsize, off_t offset)); +# endif +_GL_CXXALIASWARN (pwrite); +#elif defined GNULIB_POSIXCHECK +# undef pwrite +# if HAVE_RAW_DECL_PWRITE +_GL_WARN_ON_USE (pwrite, "pwrite is unportable - " + "use gnulib module pwrite for portability"); +# endif +#endif + + +#if @GNULIB_READLINK@ +/* Read the contents of the symbolic link FILE and place the first BUFSIZE + bytes of it into BUF. Return the number of bytes placed into BUF if + successful, otherwise -1 and errno set. + See the POSIX:2001 specification + . */ +# if @REPLACE_READLINK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define readlink rpl_readlink +# endif +_GL_FUNCDECL_RPL (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize)); +# else +# if !@HAVE_READLINK@ +_GL_FUNCDECL_SYS (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (readlink, ssize_t, + (const char *file, char *buf, size_t bufsize)); +# endif +_GL_CXXALIASWARN (readlink); +#elif defined GNULIB_POSIXCHECK +# undef readlink +# if HAVE_RAW_DECL_READLINK +_GL_WARN_ON_USE (readlink, "readlink is unportable - " + "use gnulib module readlink for portability"); +# endif +#endif + + +#if @GNULIB_READLINKAT@ +# if !@HAVE_READLINKAT@ +_GL_FUNCDECL_SYS (readlinkat, ssize_t, + (int fd, char const *file, char *buf, size_t len) + _GL_ARG_NONNULL ((2, 3))); +# endif +_GL_CXXALIAS_SYS (readlinkat, ssize_t, + (int fd, char const *file, char *buf, size_t len)); +_GL_CXXALIASWARN (readlinkat); +#elif defined GNULIB_POSIXCHECK +# undef readlinkat +# if HAVE_RAW_DECL_READLINKAT +_GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - " + "use gnulib module readlinkat for portability"); +# endif +#endif + + +#if @GNULIB_RMDIR@ +/* Remove the directory DIR. */ +# if @REPLACE_RMDIR@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define rmdir rpl_rmdir +# endif +_GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (rmdir, int, (char const *name)); +# else +_GL_CXXALIAS_SYS (rmdir, int, (char const *name)); +# endif +_GL_CXXALIASWARN (rmdir); +#elif defined GNULIB_POSIXCHECK +# undef rmdir +# if HAVE_RAW_DECL_RMDIR +_GL_WARN_ON_USE (rmdir, "rmdir is unportable - " + "use gnulib module rmdir for portability"); +# endif +#endif + + +#if @GNULIB_SLEEP@ +/* Pause the execution of the current thread for N seconds. + Returns the number of seconds left to sleep. + See the POSIX:2001 specification + . */ +# if @REPLACE_SLEEP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef sleep +# define sleep rpl_sleep +# endif +_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n)); +_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n)); +# else +# if !@HAVE_SLEEP@ +_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n)); +# endif +_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n)); +# endif +_GL_CXXALIASWARN (sleep); +#elif defined GNULIB_POSIXCHECK +# undef sleep +# if HAVE_RAW_DECL_SLEEP +_GL_WARN_ON_USE (sleep, "sleep is unportable - " + "use gnulib module sleep for portability"); +# endif +#endif + + +#if @GNULIB_SYMLINK@ +# if @REPLACE_SYMLINK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef symlink +# define symlink rpl_symlink +# endif +_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file)); +# else +# if !@HAVE_SYMLINK@ +_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file) + _GL_ARG_NONNULL ((1, 2))); +# endif +_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file)); +# endif +_GL_CXXALIASWARN (symlink); +#elif defined GNULIB_POSIXCHECK +# undef symlink +# if HAVE_RAW_DECL_SYMLINK +_GL_WARN_ON_USE (symlink, "symlink is not portable - " + "use gnulib module symlink for portability"); +# endif +#endif + + +#if @GNULIB_SYMLINKAT@ +# if !@HAVE_SYMLINKAT@ +_GL_FUNCDECL_SYS (symlinkat, int, + (char const *contents, int fd, char const *file) + _GL_ARG_NONNULL ((1, 3))); +# endif +_GL_CXXALIAS_SYS (symlinkat, int, + (char const *contents, int fd, char const *file)); +_GL_CXXALIASWARN (symlinkat); +#elif defined GNULIB_POSIXCHECK +# undef symlinkat +# if HAVE_RAW_DECL_SYMLINKAT +_GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " + "use gnulib module symlinkat for portability"); +# endif +#endif + + +#if @GNULIB_TTYNAME_R@ +/* Store at most BUFLEN characters of the pathname of the terminal FD is + open on in BUF. Return 0 on success, otherwise an error number. */ +# if @REPLACE_TTYNAME_R@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ttyname_r +# define ttyname_r rpl_ttyname_r +# endif +_GL_FUNCDECL_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen)); +# else +# if !@HAVE_TTYNAME_R@ +_GL_FUNCDECL_SYS (ttyname_r, int, + (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (ttyname_r, int, + (int fd, char *buf, size_t buflen)); +# endif +_GL_CXXALIASWARN (ttyname_r); +#elif defined GNULIB_POSIXCHECK +# undef ttyname_r +# if HAVE_RAW_DECL_TTYNAME_R +_GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - " + "use gnulib module ttyname_r for portability"); +# endif +#endif + + +#if @GNULIB_UNLINK@ +# if @REPLACE_UNLINK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unlink +# define unlink rpl_unlink +# endif +_GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (unlink, int, (char const *file)); +# else +_GL_CXXALIAS_SYS (unlink, int, (char const *file)); +# endif +_GL_CXXALIASWARN (unlink); +#elif defined GNULIB_POSIXCHECK +# undef unlink +# if HAVE_RAW_DECL_UNLINK +_GL_WARN_ON_USE (unlink, "unlink is not portable - " + "use gnulib module unlink for portability"); +# endif +#endif + + +#if @GNULIB_UNLINKAT@ +# if @REPLACE_UNLINKAT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef unlinkat +# define unlinkat rpl_unlinkat +# endif +_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag)); +# else +# if !@HAVE_UNLINKAT@ +_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag)); +# endif +_GL_CXXALIASWARN (unlinkat); +#elif defined GNULIB_POSIXCHECK +# undef unlinkat +# if HAVE_RAW_DECL_UNLINKAT +_GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " + "use gnulib module openat for portability"); +# endif +#endif + + +#if @GNULIB_USLEEP@ +/* Pause the execution of the current thread for N microseconds. + Returns 0 on completion, or -1 on range error. + See the POSIX:2001 specification + . */ +# if @REPLACE_USLEEP@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef usleep +# define usleep rpl_usleep +# endif +_GL_FUNCDECL_RPL (usleep, int, (useconds_t n)); +_GL_CXXALIAS_RPL (usleep, int, (useconds_t n)); +# else +# if !@HAVE_USLEEP@ +_GL_FUNCDECL_SYS (usleep, int, (useconds_t n)); +# endif +_GL_CXXALIAS_SYS (usleep, int, (useconds_t n)); +# endif +_GL_CXXALIASWARN (usleep); +#elif defined GNULIB_POSIXCHECK +# undef usleep +# if HAVE_RAW_DECL_USLEEP +_GL_WARN_ON_USE (usleep, "usleep is unportable - " + "use gnulib module usleep for portability"); +# endif +#endif + + +#if @GNULIB_WRITE@ +/* Write up to COUNT bytes starting at BUF to file descriptor FD. + See the POSIX:2001 specification + . */ +# if @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef write +# define write rpl_write +# endif +_GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count)); +# else +/* Need to cast, because on mingw, the third parameter is + unsigned int count + and the return type is 'int'. */ +_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count)); +# endif +_GL_CXXALIASWARN (write); +#endif + + +#endif /* _GL_UNISTD_H */ +#endif /* _GL_UNISTD_H */ diff --git a/grub-core/gnulib/vasnprintf.c b/grub-core/gnulib/vasnprintf.c new file mode 100644 index 000000000..e618901ba --- /dev/null +++ b/grub-core/gnulib/vasnprintf.c @@ -0,0 +1,5567 @@ +/* vsprintf with automatic memory allocation. + Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file can be parametrized with the following macros: + VASNPRINTF The name of the function being defined. + FCHAR_T The element type of the format string. + DCHAR_T The element type of the destination (result) string. + FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters + in the format string are ASCII. MUST be set if + FCHAR_T and DCHAR_T are not the same type. + DIRECTIVE Structure denoting a format directive. + Depends on FCHAR_T. + DIRECTIVES Structure denoting the set of format directives of a + format string. Depends on FCHAR_T. + PRINTF_PARSE Function that parses a format string. + Depends on FCHAR_T. + DCHAR_CPY memcpy like function for DCHAR_T[] arrays. + DCHAR_SET memset like function for DCHAR_T[] arrays. + DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. + SNPRINTF The system's snprintf (or similar) function. + This may be either snprintf or swprintf. + TCHAR_T The element type of the argument and result string + of the said SNPRINTF function. This may be either + char or wchar_t. The code exploits that + sizeof (TCHAR_T) | sizeof (DCHAR_T) and + alignof (TCHAR_T) <= alignof (DCHAR_T). + DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type. + DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[]. + DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t. + DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t. + DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */ + +/* Tell glibc's to provide a prototype for snprintf(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifndef VASNPRINTF +# include +#endif +#ifndef IN_LIBINTL +# include +#endif + +/* Specification. */ +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# include "vasnwprintf.h" +# else +# include "vasnprintf.h" +# endif +#endif + +#include /* localeconv() */ +#include /* snprintf(), sprintf() */ +#include /* abort(), malloc(), realloc(), free() */ +#include /* memcpy(), strlen() */ +#include /* errno */ +#include /* CHAR_BIT */ +#include /* DBL_MAX_EXP, LDBL_MAX_EXP */ +#if HAVE_NL_LANGINFO +# include +#endif +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# include "wprintf-parse.h" +# else +# include "printf-parse.h" +# endif +#endif + +/* Checked size_t computations. */ +#include "xsize.h" + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "float+.h" +#endif + +#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnand-nolibm.h" +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnanl-nolibm.h" +# include "fpucw.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnand-nolibm.h" +# include "printf-frexp.h" +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL +# include +# include "isnanl-nolibm.h" +# include "printf-frexpl.h" +# include "fpucw.h" +#endif + +/* Default parameters. */ +#ifndef VASNPRINTF +# if WIDE_CHAR_VERSION +# define VASNPRINTF vasnwprintf +# define FCHAR_T wchar_t +# define DCHAR_T wchar_t +# define TCHAR_T wchar_t +# define DCHAR_IS_TCHAR 1 +# define DIRECTIVE wchar_t_directive +# define DIRECTIVES wchar_t_directives +# define PRINTF_PARSE wprintf_parse +# define DCHAR_CPY wmemcpy +# define DCHAR_SET wmemset +# else +# define VASNPRINTF vasnprintf +# define FCHAR_T char +# define DCHAR_T char +# define TCHAR_T char +# define DCHAR_IS_TCHAR 1 +# define DIRECTIVE char_directive +# define DIRECTIVES char_directives +# define PRINTF_PARSE printf_parse +# define DCHAR_CPY memcpy +# define DCHAR_SET memset +# endif +#endif +#if WIDE_CHAR_VERSION + /* TCHAR_T is wchar_t. */ +# define USE_SNPRINTF 1 +# if HAVE_DECL__SNWPRINTF + /* On Windows, the function swprintf() has a different signature than + on Unix; we use the function _snwprintf() or - on mingw - snwprintf() + instead. The mingw function snwprintf() has fewer bugs than the + MSVCRT function _snwprintf(), so prefer that. */ +# if defined __MINGW32__ +# define SNPRINTF snwprintf +# else +# define SNPRINTF _snwprintf +# endif +# else + /* Unix. */ +# define SNPRINTF swprintf +# endif +#else + /* TCHAR_T is char. */ + /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. + But don't use it on BeOS, since BeOS snprintf produces no output if the + size argument is >= 0x3000000. + Also don't use it on Linux libc5, since there snprintf with size = 1 + writes any output without bounds, like sprintf. */ +# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1) +# define USE_SNPRINTF 1 +# else +# define USE_SNPRINTF 0 +# endif +# if HAVE_DECL__SNPRINTF + /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT + function _snprintf(), so prefer that. */ +# if defined __MINGW32__ +# define SNPRINTF snprintf + /* Here we need to call the native snprintf, not rpl_snprintf. */ +# undef snprintf +# else +# define SNPRINTF _snprintf +# endif +# else + /* Unix. */ +# define SNPRINTF snprintf + /* Here we need to call the native snprintf, not rpl_snprintf. */ +# undef snprintf +# endif +#endif +/* Here we need to call the native sprintf, not rpl_sprintf. */ +#undef sprintf + +/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" + warnings in this file. Use -Dlint to suppress them. */ +#ifdef lint +# define IF_LINT(Code) Code +#else +# define IF_LINT(Code) /* empty */ +#endif + +/* Avoid some warnings from "gcc -Wshadow". + This file doesn't use the exp() and remainder() functions. */ +#undef exp +#define exp expo +#undef remainder +#define remainder rem + +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION +# if (HAVE_STRNLEN && !defined _AIX) +# define local_strnlen strnlen +# else +# ifndef local_strnlen_defined +# define local_strnlen_defined 1 +static size_t +local_strnlen (const char *string, size_t maxlen) +{ + const char *end = memchr (string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} +# endif +# endif +#endif + +#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T +# if HAVE_WCSLEN +# define local_wcslen wcslen +# else + /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid + a dependency towards this library, here is a local substitute. + Define this substitute only once, even if this file is included + twice in the same compilation unit. */ +# ifndef local_wcslen_defined +# define local_wcslen_defined 1 +static size_t +local_wcslen (const wchar_t *s) +{ + const wchar_t *ptr; + + for (ptr = s; *ptr != (wchar_t) 0; ptr++) + ; + return ptr - s; +} +# endif +# endif +#endif + +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION +# if HAVE_WCSNLEN +# define local_wcsnlen wcsnlen +# else +# ifndef local_wcsnlen_defined +# define local_wcsnlen_defined 1 +static size_t +local_wcsnlen (const wchar_t *s, size_t maxlen) +{ + const wchar_t *ptr; + + for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--) + ; + return ptr - s; +} +# endif +# endif +#endif + +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL +/* Determine the decimal-point character according to the current locale. */ +# ifndef decimal_point_char_defined +# define decimal_point_char_defined 1 +static char +decimal_point_char (void) +{ + const char *point; + /* Determine it in a multithread-safe way. We know nl_langinfo is + multithread-safe on glibc systems and MacOS X systems, but is not required + to be multithread-safe by POSIX. sprintf(), however, is multithread-safe. + localeconv() is rarely multithread-safe. */ +# if HAVE_NL_LANGINFO && (__GLIBC__ || (defined __APPLE__ && defined __MACH__)) + point = nl_langinfo (RADIXCHAR); +# elif 1 + char pointbuf[5]; + sprintf (pointbuf, "%#.0f", 1.0); + point = &pointbuf[1]; +# else + point = localeconv () -> decimal_point; +# endif + /* The decimal point is always a single byte: either '.' or ','. */ + return (point[0] != '\0' ? point[0] : '.'); +} +# endif +#endif + +#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zero (double x) +{ + return isnand (x) || x + x == x; +} + +#endif + +#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL + +/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ +static int +is_infinite_or_zerol (long double x) +{ + return isnanl (x) || x + x == x; +} + +#endif + +#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL + +/* Converting 'long double' to decimal without rare rounding bugs requires + real bignums. We use the naming conventions of GNU gmp, but vastly simpler + (and slower) algorithms. */ + +typedef unsigned int mp_limb_t; +# define GMP_LIMB_BITS 32 +typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1]; + +typedef unsigned long long mp_twolimb_t; +# define GMP_TWOLIMB_BITS 64 +typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1]; + +/* Representation of a bignum >= 0. */ +typedef struct +{ + size_t nlimbs; + mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */ +} mpn_t; + +/* Compute the product of two bignums >= 0. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +multiply (mpn_t src1, mpn_t src2, mpn_t *dest) +{ + const mp_limb_t *p1; + const mp_limb_t *p2; + size_t len1; + size_t len2; + + if (src1.nlimbs <= src2.nlimbs) + { + len1 = src1.nlimbs; + p1 = src1.limbs; + len2 = src2.nlimbs; + p2 = src2.limbs; + } + else + { + len1 = src2.nlimbs; + p1 = src2.limbs; + len2 = src1.nlimbs; + p2 = src1.limbs; + } + /* Now 0 <= len1 <= len2. */ + if (len1 == 0) + { + /* src1 or src2 is zero. */ + dest->nlimbs = 0; + dest->limbs = (mp_limb_t *) malloc (1); + } + else + { + /* Here 1 <= len1 <= len2. */ + size_t dlen; + mp_limb_t *dp; + size_t k, i, j; + + dlen = len1 + len2; + dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); + if (dp == NULL) + return NULL; + for (k = len2; k > 0; ) + dp[--k] = 0; + for (i = 0; i < len1; i++) + { + mp_limb_t digit1 = p1[i]; + mp_twolimb_t carry = 0; + for (j = 0; j < len2; j++) + { + mp_limb_t digit2 = p2[j]; + carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; + carry += dp[i + j]; + dp[i + j] = (mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; + } + dp[i + len2] = (mp_limb_t) carry; + } + /* Normalise. */ + while (dlen > 0 && dp[dlen - 1] == 0) + dlen--; + dest->nlimbs = dlen; + dest->limbs = dp; + } + return dest->limbs; +} + +/* Compute the quotient of a bignum a >= 0 and a bignum b > 0. + a is written as a = q * b + r with 0 <= r < b. q is the quotient, r + the remainder. + Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, + q is incremented. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +divide (mpn_t a, mpn_t b, mpn_t *q) +{ + /* Algorithm: + First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]] + with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS). + If m=n=1, perform a single-precision division: + r:=0, j:=m, + while j>0 do + {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j = + = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r=n>1, perform a multiple-precision division: + We have a/b < beta^(m-n+1). + s:=intDsize-1-(highest bit in b[n-1]), 0<=s=beta/2. + For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).} + Compute q* : + q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]). + In case of overflow (q* >= beta) set q* := beta-1. + Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2] + and c3 := b[n-2] * q*. + {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow + occurred. Furthermore 0 <= c3 < beta^2. + If there was overflow and + r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2, + the next test can be skipped.} + While c3 > c2, {Here 0 <= c2 < c3 < beta^2} + Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2]. + If q* > 0: + Put r := r - b * q* * beta^j. In detail: + [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]]. + hence: u:=0, for i:=0 to n-1 do + u := u + q* * b[i], + r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry), + u:=u div beta (+ 1, if carry in subtraction) + r[n+j]:=r[n+j]-u. + {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1 + < q* + 1 <= beta, + the carry u does not overflow.} + If a negative carry occurs, put q* := q* - 1 + and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]]. + Set q[j] := q*. + Normalise [q[m-n],..,q[0]]; this yields the quotient q. + Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the + rest r. + The room for q[j] can be allocated at the memory location of r[n+j]. + Finally, round-to-even: + Shift r left by 1 bit. + If r > b or if r = b and q[0] is odd, q := q+1. + */ + const mp_limb_t *a_ptr = a.limbs; + size_t a_len = a.nlimbs; + const mp_limb_t *b_ptr = b.limbs; + size_t b_len = b.nlimbs; + mp_limb_t *roomptr; + mp_limb_t *tmp_roomptr = NULL; + mp_limb_t *q_ptr; + size_t q_len; + mp_limb_t *r_ptr; + size_t r_len; + + /* Allocate room for a_len+2 digits. + (Need a_len+1 digits for the real division and 1 more digit for the + final rounding of q.) */ + roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); + if (roomptr == NULL) + return NULL; + + /* Normalise a. */ + while (a_len > 0 && a_ptr[a_len - 1] == 0) + a_len--; + + /* Normalise b. */ + for (;;) + { + if (b_len == 0) + /* Division by zero. */ + abort (); + if (b_ptr[b_len - 1] == 0) + b_len--; + else + break; + } + + /* Here m = a_len >= 0 and n = b_len > 0. */ + + if (a_len < b_len) + { + /* m beta^(m-2) <= a/b < beta^m */ + r_ptr = roomptr; + q_ptr = roomptr + 1; + { + mp_limb_t den = b_ptr[0]; + mp_limb_t remainder = 0; + const mp_limb_t *sourceptr = a_ptr + a_len; + mp_limb_t *destptr = q_ptr + a_len; + size_t count; + for (count = a_len; count > 0; count--) + { + mp_twolimb_t num = + ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr; + *--destptr = num / den; + remainder = num % den; + } + /* Normalise and store r. */ + if (remainder > 0) + { + r_ptr[0] = remainder; + r_len = 1; + } + else + r_len = 0; + /* Normalise q. */ + q_len = a_len; + if (q_ptr[q_len - 1] == 0) + q_len--; + } + } + else + { + /* n>1: multiple precision division. + beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==> + beta^(m-n-1) <= a/b < beta^(m-n+1). */ + /* Determine s. */ + size_t s; + { + mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ + s = 31; + if (msd >= 0x10000) + { + msd = msd >> 16; + s -= 16; + } + if (msd >= 0x100) + { + msd = msd >> 8; + s -= 8; + } + if (msd >= 0x10) + { + msd = msd >> 4; + s -= 4; + } + if (msd >= 0x4) + { + msd = msd >> 2; + s -= 2; + } + if (msd >= 0x2) + { + msd = msd >> 1; + s -= 1; + } + } + /* 0 <= s < GMP_LIMB_BITS. + Copy b, shifting it left by s bits. */ + if (s > 0) + { + tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t)); + if (tmp_roomptr == NULL) + { + free (roomptr); + return NULL; + } + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = tmp_roomptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + /* accu must be zero, since that was how s was determined. */ + if (accu != 0) + abort (); + } + b_ptr = tmp_roomptr; + } + /* Copy a, shifting it left by s bits, yields r. + Memory layout: + At the beginning: r = roomptr[0..a_len], + at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */ + r_ptr = roomptr; + if (s == 0) + { + memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t)); + r_ptr[a_len] = 0; + } + else + { + const mp_limb_t *sourceptr = a_ptr; + mp_limb_t *destptr = r_ptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = a_len; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + *destptr++ = (mp_limb_t) accu; + } + q_ptr = roomptr + b_len; + q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */ + { + size_t j = a_len - b_len; /* m-n */ + mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */ + mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */ + mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */ + ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd; + /* Division loop, traversed m-n+1 times. + j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */ + for (;;) + { + mp_limb_t q_star; + mp_limb_t c1; + if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */ + { + /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */ + mp_twolimb_t num = + ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS) + | r_ptr[j + b_len - 1]; + q_star = num / b_msd; + c1 = num % b_msd; + } + else + { + /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */ + q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */ + /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta + <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta + <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) + {<= beta !}. + If yes, jump directly to the subtraction loop. + (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta + <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */ + if (r_ptr[j + b_len] > b_msd + || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd) + /* r[j+n] >= b[n-1]+1 or + r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a + carry. */ + goto subtract; + } + /* q_star = q*, + c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, 0, decrease it by + b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2 + this can happen only twice. */ + if (c3 > c2) + { + q_star = q_star - 1; /* q* := q* - 1 */ + if (c3 - c2 > b_msdd) + q_star = q_star - 1; /* q* := q* - 1 */ + } + } + if (q_star > 0) + subtract: + { + /* Subtract r := r - b * q* * beta^j. */ + mp_limb_t cr; + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = r_ptr + j; + mp_twolimb_t carry = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + /* Here 0 <= carry <= q*. */ + carry = + carry + + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++ + + (mp_limb_t) ~(*destptr); + /* Here 0 <= carry <= beta*q* + beta-1. */ + *destptr++ = ~(mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; /* <= q* */ + } + cr = (mp_limb_t) carry; + } + /* Subtract cr from r_ptr[j + b_len], then forget about + r_ptr[j + b_len]. */ + if (cr > r_ptr[j + b_len]) + { + /* Subtraction gave a carry. */ + q_star = q_star - 1; /* q* := q* - 1 */ + /* Add b back. */ + { + const mp_limb_t *sourceptr = b_ptr; + mp_limb_t *destptr = r_ptr + j; + mp_limb_t carry = 0; + size_t count; + for (count = b_len; count > 0; count--) + { + mp_limb_t source1 = *sourceptr++; + mp_limb_t source2 = *destptr; + *destptr++ = source1 + source2 + carry; + carry = + (carry + ? source1 >= (mp_limb_t) ~source2 + : source1 > (mp_limb_t) ~source2); + } + } + /* Forget about the carry and about r[j+n]. */ + } + } + /* q* is determined. Store it as q[j]. */ + q_ptr[j] = q_star; + if (j == 0) + break; + j--; + } + } + r_len = b_len; + /* Normalise q. */ + if (q_ptr[q_len - 1] == 0) + q_len--; +# if 0 /* Not needed here, since we need r only to compare it with b/2, and + b is shifted left by s bits. */ + /* Shift r right by s bits. */ + if (s > 0) + { + mp_limb_t ptr = r_ptr + r_len; + mp_twolimb_t accu = 0; + size_t count; + for (count = r_len; count > 0; count--) + { + accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS; + accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s); + *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS); + } + } +# endif + /* Normalise r. */ + while (r_len > 0 && r_ptr[r_len - 1] == 0) + r_len--; + } + /* Compare r << 1 with b. */ + if (r_len > b_len) + goto increment_q; + { + size_t i; + for (i = b_len;;) + { + mp_limb_t r_i = + (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0) + | (i < r_len ? r_ptr[i] << 1 : 0); + mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0); + if (r_i > b_i) + goto increment_q; + if (r_i < b_i) + goto keep_q; + if (i == 0) + break; + i--; + } + } + if (q_len > 0 && ((q_ptr[0] & 1) != 0)) + /* q is odd. */ + increment_q: + { + size_t i; + for (i = 0; i < q_len; i++) + if (++(q_ptr[i]) != 0) + goto keep_q; + q_ptr[q_len++] = 1; + } + keep_q: + if (tmp_roomptr != NULL) + free (tmp_roomptr); + q->limbs = q_ptr; + q->nlimbs = q_len; + return roomptr; +} + +/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal + representation. + Destroys the contents of a. + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +convert_to_decimal (mpn_t a, size_t extra_zeroes) +{ + mp_limb_t *a_ptr = a.limbs; + size_t a_len = a.nlimbs; + /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ + size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); + char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); + if (c_ptr != NULL) + { + char *d_ptr = c_ptr; + for (; extra_zeroes > 0; extra_zeroes--) + *d_ptr++ = '0'; + while (a_len > 0) + { + /* Divide a by 10^9, in-place. */ + mp_limb_t remainder = 0; + mp_limb_t *ptr = a_ptr + a_len; + size_t count; + for (count = a_len; count > 0; count--) + { + mp_twolimb_t num = + ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr; + *ptr = num / 1000000000; + remainder = num % 1000000000; + } + /* Store the remainder as 9 decimal digits. */ + for (count = 9; count > 0; count--) + { + *d_ptr++ = '0' + (remainder % 10); + remainder = remainder / 10; + } + /* Normalize a. */ + if (a_ptr[a_len - 1] == 0) + a_len--; + } + /* Remove leading zeroes. */ + while (d_ptr > c_ptr && d_ptr[-1] == '0') + d_ptr--; + /* But keep at least one zero. */ + if (d_ptr == c_ptr) + *d_ptr++ = '0'; + /* Terminate the string. */ + *d_ptr = '\0'; + } + return c_ptr; +} + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and >= 0: + write x as x = 2^e * m, where m is a bignum. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +decode_long_double (long double x, int *ep, mpn_t *mp) +{ + mpn_t m; + int exp; + long double y; + size_t i; + + /* Allocate memory for result. */ + m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); + if (m.limbs == NULL) + return NULL; + /* Split into exponential part and mantissa. */ + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); + /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the + latter is an integer. */ + /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'long double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int', + doesn't matter). */ +# if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0 +# if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2)); + hi = (int) y; + y -= hi; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# else + { + mp_limb_t d; + y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS); + d = (int) y; + y -= d; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d; + } +# endif +# endif + for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + hi = (int) y; + y -= hi; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0L && y < 1.0L)) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess + precision. */ + if (!(y == 0.0L)) + abort (); +#endif + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; + *mp = m; + *ep = exp - LDBL_MANT_BIT; + return m.limbs; +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and >= 0: + write x as x = 2^e * m, where m is a bignum. + Return the allocated memory in case of success, NULL in case of memory + allocation failure. */ +static void * +decode_double (double x, int *ep, mpn_t *mp) +{ + mpn_t m; + int exp; + double y; + size_t i; + + /* Allocate memory for result. */ + m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; + m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); + if (m.limbs == NULL) + return NULL; + /* Split into exponential part and mantissa. */ + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); + /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the + latter is an integer. */ + /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'double' values between 0 and 2^16 (to 'unsigned int' or 'int', + doesn't matter). */ +# if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0 +# if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2)); + hi = (int) y; + y -= hi; + if (!(y >= 0.0 && y < 1.0)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +# else + { + mp_limb_t d; + y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS); + d = (int) y; + y -= d; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d; + } +# endif +# endif + for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) + { + mp_limb_t hi, lo; + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + hi = (int) y; + y -= hi; + if (!(y >= 0.0 && y < 1.0)) + abort (); + y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); + lo = (int) y; + y -= lo; + if (!(y >= 0.0 && y < 1.0)) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } + if (!(y == 0.0)) + abort (); + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; + *mp = m; + *ep = exp - DBL_MANT_BIT; + return m.limbs; +} + +# endif + +/* Assuming x = 2^e * m is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) +{ + int s; + size_t extra_zeroes; + unsigned int abs_n; + unsigned int abs_s; + mp_limb_t *pow5_ptr; + size_t pow5_len; + unsigned int s_limbs; + unsigned int s_bits; + mpn_t pow5; + mpn_t z; + void *z_memory; + char *digits; + + if (memory == NULL) + return NULL; + /* x = 2^e * m, hence + y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) + = round (2^s * 5^n * m). */ + s = e + n; + extra_zeroes = 0; + /* Factor out a common power of 10 if possible. */ + if (s > 0 && n > 0) + { + extra_zeroes = (s < n ? s : n); + s -= extra_zeroes; + n -= extra_zeroes; + } + /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes. + Before converting to decimal, we need to compute + z = round (2^s * 5^n * m). */ + /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same + sign. 2.322 is slightly larger than log(5)/log(2). */ + abs_n = (n >= 0 ? n : -n); + abs_s = (s >= 0 ? s : -s); + pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1 + + abs_s / GMP_LIMB_BITS + 1) + * sizeof (mp_limb_t)); + if (pow5_ptr == NULL) + { + free (memory); + return NULL; + } + /* Initialize with 1. */ + pow5_ptr[0] = 1; + pow5_len = 1; + /* Multiply with 5^|n|. */ + if (abs_n > 0) + { + static mp_limb_t const small_pow5[13 + 1] = + { + 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, + 48828125, 244140625, 1220703125 + }; + unsigned int n13; + for (n13 = 0; n13 <= abs_n; n13 += 13) + { + mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13]; + size_t j; + mp_twolimb_t carry = 0; + for (j = 0; j < pow5_len; j++) + { + mp_limb_t digit2 = pow5_ptr[j]; + carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; + pow5_ptr[j] = (mp_limb_t) carry; + carry = carry >> GMP_LIMB_BITS; + } + if (carry > 0) + pow5_ptr[pow5_len++] = (mp_limb_t) carry; + } + } + s_limbs = abs_s / GMP_LIMB_BITS; + s_bits = abs_s % GMP_LIMB_BITS; + if (n >= 0 ? s >= 0 : s <= 0) + { + /* Multiply with 2^|s|. */ + if (s_bits > 0) + { + mp_limb_t *ptr = pow5_ptr; + mp_twolimb_t accu = 0; + size_t count; + for (count = pow5_len; count > 0; count--) + { + accu += (mp_twolimb_t) *ptr << s_bits; + *ptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + if (accu > 0) + { + *ptr = (mp_limb_t) accu; + pow5_len++; + } + } + if (s_limbs > 0) + { + size_t count; + for (count = pow5_len; count > 0;) + { + count--; + pow5_ptr[s_limbs + count] = pow5_ptr[count]; + } + for (count = s_limbs; count > 0;) + { + count--; + pow5_ptr[count] = 0; + } + pow5_len += s_limbs; + } + pow5.limbs = pow5_ptr; + pow5.nlimbs = pow5_len; + if (n >= 0) + { + /* Multiply m with pow5. No division needed. */ + z_memory = multiply (m, pow5, &z); + } + else + { + /* Divide m by pow5 and round. */ + z_memory = divide (m, pow5, &z); + } + } + else + { + pow5.limbs = pow5_ptr; + pow5.nlimbs = pow5_len; + if (n >= 0) + { + /* n >= 0, s < 0. + Multiply m with pow5, then divide by 2^|s|. */ + mpn_t numerator; + mpn_t denominator; + void *tmp_memory; + tmp_memory = multiply (m, pow5, &numerator); + if (tmp_memory == NULL) + { + free (pow5_ptr); + free (memory); + return NULL; + } + /* Construct 2^|s|. */ + { + mp_limb_t *ptr = pow5_ptr + pow5_len; + size_t i; + for (i = 0; i < s_limbs; i++) + ptr[i] = 0; + ptr[s_limbs] = (mp_limb_t) 1 << s_bits; + denominator.limbs = ptr; + denominator.nlimbs = s_limbs + 1; + } + z_memory = divide (numerator, denominator, &z); + free (tmp_memory); + } + else + { + /* n < 0, s > 0. + Multiply m with 2^s, then divide by pow5. */ + mpn_t numerator; + mp_limb_t *num_ptr; + num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1) + * sizeof (mp_limb_t)); + if (num_ptr == NULL) + { + free (pow5_ptr); + free (memory); + return NULL; + } + { + mp_limb_t *destptr = num_ptr; + { + size_t i; + for (i = 0; i < s_limbs; i++) + *destptr++ = 0; + } + if (s_bits > 0) + { + const mp_limb_t *sourceptr = m.limbs; + mp_twolimb_t accu = 0; + size_t count; + for (count = m.nlimbs; count > 0; count--) + { + accu += (mp_twolimb_t) *sourceptr++ << s_bits; + *destptr++ = (mp_limb_t) accu; + accu = accu >> GMP_LIMB_BITS; + } + if (accu > 0) + *destptr++ = (mp_limb_t) accu; + } + else + { + const mp_limb_t *sourceptr = m.limbs; + size_t count; + for (count = m.nlimbs; count > 0; count--) + *destptr++ = *sourceptr++; + } + numerator.limbs = num_ptr; + numerator.nlimbs = destptr - num_ptr; + } + z_memory = divide (numerator, pow5, &z); + free (num_ptr); + } + } + free (pow5_ptr); + free (memory); + + /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ + + if (z_memory == NULL) + return NULL; + digits = convert_to_decimal (z, extra_zeroes); + free (z_memory); + return digits; +} + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_long_double (long double x, int n) +{ + int e IF_LINT(= 0); + mpn_t m; + void *memory = decode_long_double (x, &e, &m); + return scale10_round_decimal_decoded (e, m, memory, n); +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and >= 0, and n is an integer: + Returns the decimal representation of round (x * 10^n). + Return the allocated memory - containing the decimal digits in low-to-high + order, terminated with a NUL character - in case of success, NULL in case + of memory allocation failure. */ +static char * +scale10_round_decimal_double (double x, int n) +{ + int e IF_LINT(= 0); + mpn_t m; + void *memory = decode_double (x, &e, &m); + return scale10_round_decimal_decoded (e, m, memory, n); +} + +# endif + +# if NEED_PRINTF_LONG_DOUBLE + +/* Assuming x is finite and > 0: + Return an approximation for n with 10^n <= x < 10^(n+1). + The approximation is usually the right n, but may be off by 1 sometimes. */ +static int +floorlog10l (long double x) +{ + int exp; + long double y; + double z; + double l; + + /* Split into exponential part and mantissa. */ + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); + if (y == 0.0L) + return INT_MIN; + if (y < 0.5L) + { + while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) + { + y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); + exp -= GMP_LIMB_BITS; + } + if (y < (1.0L / (1 << 16))) + { + y *= 1.0L * (1 << 16); + exp -= 16; + } + if (y < (1.0L / (1 << 8))) + { + y *= 1.0L * (1 << 8); + exp -= 8; + } + if (y < (1.0L / (1 << 4))) + { + y *= 1.0L * (1 << 4); + exp -= 4; + } + if (y < (1.0L / (1 << 2))) + { + y *= 1.0L * (1 << 2); + exp -= 2; + } + if (y < (1.0L / (1 << 1))) + { + y *= 1.0L * (1 << 1); + exp -= 1; + } + } + if (!(y >= 0.5L && y < 1.0L)) + abort (); + /* Compute an approximation for l = log2(x) = exp + log2(y). */ + l = exp; + z = y; + if (z < 0.70710678118654752444) + { + z *= 1.4142135623730950488; + l -= 0.5; + } + if (z < 0.8408964152537145431) + { + z *= 1.1892071150027210667; + l -= 0.25; + } + if (z < 0.91700404320467123175) + { + z *= 1.0905077326652576592; + l -= 0.125; + } + if (z < 0.9576032806985736469) + { + z *= 1.0442737824274138403; + l -= 0.0625; + } + /* Now 0.95 <= z <= 1.01. */ + z = 1 - z; + /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) + Four terms are enough to get an approximation with error < 10^-7. */ + l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); + /* Finally multiply with log(2)/log(10), yields an approximation for + log10(x). */ + l *= 0.30102999566398119523; + /* Round down to the next integer. */ + return (int) l + (l < 0 ? -1 : 0); +} + +# endif + +# if NEED_PRINTF_DOUBLE + +/* Assuming x is finite and > 0: + Return an approximation for n with 10^n <= x < 10^(n+1). + The approximation is usually the right n, but may be off by 1 sometimes. */ +static int +floorlog10 (double x) +{ + int exp; + double y; + double z; + double l; + + /* Split into exponential part and mantissa. */ + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); + if (y == 0.0) + return INT_MIN; + if (y < 0.5) + { + while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) + { + y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); + exp -= GMP_LIMB_BITS; + } + if (y < (1.0 / (1 << 16))) + { + y *= 1.0 * (1 << 16); + exp -= 16; + } + if (y < (1.0 / (1 << 8))) + { + y *= 1.0 * (1 << 8); + exp -= 8; + } + if (y < (1.0 / (1 << 4))) + { + y *= 1.0 * (1 << 4); + exp -= 4; + } + if (y < (1.0 / (1 << 2))) + { + y *= 1.0 * (1 << 2); + exp -= 2; + } + if (y < (1.0 / (1 << 1))) + { + y *= 1.0 * (1 << 1); + exp -= 1; + } + } + if (!(y >= 0.5 && y < 1.0)) + abort (); + /* Compute an approximation for l = log2(x) = exp + log2(y). */ + l = exp; + z = y; + if (z < 0.70710678118654752444) + { + z *= 1.4142135623730950488; + l -= 0.5; + } + if (z < 0.8408964152537145431) + { + z *= 1.1892071150027210667; + l -= 0.25; + } + if (z < 0.91700404320467123175) + { + z *= 1.0905077326652576592; + l -= 0.125; + } + if (z < 0.9576032806985736469) + { + z *= 1.0442737824274138403; + l -= 0.0625; + } + /* Now 0.95 <= z <= 1.01. */ + z = 1 - z; + /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) + Four terms are enough to get an approximation with error < 10^-7. */ + l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); + /* Finally multiply with log(2)/log(10), yields an approximation for + log10(x). */ + l *= 0.30102999566398119523; + /* Round down to the next integer. */ + return (int) l + (l < 0 ? -1 : 0); +} + +# endif + +/* Tests whether a string of digits consists of exactly PRECISION zeroes and + a single '1' digit. */ +static int +is_borderline (const char *digits, size_t precision) +{ + for (; precision > 0; precision--, digits++) + if (*digits != '0') + return 0; + if (*digits != '1') + return 0; + digits++; + return *digits == '\0'; +} + +#endif + +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 + +/* Use a different function name, to make it possible that the 'wchar_t' + parametrization and the 'char' parametrization get compiled in the same + translation unit. */ +# if WIDE_CHAR_VERSION +# define MAX_ROOM_NEEDED wmax_room_needed +# else +# define MAX_ROOM_NEEDED max_room_needed +# endif + +/* Returns the number of TCHAR_T units needed as temporary space for the result + of sprintf or SNPRINTF of a single conversion directive. */ +static inline size_t +MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, + arg_type type, int flags, size_t width, int has_precision, + size_t precision, int pad_ourselves) +{ + size_t tmp_length; + + switch (conversion) + { + case 'd': case 'i': case 'u': +# if HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.30103 /* binary -> decimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Multiply by 2, as an estimate for FLAG_GROUP. */ + tmp_length = xsum (tmp_length, tmp_length); + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); + break; + + case 'o': +# if HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.333334 /* binary -> octal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 1, to account for a leading sign. */ + tmp_length = xsum (tmp_length, 1); + break; + + case 'x': case 'X': +# if HAVE_LONG_LONG_INT + if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long long) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else +# endif + if (type == TYPE_LONGINT || type == TYPE_ULONGINT) + tmp_length = + (unsigned int) (sizeof (unsigned long) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (sizeof (unsigned int) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Add 2, to account for a leading sign or alternate form. */ + tmp_length = xsum (tmp_length, 2); + break; + + case 'f': case 'F': + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) (LDBL_MAX_EXP + * 0.30103 /* binary -> decimal */ + * 2 /* estimate for FLAG_GROUP */ + ) + + 1 /* turn floor into ceil */ + + 10; /* sign, decimal point etc. */ + else + tmp_length = + (unsigned int) (DBL_MAX_EXP + * 0.30103 /* binary -> decimal */ + * 2 /* estimate for FLAG_GROUP */ + ) + + 1 /* turn floor into ceil */ + + 10; /* sign, decimal point etc. */ + tmp_length = xsum (tmp_length, precision); + break; + + case 'e': case 'E': case 'g': case 'G': + tmp_length = + 12; /* sign, decimal point, exponent etc. */ + tmp_length = xsum (tmp_length, precision); + break; + + case 'a': case 'A': + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) (LDBL_DIG + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) (DBL_DIG + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + break; + + case 'c': +# if HAVE_WINT_T && !WIDE_CHAR_VERSION + if (type == TYPE_WIDE_CHAR) + tmp_length = MB_CUR_MAX; + else +# endif + tmp_length = 1; + break; + + case 's': +# if HAVE_WCHAR_T + if (type == TYPE_WIDE_STRING) + { +# if WIDE_CHAR_VERSION + /* ISO C says about %ls in fwprintf: + "If the precision is not specified or is greater than the size + of the array, the array shall contain a null wide character." + So if there is a precision, we must not use wcslen. */ + const wchar_t *arg = ap->arg[arg_index].a.a_wide_string; + + if (has_precision) + tmp_length = local_wcsnlen (arg, precision); + else + tmp_length = local_wcslen (arg); +# else + /* ISO C says about %ls in fprintf: + "If a precision is specified, no more than that many bytes are + written (including shift sequences, if any), and the array + shall contain a null wide character if, to equal the multibyte + character sequence length given by the precision, the function + would need to access a wide character one past the end of the + array." + So if there is a precision, we must not use wcslen. */ + /* This case has already been handled separately in VASNPRINTF. */ + abort (); +# endif + } + else +# endif + { +# if WIDE_CHAR_VERSION + /* ISO C says about %s in fwprintf: + "If the precision is not specified or is greater than the size + of the converted array, the converted array shall contain a + null wide character." + So if there is a precision, we must not use strlen. */ + /* This case has already been handled separately in VASNPRINTF. */ + abort (); +# else + /* ISO C says about %s in fprintf: + "If the precision is not specified or greater than the size of + the array, the array shall contain a null character." + So if there is a precision, we must not use strlen. */ + const char *arg = ap->arg[arg_index].a.a_string; + + if (has_precision) + tmp_length = local_strnlen (arg, precision); + else + tmp_length = strlen (arg); +# endif + } + break; + + case 'p': + tmp_length = + (unsigned int) (sizeof (void *) * CHAR_BIT + * 0.25 /* binary -> hexadecimal */ + ) + + 1 /* turn floor into ceil */ + + 2; /* account for leading 0x */ + break; + + default: + abort (); + } + + if (!pad_ourselves) + { +# if ENABLE_UNISTDIO + /* Padding considers the number of characters, therefore the number of + elements after padding may be + > max (tmp_length, width) + but is certainly + <= tmp_length + width. */ + tmp_length = xsum (tmp_length, width); +# else + /* Padding considers the number of elements, says POSIX. */ + if (tmp_length < width) + tmp_length = width; +# endif + } + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + return tmp_length; +} + +#endif + +DCHAR_T * +VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + const FCHAR_T *format, va_list args) +{ + DIRECTIVES d; + arguments a; + + if (PRINTF_PARSE (format, &d, &a) < 0) + /* errno is already set. */ + return NULL; + +#define CLEANUP() \ + free (d.dir); \ + if (a.arg) \ + free (a.arg); + + if (PRINTF_FETCHARGS (args, &a) < 0) + { + CLEANUP (); + errno = EINVAL; + return NULL; + } + + { + size_t buf_neededlength; + TCHAR_T *buf; + TCHAR_T *buf_malloced; + const FCHAR_T *cp; + size_t i; + DIRECTIVE *dp; + /* Output string accumulator. */ + DCHAR_T *result; + size_t allocated; + size_t length; + + /* Allocate a small buffer that will hold a directive passed to + sprintf or snprintf. */ + buf_neededlength = + xsum4 (7, d.max_width_length, d.max_precision_length, 6); +#if HAVE_ALLOCA + if (buf_neededlength < 4000 / sizeof (TCHAR_T)) + { + buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T)); + buf_malloced = NULL; + } + else +#endif + { + size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T)); + if (size_overflow_p (buf_memsize)) + goto out_of_memory_1; + buf = (TCHAR_T *) malloc (buf_memsize); + if (buf == NULL) + goto out_of_memory_1; + buf_malloced = buf; + } + + if (resultbuf != NULL) + { + result = resultbuf; + allocated = *lengthp; + } + else + { + result = NULL; + allocated = 0; + } + length = 0; + /* Invariants: + result is either == resultbuf or == NULL or malloc-allocated. + If length > 0, then result != NULL. */ + + /* Ensures that allocated >= needed. Aborts through a jump to + out_of_memory if needed is SIZE_MAX or otherwise too big. */ +#define ENSURE_ALLOCATION(needed) \ + if ((needed) > allocated) \ + { \ + size_t memory_size; \ + DCHAR_T *memory; \ + \ + allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \ + if ((needed) > allocated) \ + allocated = (needed); \ + memory_size = xtimes (allocated, sizeof (DCHAR_T)); \ + if (size_overflow_p (memory_size)) \ + goto out_of_memory; \ + if (result == resultbuf || result == NULL) \ + memory = (DCHAR_T *) malloc (memory_size); \ + else \ + memory = (DCHAR_T *) realloc (result, memory_size); \ + if (memory == NULL) \ + goto out_of_memory; \ + if (result == resultbuf && length > 0) \ + DCHAR_CPY (memory, result, length); \ + result = memory; \ + } + + for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) + { + if (cp != dp->dir_start) + { + size_t n = dp->dir_start - cp; + size_t augmented_length = xsum (length, n); + + ENSURE_ALLOCATION (augmented_length); + /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we + need that the format string contains only ASCII characters + if FCHAR_T and DCHAR_T are not the same type. */ + if (sizeof (FCHAR_T) == sizeof (DCHAR_T)) + { + DCHAR_CPY (result + length, (const DCHAR_T *) cp, n); + length = augmented_length; + } + else + { + do + result[length++] = (unsigned char) *cp++; + while (--n > 0); + } + } + if (i == d.count) + break; + + /* Execute a single directive. */ + if (dp->conversion == '%') + { + size_t augmented_length; + + if (!(dp->arg_index == ARG_NONE)) + abort (); + augmented_length = xsum (length, 1); + ENSURE_ALLOCATION (augmented_length); + result[length] = '%'; + length = augmented_length; + } + else + { + if (!(dp->arg_index != ARG_NONE)) + abort (); + + if (dp->conversion == 'n') + { + switch (a.arg[dp->arg_index].type) + { + case TYPE_COUNT_SCHAR_POINTER: + *a.arg[dp->arg_index].a.a_count_schar_pointer = length; + break; + case TYPE_COUNT_SHORT_POINTER: + *a.arg[dp->arg_index].a.a_count_short_pointer = length; + break; + case TYPE_COUNT_INT_POINTER: + *a.arg[dp->arg_index].a.a_count_int_pointer = length; + break; + case TYPE_COUNT_LONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longint_pointer = length; + break; +#if HAVE_LONG_LONG_INT + case TYPE_COUNT_LONGLONGINT_POINTER: + *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; + break; +#endif + default: + abort (); + } + } +#if ENABLE_UNISTDIO + /* The unistdio extensions. */ + else if (dp->conversion == 'U') + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + switch (type) + { + case TYPE_U8_STRING: + { + const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string; + const uint8_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u8_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u8_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u8_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT8_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-8 to locale encoding. */ + converted = + u8_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-8 to UTF-16/UTF-32. */ + converted = + U8_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + case TYPE_U16_STRING: + { + const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string; + const uint16_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u16_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u16_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u16_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT16_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-16 to locale encoding. */ + converted = + u16_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-16 to UTF-8/UTF-32. */ + converted = + U16_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + case TYPE_U32_STRING: + { + const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string; + const uint32_t *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only PRECISION characters, from the left. */ + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count = u32_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of + characters. */ + arg_end = arg; + characters = 0; + for (;;) + { + int count = u32_strmblen (arg_end); + if (count == 0) + break; + if (count < 0) + { + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + u32_strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_UINT32_T + { + size_t n = arg_end - arg; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_CPY (result + length, arg, n); + length += n; + } +# else + { /* Convert. */ + DCHAR_T *converted = result + length; + size_t converted_len = allocated - length; +# if DCHAR_IS_TCHAR + /* Convert from UTF-32 to locale encoding. */ + converted = + u32_conv_to_encoding (locale_charset (), + iconveh_question_mark, + arg, arg_end - arg, NULL, + converted, &converted_len); +# else + /* Convert from UTF-32 to UTF-8/UTF-16. */ + converted = + U32_TO_DCHAR (arg, arg_end - arg, + converted, &converted_len); +# endif + if (converted == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + if (converted != result + length) + { + ENSURE_ALLOCATION (xsum (length, converted_len)); + DCHAR_CPY (result + length, converted, converted_len); + free (converted); + } + length += converted_len; + } +# endif + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } + break; + + default: + abort (); + } + } +#endif +#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T + else if (dp->conversion == 's' +# if WIDE_CHAR_VERSION + && a.arg[dp->arg_index].type != TYPE_WIDE_STRING +# else + && a.arg[dp->arg_index].type == TYPE_WIDE_STRING +# endif + ) + { + /* The normal handling of the 's' directive below requires + allocating a temporary buffer. The determination of its + length (tmp_length), in the case when a precision is + specified, below requires a conversion between a char[] + string and a wchar_t[] wide string. It could be done, but + we have no guarantee that the implementation of sprintf will + use the exactly same algorithm. Without this guarantee, it + is possible to have buffer overrun bugs. In order to avoid + such bugs, we implement the entire processing of the 's' + directive ourselves. */ + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + +# if WIDE_CHAR_VERSION + /* %s in vasnwprintf. See the specification of fwprintf. */ + { + const char *arg = a.arg[dp->arg_index].a.a_string; + const char *arg_end; + size_t characters; + + if (has_precision) + { + /* Use only as many bytes as needed to produce PRECISION + wide characters, from the left. */ +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (; precision > 0; precision--) + { + int count; +# if HAVE_MBRTOWC + count = mbrlen (arg_end, MB_CUR_MAX, &state); +# else + count = mblen (arg_end, MB_CUR_MAX); +# endif + if (count == 0) + /* Found the terminating NUL. */ + break; + if (count < 0) + { + /* Invalid or incomplete multibyte character. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else if (has_width) + { + /* Use the entire string, and count the number of wide + characters. */ +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (;;) + { + int count; +# if HAVE_MBRTOWC + count = mbrlen (arg_end, MB_CUR_MAX, &state); +# else + count = mblen (arg_end, MB_CUR_MAX); +# endif + if (count == 0) + /* Found the terminating NUL. */ + break; + if (count < 0) + { + /* Invalid or incomplete multibyte character. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end += count; + characters++; + } + } + else + { + /* Use the entire string. */ + arg_end = arg + strlen (arg); + /* The number of characters doesn't matter. */ + characters = 0; + } + + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + + if (has_precision || has_width) + { + /* We know the number of wide characters in advance. */ + size_t remaining; +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + ENSURE_ALLOCATION (xsum (length, characters)); + for (remaining = characters; remaining > 0; remaining--) + { + wchar_t wc; + int count; +# if HAVE_MBRTOWC + count = mbrtowc (&wc, arg, arg_end - arg, &state); +# else + count = mbtowc (&wc, arg, arg_end - arg); +# endif + if (count <= 0) + /* mbrtowc not consistent with mbrlen, or mbtowc + not consistent with mblen. */ + abort (); + result[length++] = wc; + arg += count; + } + if (!(arg == arg_end)) + abort (); + } + else + { +# if HAVE_MBRTOWC + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + while (arg < arg_end) + { + wchar_t wc; + int count; +# if HAVE_MBRTOWC + count = mbrtowc (&wc, arg, arg_end - arg, &state); +# else + count = mbtowc (&wc, arg, arg_end - arg); +# endif + if (count <= 0) + /* mbrtowc not consistent with mbrlen, or mbtowc + not consistent with mblen. */ + abort (); + ENSURE_ALLOCATION (xsum (length, 1)); + result[length++] = wc; + arg += count; + } + } + + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - characters; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } +# else + /* %ls in vasnprintf. See the specification of fprintf. */ + { + const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; + const wchar_t *arg_end; + size_t characters; +# if !DCHAR_IS_TCHAR + /* This code assumes that TCHAR_T is 'char'. */ + typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1]; + TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; +# endif + size_t w; + + if (has_precision) + { + /* Use only as many wide characters as needed to produce + at most PRECISION bytes, from the left. */ +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + while (precision > 0) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg_end == 0) + /* Found the terminating null wide character. */ + break; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg_end, &state); +# else + count = wctomb (cbuf, *arg_end); +# endif + if (count < 0) + { + /* Cannot convert. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + if (precision < count) + break; + arg_end++; + characters += count; + precision -= count; + } + } +# if DCHAR_IS_TCHAR + else if (has_width) +# else + else +# endif + { + /* Use the entire string, and count the number of + bytes. */ +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + arg_end = arg; + characters = 0; + for (;;) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg_end == 0) + /* Found the terminating null wide character. */ + break; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg_end, &state); +# else + count = wctomb (cbuf, *arg_end); +# endif + if (count < 0) + { + /* Cannot convert. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + arg_end++; + characters += count; + } + } +# if DCHAR_IS_TCHAR + else + { + /* Use the entire string. */ + arg_end = arg + local_wcslen (arg); + /* The number of bytes doesn't matter. */ + characters = 0; + } +# endif + +# if !DCHAR_IS_TCHAR + /* Convert the string into a piece of temporary memory. */ + tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T)); + if (tmpsrc == NULL) + goto out_of_memory; + { + TCHAR_T *tmpptr = tmpsrc; + size_t remaining; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + for (remaining = characters; remaining > 0; ) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg, &state); +# else + count = wctomb (cbuf, *arg); +# endif + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (tmpptr, cbuf, count); + tmpptr += count; + arg++; + remaining -= count; + } + if (!(arg == arg_end)) + abort (); + } + + /* Convert from TCHAR_T[] to DCHAR_T[]. */ + tmpdst = + DCHAR_CONV_FROM_ENCODING (locale_charset (), + iconveh_question_mark, + tmpsrc, characters, + NULL, + NULL, &tmpdst_len); + if (tmpdst == NULL) + { + int saved_errno = errno; + free (tmpsrc); + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + free (tmpsrc); +# endif + + if (has_width) + { +# if ENABLE_UNISTDIO + /* Outside POSIX, it's preferrable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, characters); +# else + /* The width is compared against the number of _bytes_ + of the converted value, says POSIX. */ + w = characters; +# endif + } + else + /* w doesn't matter. */ + w = 0; + + if (has_width && width > w + && !(dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + +# if DCHAR_IS_TCHAR + if (has_precision || has_width) + { + /* We know the number of bytes in advance. */ + size_t remaining; +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + ENSURE_ALLOCATION (xsum (length, characters)); + for (remaining = characters; remaining > 0; ) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg, &state); +# else + count = wctomb (cbuf, *arg); +# endif + if (count <= 0) + /* Inconsistency. */ + abort (); + memcpy (result + length, cbuf, count); + length += count; + arg++; + remaining -= count; + } + if (!(arg == arg_end)) + abort (); + } + else + { +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + mbstate_t state; + memset (&state, '\0', sizeof (mbstate_t)); +# endif + while (arg < arg_end) + { + char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ + int count; + + if (*arg == 0) + abort (); +# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t + count = wcrtomb (cbuf, *arg, &state); +# else + count = wctomb (cbuf, *arg); +# endif + if (count <= 0) + { + /* Cannot convert. */ + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EILSEQ; + return NULL; + } + ENSURE_ALLOCATION (xsum (length, count)); + memcpy (result + length, cbuf, count); + length += count; + arg++; + } + } +# else + ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + DCHAR_CPY (result + length, tmpdst, tmpdst_len); + free (tmpdst); + length += tmpdst_len; +# endif + + if (has_width && width > w + && (dp->flags & FLAG_LEFT)) + { + size_t n = width - w; + ENSURE_ALLOCATION (xsum (length, n)); + DCHAR_SET (result + length, ' ', n); + length += n; + } + } +# endif + } +#endif +#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL + else if ((dp->conversion == 'a' || dp->conversion == 'A') +# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE)) + && (0 +# if NEED_PRINTF_DOUBLE + || a.arg[dp->arg_index].type == TYPE_DOUBLE +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# endif + ) +# endif + ) + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + /* Allocate a temporary buffer of sufficient size. */ + if (type == TYPE_LONGDOUBLE) + tmp_length = + (unsigned int) ((LDBL_DIG + 1) + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + else + tmp_length = + (unsigned int) ((DBL_DIG + 1) + * 0.831 /* decimal -> hexadecimal */ + ) + + 1; /* turn floor into ceil */ + if (tmp_length < precision) + tmp_length = precision; + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + + if (tmp_length < width) + tmp_length = width; + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (DCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } + + pad_ptr = NULL; + p = tmp; + if (type == TYPE_LONGDOUBLE) + { +# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE + long double arg = a.arg[dp->arg_index].a.a_longdouble; + + if (isnanl (arg)) + { + if (dp->conversion == 'A') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion == 'A') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + int exponent; + long double mantissa; + + if (arg > 0.0L) + mantissa = printf_frexpl (arg, &exponent); + else + { + exponent = 0; + mantissa = 0.0L; + } + + if (has_precision + && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1) + { + /* Round the mantissa. */ + long double tail = mantissa; + size_t q; + + for (q = precision; ; q--) + { + int digit = (int) tail; + tail -= digit; + if (q == 0) + { + if (digit & 1 ? tail >= 0.5L : tail > 0.5L) + tail = 1 - tail; + else + tail = - tail; + break; + } + tail *= 16.0L; + } + if (tail != 0.0L) + for (q = precision; q > 0; q--) + tail *= 0.0625L; + mantissa += tail; + } + + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + { + int digit; + + digit = (int) mantissa; + mantissa -= digit; + *p++ = '0' + digit; + if ((flags & FLAG_ALT) + || mantissa > 0.0L || precision > 0) + { + *p++ = decimal_point_char (); + /* This loop terminates because we assume + that FLT_RADIX is a power of 2. */ + while (mantissa > 0.0L) + { + mantissa *= 16.0L; + digit = (int) mantissa; + mantissa -= digit; + *p++ = digit + + (digit < 10 + ? '0' + : dp->conversion - 10); + if (precision > 0) + precision--; + } + while (precision > 0) + { + *p++ = '0'; + precision--; + } + } + } + *p++ = dp->conversion - 'A' + 'P'; +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + + END_LONG_DOUBLE_ROUNDING (); + } +# else + abort (); +# endif + } + else + { +# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnand (arg)) + { + if (dp->conversion == 'A') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0 or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion == 'A') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { + int exponent; + double mantissa; + + if (arg > 0.0) + mantissa = printf_frexp (arg, &exponent); + else + { + exponent = 0; + mantissa = 0.0; + } + + if (has_precision + && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1) + { + /* Round the mantissa. */ + double tail = mantissa; + size_t q; + + for (q = precision; ; q--) + { + int digit = (int) tail; + tail -= digit; + if (q == 0) + { + if (digit & 1 ? tail >= 0.5 : tail > 0.5) + tail = 1 - tail; + else + tail = - tail; + break; + } + tail *= 16.0; + } + if (tail != 0.0) + for (q = precision; q > 0; q--) + tail *= 0.0625; + mantissa += tail; + } + + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + { + int digit; + + digit = (int) mantissa; + mantissa -= digit; + *p++ = '0' + digit; + if ((flags & FLAG_ALT) + || mantissa > 0.0 || precision > 0) + { + *p++ = decimal_point_char (); + /* This loop terminates because we assume + that FLT_RADIX is a power of 2. */ + while (mantissa > 0.0) + { + mantissa *= 16.0; + digit = (int) mantissa; + mantissa -= digit; + *p++ = digit + + (digit < 10 + ? '0' + : dp->conversion - 10); + if (precision > 0) + precision--; + } + while (precision > 0) + { + *p++ = '0'; + precision--; + } + } + } + *p++ = dp->conversion - 'A' + 'P'; +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + } +# else + abort (); +# endif + } + /* The generated string now extends from tmp to p, with the + zero padding insertion point being at pad_ptr. */ + if (has_width && p - tmp < width) + { + size_t pad = width - (p - tmp); + DCHAR_T *end = p + pad; + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > tmp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + + p = end; + } + + { + size_t count = p - tmp; + + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); + + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); + + ENSURE_ALLOCATION (n); + } + + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; + } + } +#endif +#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL + else if ((dp->conversion == 'f' || dp->conversion == 'F' + || dp->conversion == 'e' || dp->conversion == 'E' + || dp->conversion == 'g' || dp->conversion == 'G' + || dp->conversion == 'a' || dp->conversion == 'A') + && (0 +# if NEED_PRINTF_DOUBLE + || a.arg[dp->arg_index].type == TYPE_DOUBLE +# elif NEED_PRINTF_INFINITE_DOUBLE + || (a.arg[dp->arg_index].type == TYPE_DOUBLE + /* The systems (mingw) which produce wrong output + for Inf, -Inf, and NaN also do so for -0.0. + Therefore we treat this case here as well. */ + && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double)) +# endif +# if NEED_PRINTF_LONG_DOUBLE + || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE +# elif NEED_PRINTF_INFINITE_LONG_DOUBLE + || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE + /* Some systems produce wrong output for Inf, + -Inf, and NaN. Some systems in this category + (IRIX 5.3) also do so for -0.0. Therefore we + treat this case here as well. */ + && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble)) +# endif + )) + { +# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) + arg_type type = a.arg[dp->arg_index].type; +# endif + int flags = dp->flags; + int has_width; + size_t width; + int has_precision; + size_t precision; + size_t tmp_length; + DCHAR_T tmpbuf[700]; + DCHAR_T *tmp; + DCHAR_T *pad_ptr; + DCHAR_T *p; + + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } + + has_precision = 0; + precision = 0; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } + + /* POSIX specifies the default precision to be 6 for %f, %F, + %e, %E, but not for %g, %G. Implementations appear to use + the same default precision also for %g, %G. But for %a, %A, + the default precision is 0. */ + if (!has_precision) + if (!(dp->conversion == 'a' || dp->conversion == 'A')) + precision = 6; + + /* Allocate a temporary buffer of sufficient size. */ +# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1); +# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE + tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0); +# elif NEED_PRINTF_LONG_DOUBLE + tmp_length = LDBL_DIG + 1; +# elif NEED_PRINTF_DOUBLE + tmp_length = DBL_DIG + 1; +# else + tmp_length = 0; +# endif + if (tmp_length < precision) + tmp_length = precision; +# if NEED_PRINTF_LONG_DOUBLE +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + if (type == TYPE_LONGDOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + if (!(isnanl (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10l (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } + } +# endif +# if NEED_PRINTF_DOUBLE +# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE + if (type == TYPE_DOUBLE) +# endif + if (dp->conversion == 'f' || dp->conversion == 'F') + { + double arg = a.arg[dp->arg_index].a.a_double; + if (!(isnand (arg) || arg + arg == arg)) + { + /* arg is finite and nonzero. */ + int exponent = floorlog10 (arg < 0 ? -arg : arg); + if (exponent >= 0 && tmp_length < exponent + precision) + tmp_length = exponent + precision; + } + } +# endif + /* Account for sign, decimal point etc. */ + tmp_length = xsum (tmp_length, 12); + + if (tmp_length < width) + tmp_length = width; + + tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ + + if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (DCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } + + pad_ptr = NULL; + p = tmp; + +# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + if (type == TYPE_LONGDOUBLE) +# endif + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + + if (isnanl (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + DECL_LONG_DOUBLE_ROUNDING + + BEGIN_LONG_DOUBLE_ROUNDING (); + + if (signbit (arg)) /* arg < 0.0L or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0L && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { +# if NEED_PRINTF_LONG_DOUBLE + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + char *digits; + size_t ndigits; + + digits = + scale10_round_decimal_long_double (arg, precision); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + int exponent; + + if (arg == 0.0L) + { + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else + { + /* arg > 0.0L. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)precision - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision+1. */ + if (is_borderline (digits, precision)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_long_double (arg, + (int)precision - exponent + 1); + if (digits2 == NULL) + { + free (digits); + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + if (strlen (digits2) == precision + 1) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision+1. */ + + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+.2d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+.2d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0L) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ + { + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = '0'; + } + } + } + else + { + /* arg > 0.0L. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10l (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + { + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + if (is_borderline (digits, precision - 1)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_long_double (arg, + (int)(precision - 1) - exponent + 1); + if (digits2 == NULL) + { + free (digits); + END_LONG_DOUBLE_ROUNDING (); + goto out_of_memory; + } + if (strlen (digits2) == precision) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + { '%', '+', '.', '2', 'd', '\0' }; + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, "%+.2d", exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, "%+.2d", exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } +# endif + } + + free (digits); + } + } + else + abort (); +# else + /* arg is finite. */ + if (!(arg == 0.0L)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else if (dp->conversion == 'a' || dp->conversion == 'A') + { + *p++ = '0'; + *p++ = dp->conversion - 'A' + 'X'; + pad_ptr = p; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion - 'A' + 'P'; + *p++ = '+'; + *p++ = '0'; + } + else + abort (); +# endif + } + + END_LONG_DOUBLE_ROUNDING (); + } + } +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + else +# endif +# endif +# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE + { + double arg = a.arg[dp->arg_index].a.a_double; + + if (isnand (arg)) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; + } + else + { + *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; + } + } + else + { + int sign = 0; + + if (signbit (arg)) /* arg < 0.0 or negative zero */ + { + sign = -1; + arg = -arg; + } + + if (sign < 0) + *p++ = '-'; + else if (flags & FLAG_SHOWSIGN) + *p++ = '+'; + else if (flags & FLAG_SPACE) + *p++ = ' '; + + if (arg > 0.0 && arg + arg == arg) + { + if (dp->conversion >= 'A' && dp->conversion <= 'Z') + { + *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; + } + else + { + *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; + } + } + else + { +# if NEED_PRINTF_DOUBLE + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + char *digits; + size_t ndigits; + + digits = + scale10_round_decimal_double (arg, precision); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits > precision) + do + { + --ndigits; + *p++ = digits[ndigits]; + } + while (ndigits > precision); + else + *p++ = '0'; + /* Here ndigits <= precision. */ + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > ndigits; precision--) + *p++ = '0'; + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + int exponent; + + if (arg == 0.0) + { + exponent = 0; + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else + { + /* arg > 0.0. */ + int adjusted; + char *digits; + size_t ndigits; + + exponent = floorlog10 (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_double (arg, + (int)precision - exponent); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits == precision + 1) + break; + if (ndigits < precision + || ndigits > precision + 2) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits == precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision+1. */ + if (is_borderline (digits, precision)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_double (arg, + (int)precision - exponent + 1); + if (digits2 == NULL) + { + free (digits); + goto out_of_memory; + } + if (strlen (digits2) == precision + 1) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision+1. */ + + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + while (ndigits > 0) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + + free (digits); + } + + *p++ = dp->conversion; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + { '%', '+', '.', '3', 'd', '\0' }; +# else + { '%', '+', '.', '2', 'd', '\0' }; +# endif + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + { + static const char decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + "%+.3d"; +# else + "%+.2d"; +# endif + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, decimal_format, exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, decimal_format, exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } + } +# endif + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + if (precision == 0) + precision = 1; + /* precision >= 1. */ + + if (arg == 0.0) + /* The exponent is 0, >= -4, < precision. + Use fixed-point notation. */ + { + size_t ndigits = precision; + /* Number of trailing zeroes that have to be + dropped. */ + size_t nzeroes = + (flags & FLAG_ALT ? 0 : precision - 1); + + --ndigits; + *p++ = '0'; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = '0'; + } + } + } + else + { + /* arg > 0.0. */ + int exponent; + int adjusted; + char *digits; + size_t ndigits; + size_t nzeroes; + + exponent = floorlog10 (arg); + adjusted = 0; + for (;;) + { + digits = + scale10_round_decimal_double (arg, + (int)(precision - 1) - exponent); + if (digits == NULL) + goto out_of_memory; + ndigits = strlen (digits); + + if (ndigits == precision) + break; + if (ndigits < precision - 1 + || ndigits > precision + 1) + /* The exponent was not guessed + precisely enough. */ + abort (); + if (adjusted) + /* None of two values of exponent is + the right one. Prevent an endless + loop. */ + abort (); + free (digits); + if (ndigits < precision) + exponent -= 1; + else + exponent += 1; + adjusted = 1; + } + /* Here ndigits = precision. */ + if (is_borderline (digits, precision - 1)) + { + /* Maybe the exponent guess was too high + and a smaller exponent can be reached + by turning a 10...0 into 9...9x. */ + char *digits2 = + scale10_round_decimal_double (arg, + (int)(precision - 1) - exponent + 1); + if (digits2 == NULL) + { + free (digits); + goto out_of_memory; + } + if (strlen (digits2) == precision) + { + free (digits); + digits = digits2; + exponent -= 1; + } + else + free (digits2); + } + /* Here ndigits = precision. */ + + /* Determine the number of trailing zeroes + that have to be dropped. */ + nzeroes = 0; + if ((flags & FLAG_ALT) == 0) + while (nzeroes < ndigits + && digits[nzeroes] == '0') + nzeroes++; + + /* The exponent is now determined. */ + if (exponent >= -4 + && exponent < (long)precision) + { + /* Fixed-point notation: + max(exponent,0)+1 digits, then the + decimal point, then the remaining + digits without trailing zeroes. */ + if (exponent >= 0) + { + size_t count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + size_t count = -exponent - 1; + *p++ = '0'; + *p++ = decimal_point_char (); + for (; count > 0; count--) + *p++ = '0'; + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + } + else + { + /* Exponential notation. */ + *p++ = digits[--ndigits]; + if ((flags & FLAG_ALT) || ndigits > nzeroes) + { + *p++ = decimal_point_char (); + while (ndigits > nzeroes) + { + --ndigits; + *p++ = digits[ndigits]; + } + } + *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ +# if WIDE_CHAR_VERSION + { + static const wchar_t decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + { '%', '+', '.', '3', 'd', '\0' }; +# else + { '%', '+', '.', '2', 'd', '\0' }; +# endif + SNPRINTF (p, 6 + 1, decimal_format, exponent); + } + while (*p != '\0') + p++; +# else + { + static const char decimal_format[] = + /* Produce the same number of exponent digits + as the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + "%+.3d"; +# else + "%+.2d"; +# endif + if (sizeof (DCHAR_T) == 1) + { + sprintf ((char *) p, decimal_format, exponent); + while (*p != '\0') + p++; + } + else + { + char expbuf[6 + 1]; + const char *ep; + sprintf (expbuf, decimal_format, exponent); + for (ep = expbuf; (*p = *ep) != '\0'; ep++) + p++; + } + } +# endif + } + + free (digits); + } + } + else + abort (); +# else + /* arg is finite. */ + if (!(arg == 0.0)) + abort (); + + pad_ptr = p; + + if (dp->conversion == 'f' || dp->conversion == 'F') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + } + else if (dp->conversion == 'e' || dp->conversion == 'E') + { + *p++ = '0'; + if ((flags & FLAG_ALT) || precision > 0) + { + *p++ = decimal_point_char (); + for (; precision > 0; precision--) + *p++ = '0'; + } + *p++ = dp->conversion; /* 'e' or 'E' */ + *p++ = '+'; + /* Produce the same number of exponent digits as + the native printf implementation. */ +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + *p++ = '0'; +# endif + *p++ = '0'; + *p++ = '0'; + } + else if (dp->conversion == 'g' || dp->conversion == 'G') + { + *p++ = '0'; + if (flags & FLAG_ALT) + { + size_t ndigits = + (precision > 0 ? precision - 1 : 0); + *p++ = decimal_point_char (); + for (; ndigits > 0; --ndigits) + *p++ = '0'; + } + } + else + abort (); +# endif + } + } + } +# endif + + /* The generated string now extends from tmp to p, with the + zero padding insertion point being at pad_ptr. */ + if (has_width && p - tmp < width) + { + size_t pad = width - (p - tmp); + DCHAR_T *end = p + pad; + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > tmp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + + p = end; + } + + { + size_t count = p - tmp; + + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); + + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); + + ENSURE_ALLOCATION (n); + } + + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; + } + } +#endif + else + { + arg_type type = a.arg[dp->arg_index].type; + int flags = dp->flags; +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int has_width; + size_t width; +#endif +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION + int has_precision; + size_t precision; +#endif +#if NEED_PRINTF_UNBOUNDED_PRECISION + int prec_ourselves; +#else +# define prec_ourselves 0 +#endif +#if NEED_PRINTF_FLAG_LEFTADJUST +# define pad_ourselves 1 +#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int pad_ourselves; +#else +# define pad_ourselves 0 +#endif + TCHAR_T *fbp; + unsigned int prefix_count; + int prefixes[2] IF_LINT (= { 0 }); +#if !USE_SNPRINTF + size_t tmp_length; + TCHAR_T tmpbuf[700]; + TCHAR_T *tmp; +#endif + +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + has_width = 0; + width = 0; + if (dp->width_start != dp->width_end) + { + if (dp->width_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->width_arg_index].a.a_int; + if (arg < 0) + { + /* "A negative field width is taken as a '-' flag + followed by a positive field width." */ + flags |= FLAG_LEFT; + width = (unsigned int) (-arg); + } + else + width = arg; + } + else + { + const FCHAR_T *digitp = dp->width_start; + + do + width = xsum (xtimes (width, 10), *digitp++ - '0'); + while (digitp != dp->width_end); + } + has_width = 1; + } +#endif + +#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION + has_precision = 0; + precision = 6; + if (dp->precision_start != dp->precision_end) + { + if (dp->precision_arg_index != ARG_NONE) + { + int arg; + + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + arg = a.arg[dp->precision_arg_index].a.a_int; + /* "A negative precision is taken as if the precision + were omitted." */ + if (arg >= 0) + { + precision = arg; + has_precision = 1; + } + } + else + { + const FCHAR_T *digitp = dp->precision_start + 1; + + precision = 0; + while (digitp != dp->precision_end) + precision = xsum (xtimes (precision, 10), *digitp++ - '0'); + has_precision = 1; + } + } +#endif + + /* Decide whether to handle the precision ourselves. */ +#if NEED_PRINTF_UNBOUNDED_PRECISION + switch (dp->conversion) + { + case 'd': case 'i': case 'u': + case 'o': + case 'x': case 'X': case 'p': + prec_ourselves = has_precision && (precision > 0); + break; + default: + prec_ourselves = 0; + break; + } +#endif + + /* Decide whether to perform the padding ourselves. */ +#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION) + switch (dp->conversion) + { +# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO + /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need + to perform the padding after this conversion. Functions + with unistdio extensions perform the padding based on + character count rather than element count. */ + case 'c': case 's': +# endif +# if NEED_PRINTF_FLAG_ZERO + case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': + case 'a': case 'A': +# endif + pad_ourselves = 1; + break; + default: + pad_ourselves = prec_ourselves; + break; + } +#endif + +#if !USE_SNPRINTF + /* Allocate a temporary buffer of sufficient size for calling + sprintf. */ + tmp_length = + MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type, + flags, width, has_precision, precision, + pad_ourselves); + + if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T)) + tmp = tmpbuf; + else + { + size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T)); + + if (size_overflow_p (tmp_memsize)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; + tmp = (TCHAR_T *) malloc (tmp_memsize); + if (tmp == NULL) + /* Out of memory. */ + goto out_of_memory; + } +#endif + + /* Construct the format string for calling snprintf or + sprintf. */ + fbp = buf; + *fbp++ = '%'; +#if NEED_PRINTF_FLAG_GROUPING + /* The underlying implementation doesn't support the ' flag. + Produce no grouping characters in this case; this is + acceptable because the grouping is locale dependent. */ +#else + if (flags & FLAG_GROUP) + *fbp++ = '\''; +#endif + if (flags & FLAG_LEFT) + *fbp++ = '-'; + if (flags & FLAG_SHOWSIGN) + *fbp++ = '+'; + if (flags & FLAG_SPACE) + *fbp++ = ' '; + if (flags & FLAG_ALT) + *fbp++ = '#'; + if (!pad_ourselves) + { + if (flags & FLAG_ZERO) + *fbp++ = '0'; + if (dp->width_start != dp->width_end) + { + size_t n = dp->width_end - dp->width_start; + /* The width specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->width_start; + do + *fbp++ = (unsigned char) *mp++; + while (--n > 0); + } + } + } + if (!prec_ourselves) + { + if (dp->precision_start != dp->precision_end) + { + size_t n = dp->precision_end - dp->precision_start; + /* The precision specification is known to consist only + of standard ASCII characters. */ + if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) + { + memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); + fbp += n; + } + else + { + const FCHAR_T *mp = dp->precision_start; + do + *fbp++ = (unsigned char) *mp++; + while (--n > 0); + } + } + } + + switch (type) + { +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + case TYPE_ULONGLONGINT: +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + *fbp++ = 'I'; + *fbp++ = '6'; + *fbp++ = '4'; + break; +# else + *fbp++ = 'l'; + /*FALLTHROUGH*/ +# endif +#endif + case TYPE_LONGINT: + case TYPE_ULONGINT: +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: +#endif +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: +#endif + *fbp++ = 'l'; + break; + case TYPE_LONGDOUBLE: + *fbp++ = 'L'; + break; + default: + break; + } +#if NEED_PRINTF_DIRECTIVE_F + if (dp->conversion == 'F') + *fbp = 'f'; + else +#endif + *fbp = dp->conversion; +#if USE_SNPRINTF +# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; +# else + /* On glibc2 systems from glibc >= 2.3 - probably also older + ones - we know that snprintf's returns value conforms to + ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes. + Therefore we can avoid using %n in this situation. + On glibc2 systems from 2004-10-18 or newer, the use of %n + in format strings in writable memory may crash the program + (if compiled with _FORTIFY_SOURCE=2), so we should avoid it + in this situation. */ + /* On native Win32 systems (such as mingw), we can avoid using + %n because: + - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, + snprintf does not write more than the specified number + of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes + '4', '5', '6' into buf, not '4', '5', '\0'.) + - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf + allows us to recognize the case of an insufficient + buffer size: it returns -1 in this case. + On native Win32 systems (such as mingw) where the OS is + Windows Vista, the use of %n in format strings by default + crashes the program. See + and + + So we should avoid %n in this situation. */ + fbp[1] = '\0'; +# endif +#else + fbp[1] = '\0'; +#endif + + /* Construct the arguments for calling snprintf or sprintf. */ + prefix_count = 0; + if (!pad_ourselves && dp->width_arg_index != ARG_NONE) + { + if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) + abort (); + prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; + } + if (!prec_ourselves && dp->precision_arg_index != ARG_NONE) + { + if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) + abort (); + prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; + } + +#if USE_SNPRINTF + /* The SNPRINTF result is appended after result[0..length]. + The latter is an array of DCHAR_T; SNPRINTF appends an + array of TCHAR_T to it. This is possible because + sizeof (TCHAR_T) divides sizeof (DCHAR_T) and + alignof (TCHAR_T) <= alignof (DCHAR_T). */ +# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T)) + /* Ensure that maxlen below will be >= 2. Needed on BeOS, + where an snprintf() with maxlen==1 acts like sprintf(). */ + ENSURE_ALLOCATION (xsum (length, + (2 + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR)); + /* Prepare checking whether snprintf returns the count + via %n. */ + *(TCHAR_T *) (result + length) = '\0'; +#endif + + for (;;) + { + int count = -1; + +#if USE_SNPRINTF + int retcount = 0; + size_t maxlen = allocated - length; + /* SNPRINTF can fail if its second argument is + > INT_MAX. */ + if (maxlen > INT_MAX / TCHARS_PER_DCHAR) + maxlen = INT_MAX / TCHARS_PER_DCHAR; + maxlen = maxlen * TCHARS_PER_DCHAR; +# define SNPRINTF_BUF(arg) \ + switch (prefix_count) \ + { \ + case 0: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + arg, &count); \ + break; \ + case 1: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + prefixes[0], arg, &count); \ + break; \ + case 2: \ + retcount = SNPRINTF ((TCHAR_T *) (result + length), \ + maxlen, buf, \ + prefixes[0], prefixes[1], arg, \ + &count); \ + break; \ + default: \ + abort (); \ + } +#else +# define SNPRINTF_BUF(arg) \ + switch (prefix_count) \ + { \ + case 0: \ + count = sprintf (tmp, buf, arg); \ + break; \ + case 1: \ + count = sprintf (tmp, buf, prefixes[0], arg); \ + break; \ + case 2: \ + count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ + arg); \ + break; \ + default: \ + abort (); \ + } +#endif + + errno = 0; + switch (type) + { + case TYPE_SCHAR: + { + int arg = a.arg[dp->arg_index].a.a_schar; + SNPRINTF_BUF (arg); + } + break; + case TYPE_UCHAR: + { + unsigned int arg = a.arg[dp->arg_index].a.a_uchar; + SNPRINTF_BUF (arg); + } + break; + case TYPE_SHORT: + { + int arg = a.arg[dp->arg_index].a.a_short; + SNPRINTF_BUF (arg); + } + break; + case TYPE_USHORT: + { + unsigned int arg = a.arg[dp->arg_index].a.a_ushort; + SNPRINTF_BUF (arg); + } + break; + case TYPE_INT: + { + int arg = a.arg[dp->arg_index].a.a_int; + SNPRINTF_BUF (arg); + } + break; + case TYPE_UINT: + { + unsigned int arg = a.arg[dp->arg_index].a.a_uint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGINT: + { + long int arg = a.arg[dp->arg_index].a.a_longint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_ULONGINT: + { + unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_LONG_LONG_INT + case TYPE_LONGLONGINT: + { + long long int arg = a.arg[dp->arg_index].a.a_longlongint; + SNPRINTF_BUF (arg); + } + break; + case TYPE_ULONGLONGINT: + { + unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_DOUBLE: + { + double arg = a.arg[dp->arg_index].a.a_double; + SNPRINTF_BUF (arg); + } + break; + case TYPE_LONGDOUBLE: + { + long double arg = a.arg[dp->arg_index].a.a_longdouble; + SNPRINTF_BUF (arg); + } + break; + case TYPE_CHAR: + { + int arg = a.arg[dp->arg_index].a.a_char; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_WINT_T + case TYPE_WIDE_CHAR: + { + wint_t arg = a.arg[dp->arg_index].a.a_wide_char; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_STRING: + { + const char *arg = a.arg[dp->arg_index].a.a_string; + SNPRINTF_BUF (arg); + } + break; +#if HAVE_WCHAR_T + case TYPE_WIDE_STRING: + { + const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; + SNPRINTF_BUF (arg); + } + break; +#endif + case TYPE_POINTER: + { + void *arg = a.arg[dp->arg_index].a.a_pointer; + SNPRINTF_BUF (arg); + } + break; + default: + abort (); + } + +#if USE_SNPRINTF + /* Portability: Not all implementations of snprintf() + are ISO C 99 compliant. Determine the number of + bytes that snprintf() has produced or would have + produced. */ + if (count >= 0) + { + /* Verify that snprintf() has NUL-terminated its + result. */ + if (count < maxlen + && ((TCHAR_T *) (result + length)) [count] != '\0') + abort (); + /* Portability hack. */ + if (retcount > count) + count = retcount; + } + else + { + /* snprintf() doesn't understand the '%n' + directive. */ + if (fbp[1] != '\0') + { + /* Don't use the '%n' directive; instead, look + at the snprintf() return value. */ + fbp[1] = '\0'; + continue; + } + else + { + /* Look at the snprintf() return value. */ + if (retcount < 0) + { +# if !HAVE_SNPRINTF_RETVAL_C99 + /* HP-UX 10.20 snprintf() is doubly deficient: + It doesn't understand the '%n' directive, + *and* it returns -1 (rather than the length + that would have been required) when the + buffer is too small. + But a failure at this point can also come + from other reasons than a too small buffer, + such as an invalid wide string argument to + the %ls directive, or possibly an invalid + floating-point argument. */ + size_t tmp_length = + MAX_ROOM_NEEDED (&a, dp->arg_index, + dp->conversion, type, flags, + width, has_precision, + precision, pad_ourselves); + + if (maxlen < tmp_length) + { + /* Make more room. But try to do through + this reallocation only once. */ + size_t bigger_need = + xsum (length, + xsum (tmp_length, + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR); + /* And always grow proportionally. + (There may be several arguments, each + needing a little more room than the + previous one.) */ + size_t bigger_need2 = + xsum (xtimes (allocated, 2), 12); + if (bigger_need < bigger_need2) + bigger_need = bigger_need2; + ENSURE_ALLOCATION (bigger_need); + continue; + } +# endif + } + else + count = retcount; + } + } +#endif + + /* Attempt to handle failure. */ + if (count < 0) + { + /* SNPRINTF or sprintf failed. Save and use the errno + that it has set, if any. */ + int saved_errno = errno; + + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = + (saved_errno != 0 + ? saved_errno + : (dp->conversion == 'c' || dp->conversion == 's' + ? EILSEQ + : EINVAL)); + return NULL; + } + +#if USE_SNPRINTF + /* Handle overflow of the allocated buffer. + If such an overflow occurs, a C99 compliant snprintf() + returns a count >= maxlen. However, a non-compliant + snprintf() function returns only count = maxlen - 1. To + cover both cases, test whether count >= maxlen - 1. */ + if ((unsigned int) count + 1 >= maxlen) + { + /* If maxlen already has attained its allowed maximum, + allocating more memory will not increase maxlen. + Instead of looping, bail out. */ + if (maxlen == INT_MAX / TCHARS_PER_DCHAR) + goto overflow; + else + { + /* Need at least (count + 1) * sizeof (TCHAR_T) + bytes. (The +1 is for the trailing NUL.) + But ask for (count + 2) * sizeof (TCHAR_T) + bytes, so that in the next round, we likely get + maxlen > (unsigned int) count + 1 + and so we don't get here again. + And allocate proportionally, to avoid looping + eternally if snprintf() reports a too small + count. */ + size_t n = + xmax (xsum (length, + ((unsigned int) count + 2 + + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR), + xtimes (allocated, 2)); + + ENSURE_ALLOCATION (n); + continue; + } + } +#endif + +#if NEED_PRINTF_UNBOUNDED_PRECISION + if (prec_ourselves) + { + /* Handle the precision. */ + TCHAR_T *prec_ptr = +# if USE_SNPRINTF + (TCHAR_T *) (result + length); +# else + tmp; +# endif + size_t prefix_count; + size_t move; + + prefix_count = 0; + /* Put the additional zeroes after the sign. */ + if (count >= 1 + && (*prec_ptr == '-' || *prec_ptr == '+' + || *prec_ptr == ' ')) + prefix_count = 1; + /* Put the additional zeroes after the 0x prefix if + (flags & FLAG_ALT) || (dp->conversion == 'p'). */ + else if (count >= 2 + && prec_ptr[0] == '0' + && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X')) + prefix_count = 2; + + move = count - prefix_count; + if (precision > move) + { + /* Insert zeroes. */ + size_t insert = precision - move; + TCHAR_T *prec_end; + +# if USE_SNPRINTF + size_t n = + xsum (length, + (count + insert + TCHARS_PER_DCHAR - 1) + / TCHARS_PER_DCHAR); + length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + ENSURE_ALLOCATION (n); + length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; + prec_ptr = (TCHAR_T *) (result + length); +# endif + + prec_end = prec_ptr + count; + prec_ptr += prefix_count; + + while (prec_end > prec_ptr) + { + prec_end--; + prec_end[insert] = prec_end[0]; + } + + prec_end += insert; + do + *--prec_end = '0'; + while (prec_end > prec_ptr); + + count += insert; + } + } +#endif + +#if !USE_SNPRINTF + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); +#endif + +#if !DCHAR_IS_TCHAR + /* Convert from TCHAR_T[] to DCHAR_T[]. */ + if (dp->conversion == 'c' || dp->conversion == 's') + { + /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING + TYPE_WIDE_STRING. + The result string is not certainly ASCII. */ + const TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; + /* This code assumes that TCHAR_T is 'char'. */ + typedef int TCHAR_T_verify + [2 * (sizeof (TCHAR_T) == 1) - 1]; +# if USE_SNPRINTF + tmpsrc = (TCHAR_T *) (result + length); +# else + tmpsrc = tmp; +# endif + tmpdst = + DCHAR_CONV_FROM_ENCODING (locale_charset (), + iconveh_question_mark, + tmpsrc, count, + NULL, + NULL, &tmpdst_len); + if (tmpdst == NULL) + { + int saved_errno = errno; + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = saved_errno; + return NULL; + } + ENSURE_ALLOCATION (xsum (length, tmpdst_len)); + DCHAR_CPY (result + length, tmpdst, tmpdst_len); + free (tmpdst); + count = tmpdst_len; + } + else + { + /* The result string is ASCII. + Simple 1:1 conversion. */ +# if USE_SNPRINTF + /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a + no-op conversion, in-place on the array starting + at (result + length). */ + if (sizeof (DCHAR_T) != sizeof (TCHAR_T)) +# endif + { + const TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t n; + +# if USE_SNPRINTF + if (result == resultbuf) + { + tmpsrc = (TCHAR_T *) (result + length); + /* ENSURE_ALLOCATION will not move tmpsrc + (because it's part of resultbuf). */ + ENSURE_ALLOCATION (xsum (length, count)); + } + else + { + /* ENSURE_ALLOCATION will move the array + (because it uses realloc(). */ + ENSURE_ALLOCATION (xsum (length, count)); + tmpsrc = (TCHAR_T *) (result + length); + } +# else + tmpsrc = tmp; + ENSURE_ALLOCATION (xsum (length, count)); +# endif + tmpdst = result + length; + /* Copy backwards, because of overlapping. */ + tmpsrc += count; + tmpdst += count; + for (n = count; n > 0; n--) + *--tmpdst = (unsigned char) *--tmpsrc; + } + } +#endif + +#if DCHAR_IS_TCHAR && !USE_SNPRINTF + /* Make room for the result. */ + if (count > allocated - length) + { + /* Need at least count elements. But allocate + proportionally. */ + size_t n = + xmax (xsum (length, count), xtimes (allocated, 2)); + + ENSURE_ALLOCATION (n); + } +#endif + + /* Here count <= allocated - length. */ + + /* Perform padding. */ +#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + if (pad_ourselves && has_width) + { + size_t w; +# if ENABLE_UNISTDIO + /* Outside POSIX, it's preferrable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, count); +# else + /* The width is compared against the number of _bytes_ + of the converted value, says POSIX. */ + w = count; +# endif + if (w < width) + { + size_t pad = width - w; + + /* Make room for the result. */ + if (xsum (count, pad) > allocated - length) + { + /* Need at least count + pad elements. But + allocate proportionally. */ + size_t n = + xmax (xsum3 (length, count, pad), + xtimes (allocated, 2)); + +# if USE_SNPRINTF + length += count; + ENSURE_ALLOCATION (n); + length -= count; +# else + ENSURE_ALLOCATION (n); +# endif + } + /* Here count + pad <= allocated - length. */ + + { +# if !DCHAR_IS_TCHAR || USE_SNPRINTF + DCHAR_T * const rp = result + length; +# else + DCHAR_T * const rp = tmp; +# endif + DCHAR_T *p = rp + count; + DCHAR_T *end = p + pad; + DCHAR_T *pad_ptr; +# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO + if (dp->conversion == 'c' + || dp->conversion == 's') + /* No zero-padding for string directives. */ + pad_ptr = NULL; + else +# endif + { + pad_ptr = (*rp == '-' ? rp + 1 : rp); + /* No zero-padding of "inf" and "nan". */ + if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') + || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) + pad_ptr = NULL; + } + /* The generated string now extends from rp to p, + with the zero padding insertion point being at + pad_ptr. */ + + count = count + pad; /* = end - rp */ + + if (flags & FLAG_LEFT) + { + /* Pad with spaces on the right. */ + for (; pad > 0; pad--) + *p++ = ' '; + } + else if ((flags & FLAG_ZERO) && pad_ptr != NULL) + { + /* Pad with zeroes. */ + DCHAR_T *q = end; + + while (p > pad_ptr) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = '0'; + } + else + { + /* Pad with spaces on the left. */ + DCHAR_T *q = end; + + while (p > rp) + *--q = *--p; + for (; pad > 0; pad--) + *p++ = ' '; + } + } + } + } +#endif + + /* Here still count <= allocated - length. */ + +#if !DCHAR_IS_TCHAR || USE_SNPRINTF + /* The snprintf() result did fit. */ +#else + /* Append the sprintf() result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); +#endif +#if !USE_SNPRINTF + if (tmp != tmpbuf) + free (tmp); +#endif + +#if NEED_PRINTF_DIRECTIVE_F + if (dp->conversion == 'F') + { + /* Convert the %f result to upper case for %F. */ + DCHAR_T *rp = result + length; + size_t rc; + for (rc = count; rc > 0; rc--, rp++) + if (*rp >= 'a' && *rp <= 'z') + *rp = *rp - 'a' + 'A'; + } +#endif + + length += count; + break; + } +#undef pad_ourselves +#undef prec_ourselves + } + } + } + + /* Add the final NUL. */ + ENSURE_ALLOCATION (xsum (length, 1)); + result[length] = '\0'; + + if (result != resultbuf && length + 1 < allocated) + { + /* Shrink the allocated memory if possible. */ + DCHAR_T *memory; + + memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T)); + if (memory != NULL) + result = memory; + } + + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + *lengthp = length; + /* Note that we can produce a big string of a length > INT_MAX. POSIX + says that snprintf() fails with errno = EOVERFLOW in this case, but + that's only because snprintf() returns an 'int'. This function does + not have this limitation. */ + return result; + +#if USE_SNPRINTF + overflow: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + CLEANUP (); + errno = EOVERFLOW; + return NULL; +#endif + + out_of_memory: + if (!(result == resultbuf || result == NULL)) + free (result); + if (buf_malloced != NULL) + free (buf_malloced); + out_of_memory_1: + CLEANUP (); + errno = ENOMEM; + return NULL; + } +} + +#undef MAX_ROOM_NEEDED +#undef TCHARS_PER_DCHAR +#undef SNPRINTF +#undef USE_SNPRINTF +#undef DCHAR_SET +#undef DCHAR_CPY +#undef PRINTF_PARSE +#undef DIRECTIVES +#undef DIRECTIVE +#undef DCHAR_IS_TCHAR +#undef TCHAR_T +#undef DCHAR_T +#undef FCHAR_T +#undef VASNPRINTF diff --git a/grub-core/gnulib/vasnprintf.h b/grub-core/gnulib/vasnprintf.h new file mode 100644 index 000000000..a689bad25 --- /dev/null +++ b/grub-core/gnulib/vasnprintf.h @@ -0,0 +1,80 @@ +/* vsprintf with automatic memory allocation. + Copyright (C) 2002-2004, 2007-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _VASNPRINTF_H +#define _VASNPRINTF_H + +/* Get va_list. */ +#include + +/* Get size_t. */ +#include + +#ifndef __attribute__ +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable __attribute__ only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Write formatted output to a string dynamically allocated with malloc(). + You can pass a preallocated buffer for the result in RESULTBUF and its + size in *LENGTHP; otherwise you pass RESULTBUF = NULL. + If successful, return the address of the string (this may be = RESULTBUF + if no dynamic memory allocation was necessary) and set *LENGTHP to the + number of resulting bytes, excluding the trailing NUL. Upon error, set + errno and return NULL. + + When dynamic memory allocation occurs, the preallocated buffer is left + alone (with possibly modified contents). This makes it possible to use + a statically allocated or stack-allocated buffer, like this: + + char buf[100]; + size_t len = sizeof (buf); + char *output = vasnprintf (buf, &len, format, args); + if (output == NULL) + ... error handling ...; + else + { + ... use the output string ...; + if (output != buf) + free (output); + } + */ +#if REPLACE_VASNPRINTF +# define asnprintf rpl_asnprintf +# define vasnprintf rpl_vasnprintf +#endif +extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))); + +#ifdef __cplusplus +} +#endif + +#endif /* _VASNPRINTF_H */ diff --git a/grub-core/gnulib/verify.h b/grub-core/gnulib/verify.h new file mode 100644 index 000000000..4ad780c8f --- /dev/null +++ b/grub-core/gnulib/verify.h @@ -0,0 +1,163 @@ +/* Compile-time assert-like macros. + + Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ + +#ifndef VERIFY_H +# define VERIFY_H 1 + +/* Each of these macros verifies that its argument R is nonzero. To + be portable, R should be an integer constant expression. Unlike + assert (R), there is no run-time overhead. + + There are two macros, since no single macro can be used in all + contexts in C. verify_true (R) is for scalar contexts, including + integer constant expression contexts. verify (R) is for declaration + contexts, e.g., the top level. + + Symbols ending in "__" are private to this header. + + The code below uses several ideas. + + * The first step is ((R) ? 1 : -1). Given an expression R, of + integral or boolean or floating-point type, this yields an + expression of integral type, whose value is later verified to be + constant and nonnegative. + + * Next this expression W is wrapped in a type + struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. + If W is negative, this yields a compile-time error. No compiler can + deal with a bit-field of negative size. + + One might think that an array size check would have the same + effect, that is, that the type struct { unsigned int dummy[W]; } + would work as well. However, inside a function, some compilers + (such as C++ compilers and GNU C) allow local parameters and + variables inside array size expressions. With these compilers, + an array size check would not properly diagnose this misuse of + the verify macro: + + void function (int n) { verify (n < 0); } + + * For the verify macro, the struct verify_type__ will need to + somehow be embedded into a declaration. To be portable, this + declaration must declare an object, a constant, a function, or a + typedef name. If the declared entity uses the type directly, + such as in + + struct dummy {...}; + typedef struct {...} dummy; + extern struct {...} *dummy; + extern void dummy (struct {...} *); + extern struct {...} *dummy (void); + + two uses of the verify macro would yield colliding declarations + if the entity names are not disambiguated. A workaround is to + attach the current line number to the entity name: + + #define _GL_CONCAT0(x, y) x##y + #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) + extern struct {...} * _GL_CONCAT (dummy, __LINE__); + + But this has the problem that two invocations of verify from + within the same macro would collide, since the __LINE__ value + would be the same for both invocations. (The GCC __COUNTER__ + macro solves this problem, but is not portable.) + + A solution is to use the sizeof operator. It yields a number, + getting rid of the identity of the type. Declarations like + + extern int dummy [sizeof (struct {...})]; + extern void dummy (int [sizeof (struct {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; + + can be repeated. + + * Should the implementation use a named struct or an unnamed struct? + Which of the following alternatives can be used? + + extern int dummy [sizeof (struct {...})]; + extern int dummy [sizeof (struct verify_type__ {...})]; + extern void dummy (int [sizeof (struct {...})]); + extern void dummy (int [sizeof (struct verify_type__ {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; + extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; + + In the second and sixth case, the struct type is exported to the + outer scope; two such declarations therefore collide. GCC warns + about the first, third, and fourth cases. So the only remaining + possibility is the fifth case: + + extern int (*dummy (void)) [sizeof (struct {...})]; + + * GCC warns about duplicate declarations of the dummy function if + -Wredundant_decls is used. GCC 4.3 and later have a builtin + __COUNTER__ macro that can let us generate unique identifiers for + each dummy function, to suppress this warning. + + * This implementation exploits the fact that GCC does not warn about + the last declaration mentioned above. If a future version of GCC + introduces a warning for this, the problem could be worked around + by using code specialized to GCC, just as __COUNTER__ is already + being used if available. + + #if 4 <= __GNUC__ + # define verify(R) [another version to keep GCC happy] + #endif + + * In C++, any struct definition inside sizeof is invalid. + Use a template type to work around the problem. */ + +/* Concatenate two preprocessor tokens. */ +# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) +# define _GL_CONCAT0(x, y) x##y + +/* _GL_COUNTER is an integer, preferably one that changes each time we + use it. Use __COUNTER__ if it works, falling back on __LINE__ + otherwise. __LINE__ isn't perfect, but it's better than a + constant. */ +# if defined __COUNTER__ && __COUNTER__ != __COUNTER__ +# define _GL_COUNTER __COUNTER__ +# else +# define _GL_COUNTER __LINE__ +# endif + +/* Generate a symbol with the given prefix, making it unique if + possible. */ +# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) + +/* Verify requirement R at compile-time, as an integer constant expression. + Return 1. */ + +# ifdef __cplusplus +template + struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; +# define verify_true(R) \ + (!!sizeof (verify_type__<(R) ? 1 : -1>)) +# else +# define verify_true(R) \ + (!!sizeof \ + (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) +# endif + +/* Verify requirement R at compile-time, as a declaration without a + trailing ';'. */ + +# define verify(R) \ + extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)] + +#endif diff --git a/grub-core/gnulib/vsnprintf.c b/grub-core/gnulib/vsnprintf.c new file mode 100644 index 000000000..d447cc2d5 --- /dev/null +++ b/grub-core/gnulib/vsnprintf.c @@ -0,0 +1,71 @@ +/* Formatted output to strings. + Copyright (C) 2004, 2006-2010 Free Software Foundation, Inc. + Written by Simon Josefsson and Yoann Vandoorselaere . + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include + +#include +#include +#include +#include +#include + +#include "vasnprintf.h" + +/* Print formatted output to string STR. Similar to vsprintf, but + additional length SIZE limit how much is written into STR. Returns + string length of formatted string (which may be larger than SIZE). + STR may be NULL, in which case nothing will be written. On error, + return a negative value. */ +int +vsnprintf (char *str, size_t size, const char *format, va_list args) +{ + char *output; + size_t len; + size_t lenbuf = size; + + output = vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + + if (!output) + return -1; + + if (output != str) + { + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); + } + + if (len > INT_MAX) + { + errno = EOVERFLOW; + return -1; + } + + return len; +} diff --git a/grub-core/gnulib/wchar.in.h b/grub-core/gnulib/wchar.in.h new file mode 100644 index 000000000..88d47dbc0 --- /dev/null +++ b/grub-core/gnulib/wchar.in.h @@ -0,0 +1,428 @@ +/* A substitute for ISO C99 , for platforms that have issues. + + Copyright (C) 2007-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Eric Blake. */ + +/* + * ISO C 99 for platforms that have issues. + * + * + * For now, this just ensures proper prerequisite inclusion order and + * the declaration of wcwidth(). + */ + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +/* Special invocation convention: + - Inside glibc and uClibc header files. + - On HP-UX 11.00 we have a sequence of nested includes + -> -> , and the latter includes , + once indirectly -> -> -> + and once directly. In both situations 'wint_t' is not yet defined, + therefore we cannot provide the function overrides; instead include only + the system's . + - On IRIX 6.5, similarly, we have an include -> , and + the latter includes . But here, we have no way to detect whether + is completely included or is still being included. */ + +#@INCLUDE_NEXT@ @NEXT_WCHAR_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _GL_WCHAR_H + +#define _GL_ALREADY_INCLUDING_WCHAR_H + +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . + But avoid namespace pollution on glibc systems. */ +#ifndef __GLIBC__ +# include +# include +# include +#endif + +/* Include the original if it exists. + Some builds of uClibc lack it. */ +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_WCHAR_H@ +# @INCLUDE_NEXT@ @NEXT_WCHAR_H@ +#endif + +#undef _GL_ALREADY_INCLUDING_WCHAR_H + +#ifndef _GL_WCHAR_H +#define _GL_WCHAR_H + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Define wint_t and WEOF. (Also done in wctype.in.h.) */ +#if !@HAVE_WINT_T@ && !defined wint_t +# define wint_t int +# ifndef WEOF +# define WEOF -1 +# endif +#else +# ifndef WEOF +# define WEOF ((wint_t) -1) +# endif +#endif + + +/* Override mbstate_t if it is too small. + On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for + implementing mbrtowc for encodings like UTF-8. */ +#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ +typedef int rpl_mbstate_t; +# undef mbstate_t +# define mbstate_t rpl_mbstate_t +# define GNULIB_defined_mbstate_t 1 +#endif + + +/* Convert a single-byte character to a wide character. */ +#if @GNULIB_BTOWC@ +# if @REPLACE_BTOWC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef btowc +# define btowc rpl_btowc +# endif +_GL_FUNCDECL_RPL (btowc, wint_t, (int c)); +_GL_CXXALIAS_RPL (btowc, wint_t, (int c)); +# else +# if !@HAVE_BTOWC@ +_GL_FUNCDECL_SYS (btowc, wint_t, (int c)); +# endif +_GL_CXXALIAS_SYS (btowc, wint_t, (int c)); +# endif +_GL_CXXALIASWARN (btowc); +#elif defined GNULIB_POSIXCHECK +# undef btowc +# if HAVE_RAW_DECL_BTOWC +_GL_WARN_ON_USE (btowc, "btowc is unportable - " + "use gnulib module btowc for portability"); +# endif +#endif + + +/* Convert a wide character to a single-byte character. */ +#if @GNULIB_WCTOB@ +# if @REPLACE_WCTOB@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wctob +# define wctob rpl_wctob +# endif +_GL_FUNCDECL_RPL (wctob, int, (wint_t wc)); +_GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); +# else +# if !defined wctob && !@HAVE_DECL_WCTOB@ +/* wctob is provided by gnulib, or wctob exists but is not declared. */ +_GL_FUNCDECL_SYS (wctob, int, (wint_t wc)); +# endif +_GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); +# endif +_GL_CXXALIASWARN (wctob); +#elif defined GNULIB_POSIXCHECK +# undef wctob +# if HAVE_RAW_DECL_WCTOB +_GL_WARN_ON_USE (wctob, "wctob is unportable - " + "use gnulib module wctob for portability"); +# endif +#endif + + +/* Test whether *PS is in the initial state. */ +#if @GNULIB_MBSINIT@ +# if @REPLACE_MBSINIT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbsinit +# define mbsinit rpl_mbsinit +# endif +_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps)); +_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps)); +# else +# if !@HAVE_MBSINIT@ +_GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbsinit); +#elif defined GNULIB_POSIXCHECK +# undef mbsinit +# if HAVE_RAW_DECL_MBSINIT +_GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - " + "use gnulib module mbsinit for portability"); +# endif +#endif + + +/* Convert a multibyte character to a wide character. */ +#if @GNULIB_MBRTOWC@ +# if @REPLACE_MBRTOWC@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbrtowc +# define mbrtowc rpl_mbrtowc +# endif +_GL_FUNCDECL_RPL (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +_GL_CXXALIAS_RPL (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +# else +# if !@HAVE_MBRTOWC@ +_GL_FUNCDECL_SYS (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (mbrtowc, size_t, + (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbrtowc); +#elif defined GNULIB_POSIXCHECK +# undef mbrtowc +# if HAVE_RAW_DECL_MBRTOWC +_GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - " + "use gnulib module mbrtowc for portability"); +# endif +#endif + + +/* Recognize a multibyte character. */ +#if @GNULIB_MBRLEN@ +# if @REPLACE_MBRLEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbrlen +# define mbrlen rpl_mbrlen +# endif +_GL_FUNCDECL_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +# else +# if !@HAVE_MBRLEN@ +_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbrlen); +#elif defined GNULIB_POSIXCHECK +# undef mbrlen +# if HAVE_RAW_DECL_MBRLEN +_GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - " + "use gnulib module mbrlen for portability"); +# endif +#endif + + +/* Convert a string to a wide string. */ +#if @GNULIB_MBSRTOWCS@ +# if @REPLACE_MBSRTOWCS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbsrtowcs +# define mbsrtowcs rpl_mbsrtowcs +# endif +_GL_FUNCDECL_RPL (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_MBSRTOWCS@ +_GL_FUNCDECL_SYS (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (mbsrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbsrtowcs); +#elif defined GNULIB_POSIXCHECK +# undef mbsrtowcs +# if HAVE_RAW_DECL_MBSRTOWCS +_GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - " + "use gnulib module mbsrtowcs for portability"); +# endif +#endif + + +/* Convert a string to a wide string. */ +#if @GNULIB_MBSNRTOWCS@ +# if @REPLACE_MBSNRTOWCS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef mbsnrtowcs +# define mbsnrtowcs rpl_mbsnrtowcs +# endif +_GL_FUNCDECL_RPL (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_MBSNRTOWCS@ +_GL_FUNCDECL_SYS (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (mbsnrtowcs, size_t, + (wchar_t *dest, const char **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (mbsnrtowcs); +#elif defined GNULIB_POSIXCHECK +# undef mbsnrtowcs +# if HAVE_RAW_DECL_MBSNRTOWCS +_GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - " + "use gnulib module mbsnrtowcs for portability"); +# endif +#endif + + +/* Convert a wide character to a multibyte character. */ +#if @GNULIB_WCRTOMB@ +# if @REPLACE_WCRTOMB@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcrtomb +# define wcrtomb rpl_wcrtomb +# endif +_GL_FUNCDECL_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +# else +# if !@HAVE_WCRTOMB@ +_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +# endif +_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (wcrtomb); +#elif defined GNULIB_POSIXCHECK +# undef wcrtomb +# if HAVE_RAW_DECL_WCRTOMB +_GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - " + "use gnulib module wcrtomb for portability"); +# endif +#endif + + +/* Convert a wide string to a string. */ +#if @GNULIB_WCSRTOMBS@ +# if @REPLACE_WCSRTOMBS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsrtombs +# define wcsrtombs rpl_wcsrtombs +# endif +_GL_FUNCDECL_RPL (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_WCSRTOMBS@ +_GL_FUNCDECL_SYS (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (wcsrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (wcsrtombs); +#elif defined GNULIB_POSIXCHECK +# undef wcsrtombs +# if HAVE_RAW_DECL_WCSRTOMBS +_GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - " + "use gnulib module wcsrtombs for portability"); +# endif +#endif + + +/* Convert a wide string to a string. */ +#if @GNULIB_WCSNRTOMBS@ +# if @REPLACE_WCSNRTOMBS@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcsnrtombs +# define wcsnrtombs rpl_wcsnrtombs +# endif +_GL_FUNCDECL_RPL (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# else +# if !@HAVE_WCSNRTOMBS@ +_GL_FUNCDECL_SYS (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (wcsnrtombs, size_t, + (char *dest, const wchar_t **srcp, size_t srclen, size_t len, + mbstate_t *ps)); +# endif +_GL_CXXALIASWARN (wcsnrtombs); +#elif defined GNULIB_POSIXCHECK +# undef wcsnrtombs +# if HAVE_RAW_DECL_WCSNRTOMBS +_GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - " + "use gnulib module wcsnrtombs for portability"); +# endif +#endif + + +/* Return the number of screen columns needed for WC. */ +#if @GNULIB_WCWIDTH@ +# if @REPLACE_WCWIDTH@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef wcwidth +# define wcwidth rpl_wcwidth +# endif +_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t)); +_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); +# else +# if !@HAVE_DECL_WCWIDTH@ +/* wcwidth exists but is not declared. */ +_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t)); +# endif +_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); +# endif +_GL_CXXALIASWARN (wcwidth); +#elif defined GNULIB_POSIXCHECK +# undef wcwidth +# if HAVE_RAW_DECL_WCWIDTH +_GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " + "use gnulib module wcwidth for portability"); +# endif +#endif + + +#endif /* _GL_WCHAR_H */ +#endif /* _GL_WCHAR_H */ +#endif diff --git a/grub-core/gnulib/wcrtomb.c b/grub-core/gnulib/wcrtomb.c new file mode 100644 index 000000000..e7345f698 --- /dev/null +++ b/grub-core/gnulib/wcrtomb.c @@ -0,0 +1,53 @@ +/* Convert wide character to multibyte character. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program 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. + + This program 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 this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include + + +size_t +wcrtomb (char *s, wchar_t wc, mbstate_t *ps) +{ + /* This implementation of wcrtomb on top of wctomb() supports only + stateless encodings. ps must be in the initial state. */ + if (ps != NULL && !mbsinit (ps)) + { + errno = EINVAL; + return (size_t)(-1); + } + + if (s == NULL) + /* We know the NUL wide character corresponds to the NUL character. */ + return 1; + else + { + int ret = wctomb (s, wc); + + if (ret >= 0) + return ret; + else + { + errno = EILSEQ; + return (size_t)(-1); + } + } +} diff --git a/grub-core/gnulib/wctype.in.h b/grub-core/gnulib/wctype.in.h new file mode 100644 index 000000000..12c8975fe --- /dev/null +++ b/grub-core/gnulib/wctype.in.h @@ -0,0 +1,392 @@ +/* A substitute for ISO C99 , for platforms that lack it. + + Copyright (C) 2006-2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Written by Bruno Haible and Paul Eggert. */ + +/* + * ISO C 99 for platforms that lack it. + * + * + * iswctype, towctrans, towlower, towupper, wctrans, wctype, + * wctrans_t, and wctype_t are not yet implemented. + */ + +#ifndef _GL_WCTYPE_H + +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif + +#if @HAVE_WINT_T@ +/* Solaris 2.5 has a bug: must be included before . + Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . */ +# include +# include +# include +# include +#endif + +/* Include the original if it exists. + BeOS 5 has the functions but no . */ +/* The include_next requires a split double-inclusion guard. */ +#if @HAVE_WCTYPE_H@ +# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@ +#endif + +#ifndef _GL_WCTYPE_H +#define _GL_WCTYPE_H + +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + +/* Define wint_t and WEOF. (Also done in wchar.in.h.) */ +#if !@HAVE_WINT_T@ && !defined wint_t +# define wint_t int +# ifndef WEOF +# define WEOF -1 +# endif +#else +# ifndef WEOF +# define WEOF ((wint_t) -1) +# endif +#endif + + +/* FreeBSD 4.4 to 4.11 has but lacks the functions. + Linux libc5 has and the functions but they are broken. + Assume all 11 functions (all isw* except iswblank) are implemented the + same way, or not at all. */ +#if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ + +/* IRIX 5.3 has macros but no functions, its isw* macros refer to an + undefined variable _ctmp_ and to macros like _P, and they + refer to system functions like _iswctype that are not in the + standard C library. Rather than try to get ancient buggy + implementations like this to work, just disable them. */ +# undef iswalnum +# undef iswalpha +# undef iswblank +# undef iswcntrl +# undef iswdigit +# undef iswgraph +# undef iswlower +# undef iswprint +# undef iswpunct +# undef iswspace +# undef iswupper +# undef iswxdigit +# undef towlower +# undef towupper + +/* Linux libc5 has and the functions but they are broken. */ +# if @REPLACE_ISWCNTRL@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iswalnum rpl_iswalnum +# define iswalpha rpl_iswalpha +# define iswblank rpl_iswblank +# define iswcntrl rpl_iswcntrl +# define iswdigit rpl_iswdigit +# define iswgraph rpl_iswgraph +# define iswlower rpl_iswlower +# define iswprint rpl_iswprint +# define iswpunct rpl_iswpunct +# define iswspace rpl_iswspace +# define iswupper rpl_iswupper +# define iswxdigit rpl_iswxdigit +# define towlower rpl_towlower +# define towupper rpl_towupper +# endif +# endif + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswalnum +# else +iswalnum +# endif + (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswalpha +# else +iswalpha +# endif + (wint_t wc) +{ + return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswblank +# else +iswblank +# endif + (wint_t wc) +{ + return wc == ' ' || wc == '\t'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswcntrl +# else +iswcntrl +# endif + (wint_t wc) +{ + return (wc & ~0x1f) == 0 || wc == 0x7f; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswdigit +# else +iswdigit +# endif + (wint_t wc) +{ + return wc >= '0' && wc <= '9'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswgraph +# else +iswgraph +# endif + (wint_t wc) +{ + return wc >= '!' && wc <= '~'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswlower +# else +iswlower +# endif + (wint_t wc) +{ + return wc >= 'a' && wc <= 'z'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswprint +# else +iswprint +# endif + (wint_t wc) +{ + return wc >= ' ' && wc <= '~'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswpunct +# else +iswpunct +# endif + (wint_t wc) +{ + return (wc >= '!' && wc <= '~' + && !((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswspace +# else +iswspace +# endif + (wint_t wc) +{ + return (wc == ' ' || wc == '\t' + || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswupper +# else +iswupper +# endif + (wint_t wc) +{ + return wc >= 'A' && wc <= 'Z'; +} + +static inline int +# if @REPLACE_ISWCNTRL@ +rpl_iswxdigit +# else +iswxdigit +# endif + (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); +} + +static inline wint_t +# if @REPLACE_ISWCNTRL@ +rpl_towlower +# else +towlower +# endif + (wint_t wc) +{ + return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); +} + +static inline wint_t +# if @REPLACE_ISWCNTRL@ +rpl_towupper +# else +towupper +# endif + (wint_t wc) +{ + return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); +} + +#elif ! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@ +/* Only the iswblank function is missing. */ + +# if @REPLACE_ISWBLANK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iswblank rpl_iswblank +# endif +# endif + +static inline int +# if @REPLACE_ISWBLANK@ +rpl_iswblank +# else +iswblank +# endif + (wint_t wc) +{ + return wc == ' ' || wc == '\t'; +} + +#endif + +#if defined __MINGW32__ + +/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t. + The functions towlower and towupper are implemented in the MSVCRT library + to take a wchar_t argument and return a wchar_t result. mingw declares + these functions to take a wint_t argument and return a wint_t result. + This means that: + 1. When the user passes an argument outside the range 0x0000..0xFFFF, the + function will look only at the lower 16 bits. This is allowed according + to POSIX. + 2. The return value is returned in the lower 16 bits of the result register. + The upper 16 bits are random: whatever happened to be in that part of the + result register. We need to fix this by adding a zero-extend from + wchar_t to wint_t after the call. */ + +static inline wint_t +rpl_towlower (wint_t wc) +{ + return (wint_t) (wchar_t) towlower (wc); +} +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define towlower rpl_towlower +# endif + +static inline wint_t +rpl_towupper (wint_t wc) +{ + return (wint_t) (wchar_t) towupper (wc); +} +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define towupper rpl_towupper +# endif + +#endif /* __MINGW32__ */ + +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); +_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); +#else +_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); +# if @REPLACE_ISWBLANK@ +_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); +# else +_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); +# endif +_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); +_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); +#endif +_GL_CXXALIASWARN (iswalnum); +_GL_CXXALIASWARN (iswalpha); +_GL_CXXALIASWARN (iswblank); +_GL_CXXALIASWARN (iswcntrl); +_GL_CXXALIASWARN (iswdigit); +_GL_CXXALIASWARN (iswgraph); +_GL_CXXALIASWARN (iswlower); +_GL_CXXALIASWARN (iswprint); +_GL_CXXALIASWARN (iswpunct); +_GL_CXXALIASWARN (iswspace); +_GL_CXXALIASWARN (iswupper); +_GL_CXXALIASWARN (iswxdigit); + +#if @REPLACE_ISWCNTRL@ || defined __MINGW32__ +_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc)); +_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); +#else +_GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc)); +_GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc)); +#endif +_GL_CXXALIASWARN (towlower); +_GL_CXXALIASWARN (towupper); + + +#endif /* _GL_WCTYPE_H */ +#endif /* _GL_WCTYPE_H */ diff --git a/grub-core/gnulib/xsize.h b/grub-core/gnulib/xsize.h new file mode 100644 index 000000000..fbd63290d --- /dev/null +++ b/grub-core/gnulib/xsize.h @@ -0,0 +1,108 @@ +/* xsize.h -- Checked size_t computations. + + Copyright (C) 2003, 2008, 2009, 2010 Free Software Foundation, Inc. + + This program 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _XSIZE_H +#define _XSIZE_H + +/* Get size_t. */ +#include + +/* Get SIZE_MAX. */ +#include +#if HAVE_STDINT_H +# include +#endif + +/* The size of memory objects is often computed through expressions of + type size_t. Example: + void* p = malloc (header_size + n * element_size). + These computations can lead to overflow. When this happens, malloc() + returns a piece of memory that is way too small, and the program then + crashes while attempting to fill the memory. + To avoid this, the functions and macros in this file check for overflow. + The convention is that SIZE_MAX represents overflow. + malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc + implementation that uses mmap --, it's recommended to use size_overflow_p() + or size_in_bounds_p() before invoking malloc(). + The example thus becomes: + size_t size = xsum (header_size, xtimes (n, element_size)); + void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); +*/ + +/* Convert an arbitrary value >= 0 to type size_t. */ +#define xcast_size_t(N) \ + ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) + +/* Sum of two sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum (size_t size1, size_t size2) +{ + size_t sum = size1 + size2; + return (sum >= size1 ? sum : SIZE_MAX); +} + +/* Sum of three sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum3 (size_t size1, size_t size2, size_t size3) +{ + return xsum (xsum (size1, size2), size3); +} + +/* Sum of four sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) +{ + return xsum (xsum (xsum (size1, size2), size3), size4); +} + +/* Maximum of two sizes, with overflow check. */ +static inline size_t +#if __GNUC__ >= 3 +__attribute__ ((__pure__)) +#endif +xmax (size_t size1, size_t size2) +{ + /* No explicit check is needed here, because for any n: + max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ + return (size1 >= size2 ? size1 : size2); +} + +/* Multiplication of a count with an element size, with overflow check. + The count must be >= 0 and the element size must be > 0. + This is a macro, not an inline function, so that it works correctly even + when N is of a wider type and N > SIZE_MAX. */ +#define xtimes(N, ELSIZE) \ + ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) + +/* Check for overflow. */ +#define size_overflow_p(SIZE) \ + ((SIZE) == SIZE_MAX) +/* Check against overflow. */ +#define size_in_bounds_p(SIZE) \ + ((SIZE) != SIZE_MAX) + +#endif /* _XSIZE_H */ diff --git a/grub-core/lib/posix_wrap/langinfo.h b/grub-core/lib/posix_wrap/langinfo.h index 14833c0b8..72b5b9612 100644 --- a/grub-core/lib/posix_wrap/langinfo.h +++ b/grub-core/lib/posix_wrap/langinfo.h @@ -29,7 +29,7 @@ nl_langinfo (nl_item item) switch (item) { case CODESET: - return locale_charset (); + return "UTF-8"; default: return ""; } diff --git a/grub-core/lib/posix_wrap/localcharset.h b/grub-core/lib/posix_wrap/localcharset.h index 92eb815ec..502d86066 100644 --- a/grub-core/lib/posix_wrap/localcharset.h +++ b/grub-core/lib/posix_wrap/localcharset.h @@ -19,7 +19,7 @@ #ifndef GRUB_POSIX_LOCALCHARSET_H #define GRUB_POSIX_LOCALCHARSET_H 1 -static inline char * +static inline const char * locale_charset (void) { return "UTF-8"; diff --git a/m4/00gnulib.m4 b/m4/00gnulib.m4 new file mode 100644 index 000000000..301469b31 --- /dev/null +++ b/m4/00gnulib.m4 @@ -0,0 +1,30 @@ +# 00gnulib.m4 serial 2 +dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This file must be named something that sorts before all other +dnl gnulib-provided .m4 files. It is needed until such time as we can +dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE semantics. + +# AC_DEFUN_ONCE([NAME], VALUE) +# ---------------------------- +# Define NAME to expand to VALUE on the first use (whether by direct +# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. +# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This +# definition is slower than the version in Autoconf 2.64, because it +# can only use interfaces that existed since 2.59; but it achieves the +# same effect. Quoting is necessary to avoid confusing Automake. +m4_version_prereq([2.63.263], [], +[m4_define([AC][_DEFUN_ONCE], + [AC][_DEFUN([$1], + [AC_REQUIRE([_gl_DEFUN_ONCE([$1])], + [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl +[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) + +# gl_00GNULIB +# ----------- +# Witness macro that this file has been included. Needed to force +# Automake to include this file prior to all other gnulib .m4 files. +AC_DEFUN([gl_00GNULIB]) diff --git a/m4/alloca.m4 b/m4/alloca.m4 new file mode 100644 index 000000000..f3ee34380 --- /dev/null +++ b/m4/alloca.m4 @@ -0,0 +1,47 @@ +# alloca.m4 serial 9 +dnl Copyright (C) 2002-2004, 2006-2007, 2009-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_ALLOCA], +[ + dnl Work around a bug of AC_EGREP_CPP in autoconf-2.57. + AC_REQUIRE([AC_PROG_CPP]) + AC_REQUIRE([AC_PROG_EGREP]) + + AC_REQUIRE([AC_FUNC_ALLOCA]) + if test $ac_cv_func_alloca_works = no; then + gl_PREREQ_ALLOCA + fi + + # Define an additional variable used in the Makefile substitution. + if test $ac_cv_working_alloca_h = yes; then + AC_CACHE_CHECK([for alloca as a compiler built-in], [gl_cv_rpl_alloca], [ + AC_EGREP_CPP([Need own alloca], [ +#if defined __GNUC__ || defined _AIX || defined _MSC_VER + Need own alloca +#endif + ], [gl_cv_rpl_alloca=yes], [gl_cv_rpl_alloca=no]) + ]) + if test $gl_cv_rpl_alloca = yes; then + dnl OK, alloca can be implemented through a compiler built-in. + AC_DEFINE([HAVE_ALLOCA], [1], + [Define to 1 if you have 'alloca' after including , + a header that may be supplied by this distribution.]) + ALLOCA_H=alloca.h + else + dnl alloca exists as a library function, i.e. it is slow and probably + dnl a memory leak. Don't define HAVE_ALLOCA in this case. + ALLOCA_H= + fi + else + ALLOCA_H=alloca.h + fi + AC_SUBST([ALLOCA_H]) +]) + +# Prerequisites of lib/alloca.c. +# STACK_DIRECTION is already handled by AC_FUNC_ALLOCA. +AC_DEFUN([gl_PREREQ_ALLOCA], [:]) diff --git a/m4/argp.m4 b/m4/argp.m4 new file mode 100644 index 000000000..d3ca5bacc --- /dev/null +++ b/m4/argp.m4 @@ -0,0 +1,65 @@ +# argp.m4 serial 11 +dnl Copyright (C) 2003-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ARGP], +[ + AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + dnl argp-parse.c depends on GNU getopt internals, therefore use GNU getopt + dnl always. + gl_REPLACE_GETOPT + dnl Note: gl_REPLACE_GETOPT does AC_LIBOBJ([getopt]), AC_LIBOBJ([getopt1]). + + AC_CHECK_DECL([program_invocation_name], + [AC_DEFINE([HAVE_DECL_PROGRAM_INVOCATION_NAME], [1], + [Define if program_invocation_name is declared])], + [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_NAME], [1], + [Define to 1 to add extern declaration of program_invocation_name to argp.h])], + [#include ]) + AC_CHECK_DECL([program_invocation_short_name], + [AC_DEFINE([HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME], [1], + [Define if program_invocation_short_name is declared])], + [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_SHORT_NAME], [1], + [Define to 1 to add extern declaration of program_invocation_short_name to argp.h])], + [#include ]) + + # Check if program_invocation_name and program_invocation_short_name + # are defined elsewhere. It is improbable that only one of them will + # be defined and other not, I prefer to stay on the safe side and to + # test each one separately. + AC_MSG_CHECKING([whether program_invocation_name is defined]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[program_invocation_name = "test";]])], + [AC_DEFINE([HAVE_PROGRAM_INVOCATION_NAME], [1], + [Define if program_invocation_name is defined]) + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])]) + + AC_MSG_CHECKING([whether program_invocation_short_name is defined]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[program_invocation_short_name = "test";]])], + [AC_DEFINE([HAVE_PROGRAM_INVOCATION_SHORT_NAME], [1], + [Define if program_invocation_short_name is defined]) + AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no])]) + + AC_CHECK_DECLS_ONCE([clearerr_unlocked]) + AC_CHECK_DECLS_ONCE([feof_unlocked]) + AC_CHECK_DECLS_ONCE([ferror_unlocked]) + AC_CHECK_DECLS_ONCE([fflush_unlocked]) + AC_CHECK_DECLS_ONCE([fgets_unlocked]) + AC_CHECK_DECLS_ONCE([fputc_unlocked]) + AC_CHECK_DECLS_ONCE([fputs_unlocked]) + AC_CHECK_DECLS_ONCE([fread_unlocked]) + AC_CHECK_DECLS_ONCE([fwrite_unlocked]) + AC_CHECK_DECLS_ONCE([getc_unlocked]) + AC_CHECK_DECLS_ONCE([getchar_unlocked]) + AC_CHECK_DECLS_ONCE([putc_unlocked]) + AC_CHECK_DECLS_ONCE([putchar_unlocked]) + AC_CHECK_FUNCS_ONCE([flockfile funlockfile]) + AC_CHECK_HEADERS_ONCE([features.h linewrap.h]) +]) diff --git a/m4/asm-underscore.m4 b/m4/asm-underscore.m4 new file mode 100644 index 000000000..1736cc432 --- /dev/null +++ b/m4/asm-underscore.m4 @@ -0,0 +1,48 @@ +# asm-underscore.m4 serial 1 +dnl Copyright (C) 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. Based on as-underscore.m4 in GNU clisp. + +# gl_ASM_SYMBOL_PREFIX +# Tests for the prefix of C symbols at the assembly language level and the +# linker level. This prefix is either an underscore or empty. Defines the +# C macro USER_LABEL_PREFIX to this prefix, and sets ASM_SYMBOL_PREFIX to +# a stringified variant of this prefix. + +AC_DEFUN([gl_ASM_SYMBOL_PREFIX], +[ + dnl We don't use GCC's __USER_LABEL_PREFIX__ here, because + dnl 1. It works only for GCC. + dnl 2. It is incorrectly defined on some platforms, in some GCC versions. + AC_CACHE_CHECK( + [whether C symbols are prefixed with underscore at the linker level], + [gl_cv_prog_as_underscore], + [cat > conftest.c </dev/null 2>&1 + if grep _foo conftest.s >/dev/null ; then + gl_cv_prog_as_underscore=yes + else + gl_cv_prog_as_underscore=no + fi + rm -f conftest* + ]) + if test $gl_cv_prog_as_underscore = yes; then + USER_LABEL_PREFIX=_ + else + USER_LABEL_PREFIX= + fi + AC_DEFINE_UNQUOTED([USER_LABEL_PREFIX], [$USER_LABEL_PREFIX], + [Define to the prefix of C symbols at the assembler and linker level, + either an underscore or empty.]) + ASM_SYMBOL_PREFIX='"'${USER_LABEL_PREFIX}'"' + AC_SUBST([ASM_SYMBOL_PREFIX]) +]) diff --git a/m4/btowc.m4 b/m4/btowc.m4 new file mode 100644 index 000000000..b16b1f020 --- /dev/null +++ b/m4/btowc.m4 @@ -0,0 +1,109 @@ +# btowc.m4 serial 7 +dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_BTOWC], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + + dnl Check whether is usable at all, first. Otherwise the test + dnl program below may lead to an endless loop. See + dnl . + AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) + + AC_CHECK_FUNCS_ONCE([btowc]) + if test $ac_cv_func_btowc = no; then + HAVE_BTOWC=0 + else + + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Cygwin 1.7.2 btowc('\0') is WEOF, not 0. + AC_CACHE_CHECK([whether btowc(0) is correct], + [gl_cv_func_btowc_nul], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + if (btowc ('\0') != 0) + return 1; + return 0; +}]])], + [gl_cv_func_btowc_nul=yes], + [gl_cv_func_btowc_nul=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess no on Cygwin. + cygwin*) gl_cv_func_btowc_nul="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_btowc_nul="guessing yes" ;; + esac +changequote([,])dnl + ]) + ]) + + dnl IRIX 6.5 btowc(EOF) is 0xFF, not WEOF. + AC_CACHE_CHECK([whether btowc(EOF) is correct], + [gl_cv_func_btowc_eof], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on IRIX. + irix*) gl_cv_func_btowc_eof="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_btowc_eof="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#include +int main () +{ + if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) + { + if (btowc (EOF) != WEOF) + return 1; + } + return 0; +}]])], + [gl_cv_func_btowc_eof=yes], + [gl_cv_func_btowc_eof=no], + [:]) + fi + ]) + + case "$gl_cv_func_btowc_nul" in + *yes) ;; + *) REPLACE_BTOWC=1 ;; + esac + case "$gl_cv_func_btowc_eof" in + *yes) ;; + *) REPLACE_BTOWC=1 ;; + esac + fi + if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then + gl_REPLACE_WCHAR_H + AC_LIBOBJ([btowc]) + gl_PREREQ_BTOWC + fi +]) + +# Prerequisites of lib/btowc.c. +AC_DEFUN([gl_PREREQ_BTOWC], [ + : +]) diff --git a/m4/codeset.m4 b/m4/codeset.m4 new file mode 100644 index 000000000..f722b2e86 --- /dev/null +++ b/m4/codeset.m4 @@ -0,0 +1,23 @@ +# codeset.m4 serial 5 (gettext-0.18.2) +dnl Copyright (C) 2000-2002, 2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], [am_cv_langinfo_codeset], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[char* cs = nl_langinfo(CODESET); return !cs;]])], + [am_cv_langinfo_codeset=yes], + [am_cv_langinfo_codeset=no]) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE([HAVE_LANGINFO_CODESET], [1], + [Define if you have and nl_langinfo(CODESET).]) + fi +]) diff --git a/m4/dirname.m4 b/m4/dirname.m4 new file mode 100644 index 000000000..576b5bead --- /dev/null +++ b/m4/dirname.m4 @@ -0,0 +1,26 @@ +#serial 8 -*- autoconf -*- +dnl Copyright (C) 2002-2006, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_DIRNAME], +[ + AC_REQUIRE([gl_DIRNAME_LGPL]) + AC_LIBOBJ([basename]) + AC_LIBOBJ([dirname]) +]) + +AC_DEFUN([gl_DIRNAME_LGPL], +[ + AC_LIBOBJ([basename-lgpl]) + AC_LIBOBJ([dirname-lgpl]) + AC_LIBOBJ([stripslash]) + + dnl Prerequisites of lib/dirname.h. + AC_REQUIRE([gl_AC_DOS]) + AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) + + dnl No prerequisites of lib/basename-lgpl.c, lib/dirname-lgpl.c, + dnl lib/stripslash.c. +]) diff --git a/m4/dos.m4 b/m4/dos.m4 new file mode 100644 index 000000000..5660542be --- /dev/null +++ b/m4/dos.m4 @@ -0,0 +1,71 @@ +#serial 11 -*- autoconf -*- + +# Define some macros required for proper operation of code in lib/*.c +# on MSDOS/Windows systems. + +# Copyright (C) 2000-2001, 2004-2006, 2009-2010 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# From Jim Meyering. + +AC_DEFUN([gl_AC_DOS], + [ + AC_CACHE_CHECK([whether system is Windows or MSDOS], [ac_cv_win_or_dos], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__ +neither MSDOS nor Windows +#endif]])], + [ac_cv_win_or_dos=yes], + [ac_cv_win_or_dos=no]) + ]) + + if test x"$ac_cv_win_or_dos" = xyes; then + ac_fs_accepts_drive_letter_prefix=1 + ac_fs_backslash_is_file_name_separator=1 + AC_CACHE_CHECK([whether drive letter can start relative path], + [ac_cv_drive_letter_can_be_relative], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#if defined __CYGWIN__ +drive letters are always absolute +#endif]])], + [ac_cv_drive_letter_can_be_relative=yes], + [ac_cv_drive_letter_can_be_relative=no]) + ]) + if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then + ac_fs_drive_letter_can_be_relative=1 + else + ac_fs_drive_letter_can_be_relative=0 + fi + else + ac_fs_accepts_drive_letter_prefix=0 + ac_fs_backslash_is_file_name_separator=0 + ac_fs_drive_letter_can_be_relative=0 + fi + + AC_DEFINE_UNQUOTED([FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX], + $ac_fs_accepts_drive_letter_prefix, + [Define on systems for which file names may have a so-called + `drive letter' prefix, define this to compute the length of that + prefix, including the colon.]) + + AH_VERBATIM(ISSLASH, + [#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#else +# define ISSLASH(C) ((C) == '/') +#endif]) + + AC_DEFINE_UNQUOTED([FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR], + $ac_fs_backslash_is_file_name_separator, + [Define if the backslash character may also serve as a file name + component separator.]) + + AC_DEFINE_UNQUOTED([FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE], + $ac_fs_drive_letter_can_be_relative, + [Define if a drive letter prefix denotes a relative path if it is + not followed by a file name component separator.]) + ]) diff --git a/m4/double-slash-root.m4 b/m4/double-slash-root.m4 new file mode 100644 index 000000000..66a79c0f2 --- /dev/null +++ b/m4/double-slash-root.m4 @@ -0,0 +1,38 @@ +# double-slash-root.m4 serial 4 -*- Autoconf -*- +dnl Copyright (C) 2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_DOUBLE_SLASH_ROOT], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether // is distinct from /], [gl_cv_double_slash_root], + [ if test x"$cross_compiling" = xyes ; then + # When cross-compiling, there is no way to tell whether // is special + # short of a list of hosts. However, the only known hosts to date + # that have a distinct // are Apollo DomainOS (too old to port to), + # Cygwin, and z/OS. If anyone knows of another system for which // has + # special semantics and is distinct from /, please report it to + # . + case $host in + *-cygwin | i370-ibm-openedition) + gl_cv_double_slash_root=yes ;; + *) + # Be optimistic and assume that / and // are the same when we + # don't know. + gl_cv_double_slash_root='unknown, assuming no' ;; + esac + else + set x `ls -di / // 2>/dev/null` + if test "$[2]" = "$[4]" && wc //dev/null >/dev/null 2>&1; then + gl_cv_double_slash_root=no + else + gl_cv_double_slash_root=yes + fi + fi]) + if test "$gl_cv_double_slash_root" = yes; then + AC_DEFINE([DOUBLE_SLASH_IS_DISTINCT_ROOT], [1], + [Define to 1 if // is a file system root distinct from /.]) + fi +]) diff --git a/m4/errno_h.m4 b/m4/errno_h.m4 new file mode 100644 index 000000000..d02a03936 --- /dev/null +++ b/m4/errno_h.m4 @@ -0,0 +1,115 @@ +# errno_h.m4 serial 6 +dnl Copyright (C) 2004, 2006, 2008, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ + AC_EGREP_CPP([booboo],[ +#include +#if !defined ENOMSG +booboo +#endif +#if !defined EIDRM +booboo +#endif +#if !defined ENOLINK +booboo +#endif +#if !defined EPROTO +booboo +#endif +#if !defined EMULTIHOP +booboo +#endif +#if !defined EBADMSG +booboo +#endif +#if !defined EOVERFLOW +booboo +#endif +#if !defined ENOTSUP +booboo +#endif +#if !defined ESTALE +booboo +#endif +#if !defined ECANCELED +booboo +#endif + ], + [gl_cv_header_errno_h_complete=no], + [gl_cv_header_errno_h_complete=yes]) + ]) + if test $gl_cv_header_errno_h_complete = yes; then + ERRNO_H='' + else + gl_CHECK_NEXT_HEADERS([errno.h]) + ERRNO_H='errno.h' + fi + AC_SUBST([ERRNO_H]) + gl_REPLACE_ERRNO_VALUE([EMULTIHOP]) + gl_REPLACE_ERRNO_VALUE([ENOLINK]) + gl_REPLACE_ERRNO_VALUE([EOVERFLOW]) +]) + +# Assuming $1 = EOVERFLOW. +# The EOVERFLOW errno value ought to be defined in , according to +# POSIX. But some systems (like OpenBSD 4.0 or AIX 3) don't define it, and +# some systems (like OSF/1) define it when _XOPEN_SOURCE_EXTENDED is defined. +# Check for the value of EOVERFLOW. +# Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE. +AC_DEFUN([gl_REPLACE_ERRNO_VALUE], +[ + if test -n "$ERRNO_H"; then + AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [ + AC_EGREP_CPP([yes],[ +#include +#ifdef ]$1[ +yes +#endif + ], + [gl_cv_header_errno_h_]$1[=yes], + [gl_cv_header_errno_h_]$1[=no]) + if test $gl_cv_header_errno_h_]$1[ = no; then + AC_EGREP_CPP([yes],[ +#define _XOPEN_SOURCE_EXTENDED 1 +#include +#ifdef ]$1[ +yes +#endif + ], [gl_cv_header_errno_h_]$1[=hidden]) + if test $gl_cv_header_errno_h_]$1[ = hidden; then + dnl The macro exists but is hidden. + dnl Define it to the same value. + AC_COMPUTE_INT([gl_cv_header_errno_h_]$1, $1, [ +#define _XOPEN_SOURCE_EXTENDED 1 +#include +/* The following two lines are a workaround against an autoconf-2.52 bug. */ +#include +#include +]) + fi + fi + ]) + case $gl_cv_header_errno_h_]$1[ in + yes | no) + ]$1[_HIDDEN=0; ]$1[_VALUE= + ;; + *) + ]$1[_HIDDEN=1; ]$1[_VALUE="$gl_cv_header_errno_h_]$1[" + ;; + esac + AC_SUBST($1[_HIDDEN]) + AC_SUBST($1[_VALUE]) + fi +]) + +dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +dnl Remove this when we can assume autoconf >= 2.61. +m4_ifdef([AC_COMPUTE_INT], [], [ + AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +]) diff --git a/m4/error.m4 b/m4/error.m4 new file mode 100644 index 000000000..dd5a197b6 --- /dev/null +++ b/m4/error.m4 @@ -0,0 +1,39 @@ +#serial 13 + +# Copyright (C) 1996-1998, 2001-2004, 2009-2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ERROR], +[ + AC_FUNC_ERROR_AT_LINE + dnl Note: AC_FUNC_ERROR_AT_LINE does AC_LIBSOURCES([error.h, error.c]). + gl_PREREQ_ERROR +]) + +# Redefine AC_FUNC_ERROR_AT_LINE, because it is no longer maintained in +# Autoconf. +AC_DEFUN([AC_FUNC_ERROR_AT_LINE], +[ + AC_LIBSOURCES([error.h, error.c])dnl + AC_CACHE_CHECK([for error_at_line], [ac_cv_lib_error_at_line], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[error_at_line (0, 0, "", 0, "an error occurred");]])], + [ac_cv_lib_error_at_line=yes], + [ac_cv_lib_error_at_line=no])]) + if test $ac_cv_lib_error_at_line = no; then + AC_LIBOBJ([error]) + fi +]) + +# Prerequisites of lib/error.c. +AC_DEFUN([gl_PREREQ_ERROR], +[ + AC_REQUIRE([AC_FUNC_STRERROR_R]) + AC_REQUIRE([AC_C_INLINE]) + : +]) diff --git a/m4/extensions.m4 b/m4/extensions.m4 new file mode 100644 index 000000000..7d9458a8d --- /dev/null +++ b/m4/extensions.m4 @@ -0,0 +1,118 @@ +# serial 9 -*- Autoconf -*- +# Enable extensions on systems that normally disable them. + +# Copyright (C) 2003, 2006-2010 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from CVS +# Autoconf. Perhaps we can remove this once we can assume Autoconf +# 2.62 or later everywhere, but since CVS Autoconf mutates rapidly +# enough in this area it's likely we'll need to redefine +# AC_USE_SYSTEM_EXTENSIONS for quite some time. + +# If autoconf reports a warning +# warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +# or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +# the fix is +# 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked +# but always AC_REQUIREd, +# 2) to ensure that for each occurrence of +# AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +# or +# AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) +# the corresponding gnulib module description has 'extensions' among +# its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS +# invocation occurs in gl_EARLY, not in gl_INIT. + +# AC_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +# Remember that #undef in AH_VERBATIM gets replaced with #define by +# AC_DEFINE. The goal here is to define all known feature-enabling +# macros, then, if reports of conflicts are made, disable macros that +# cause problems on some platforms (such as __EXTENSIONS__). +AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], +[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl + + AC_REQUIRE([AC_CANONICAL_HOST]) + + AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) + if test "$MINIX" = yes; then + AC_DEFINE([_POSIX_SOURCE], [1], + [Define to 1 if you need to in order for `stat' and other + things to work.]) + AC_DEFINE([_POSIX_1_SOURCE], [2], + [Define to 2 if the system does not provide POSIX.1 features + except with this defined.]) + AC_DEFINE([_MINIX], [1], + [Define to 1 if on MINIX.]) + fi + + dnl HP-UX 11.11 defines mbstate_t only if _XOPEN_SOURCE is defined to 500, + dnl regardless of whether the flags -Ae or _D_HPUX_SOURCE=1 are already + dnl provided. + case "$host_os" in + hpux*) + AC_DEFINE([_XOPEN_SOURCE], [500], + [Define to 500 only on HP-UX.]) + ;; + esac + + AH_VERBATIM([__EXTENSIONS__], +[/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +]) + AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], + [ac_cv_safe_to_define___extensions__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +# define __EXTENSIONS__ 1 + ]AC_INCLUDES_DEFAULT])], + [ac_cv_safe_to_define___extensions__=yes], + [ac_cv_safe_to_define___extensions__=no])]) + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_ALL_SOURCE]) + AC_DEFINE([_GNU_SOURCE]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([_TANDEM_SOURCE]) +])# AC_USE_SYSTEM_EXTENSIONS + +# gl_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], +[ + dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. + dnl gnulib does not need it. But if it gets required by third-party macros + dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a + dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". + dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, + dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. + AC_REQUIRE([AC_GNU_SOURCE]) + + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +]) diff --git a/m4/fcntl-o.m4 b/m4/fcntl-o.m4 new file mode 100644 index 000000000..1adacc8ab --- /dev/null +++ b/m4/fcntl-o.m4 @@ -0,0 +1,85 @@ +# fcntl-o.m4 serial 2 +dnl Copyright (C) 2006, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Paul Eggert. + +# Test whether the flags O_NOATIME and O_NOFOLLOW actually work. +# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. +# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. +AC_DEFUN([gl_FCNTL_O_FLAGS], +[ + dnl Persuade glibc to define O_NOATIME and O_NOFOLLOW. + dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes + dnl AC_GNU_SOURCE. + m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], + [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], + [AC_REQUIRE([AC_GNU_SOURCE])]) + AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + #include + #include + #ifndef O_NOATIME + #define O_NOATIME 0 + #endif + #ifndef O_NOFOLLOW + #define O_NOFOLLOW 0 + #endif + static int const constants[] = + { + O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, + O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY + }; + ]], + [[ + int status = !constants; + { + static char const sym[] = "conftest.sym"; + if (symlink (".", sym) != 0 + || close (open (sym, O_RDONLY | O_NOFOLLOW)) == 0) + status |= 32; + unlink (sym); + } + { + static char const file[] = "confdefs.h"; + int fd = open (file, O_RDONLY | O_NOATIME); + char c; + struct stat st0, st1; + if (fd < 0 + || fstat (fd, &st0) != 0 + || sleep (1) != 0 + || read (fd, &c, 1) != 1 + || close (fd) != 0 + || stat (file, &st1) != 0 + || st0.st_atime != st1.st_atime) + status |= 64; + } + return status;]])], + [gl_cv_header_working_fcntl_h=yes], + [case $? in #( + 32) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( + 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( + 96) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( + *) gl_cv_header_working_fcntl_h='no';; + esac], + [gl_cv_header_working_fcntl_h=cross-compiling])]) + + case $gl_cv_header_working_fcntl_h in #( + *O_NOATIME* | no | cross-compiling) ac_val=0;; #( + *) ac_val=1;; + esac + AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val], + [Define to 1 if O_NOATIME works.]) + + case $gl_cv_header_working_fcntl_h in #( + *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( + *) ac_val=1;; + esac + AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val], + [Define to 1 if O_NOFOLLOW works.]) +]) diff --git a/m4/float_h.m4 b/m4/float_h.m4 new file mode 100644 index 000000000..f6099db40 --- /dev/null +++ b/m4/float_h.m4 @@ -0,0 +1,19 @@ +# float_h.m4 serial 4 +dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FLOAT_H], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + FLOAT_H= + case "$host_os" in + beos* | openbsd* | mirbsd*) + FLOAT_H=float.h + gl_CHECK_NEXT_HEADERS([float.h]) + ;; + esac + AC_SUBST([FLOAT_H]) +]) diff --git a/m4/fnmatch.m4 b/m4/fnmatch.m4 new file mode 100644 index 000000000..212ead572 --- /dev/null +++ b/m4/fnmatch.m4 @@ -0,0 +1,121 @@ +# Check for fnmatch - serial 4. + +# Copyright (C) 2000-2007, 2009-2010 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Autoconf defines AC_FUNC_FNMATCH, but that is obsolescent. +# New applications should use the macros below instead. + +# Request a POSIX compliant fnmatch function. +AC_DEFUN([gl_FUNC_FNMATCH_POSIX], +[ + m4_divert_text([DEFAULTS], [gl_fnmatch_required=POSIX]) + + dnl Persuade glibc to declare FNM_CASEFOLD etc. + dnl This is only needed if gl_fnmatch_required = GNU. It would be possible + dnl to avoid this dependency for gl_FUNC_FNMATCH_POSIX by putting + dnl gl_FUNC_FNMATCH_GNU into a separate .m4 file. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + FNMATCH_H= + gl_fnmatch_required_lowercase=`echo $gl_fnmatch_required | tr 'A-Z' 'a-z'` + gl_fnmatch_cache_var="gl_cv_func_fnmatch_${gl_fnmatch_required_lowercase}" + AC_CACHE_CHECK([for working $gl_fnmatch_required fnmatch], + [$gl_fnmatch_cache_var], + [dnl Some versions of Solaris, SCO, and the GNU C Library + dnl have a broken or incompatible fnmatch. + dnl So we run a test program. If we are cross-compiling, take no chance. + dnl Thanks to John Oleynick, François Pinard, and Paul Eggert for this + dnl test. + if test $gl_fnmatch_required = GNU; then + gl_fnmatch_gnu_start= + gl_fnmatch_gnu_end= + else + gl_fnmatch_gnu_start='#if 0' + gl_fnmatch_gnu_end='#endif' + fi + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + static int + y (char const *pattern, char const *string, int flags) + { + return fnmatch (pattern, string, flags) == 0; + } + static int + n (char const *pattern, char const *string, int flags) + { + return fnmatch (pattern, string, flags) == FNM_NOMATCH; + } + ]], + [[char const *Apat = 'A' < '\\\\' ? "[A-\\\\\\\\]" : "[\\\\\\\\-A]"; + char const *apat = 'a' < '\\\\' ? "[a-\\\\\\\\]" : "[\\\\\\\\-a]"; + static char const A_1[] = { 'A' - 1, 0 }; + static char const A01[] = { 'A' + 1, 0 }; + static char const a_1[] = { 'a' - 1, 0 }; + static char const a01[] = { 'a' + 1, 0 }; + static char const bs_1[] = { '\\\\' - 1, 0 }; + static char const bs01[] = { '\\\\' + 1, 0 }; + return + !(n ("a*", "", 0) + && y ("a*", "abc", 0) + && n ("d*/*1", "d/s/1", FNM_PATHNAME) + && y ("a\\\\bc", "abc", 0) + && n ("a\\\\bc", "abc", FNM_NOESCAPE) + && y ("*x", ".x", 0) + && n ("*x", ".x", FNM_PERIOD) + && y (Apat, "\\\\", 0) && y (Apat, "A", 0) + && y (apat, "\\\\", 0) && y (apat, "a", 0) + && n (Apat, A_1, 0) == ('A' < '\\\\') + && n (apat, a_1, 0) == ('a' < '\\\\') + && y (Apat, A01, 0) == ('A' < '\\\\') + && y (apat, a01, 0) == ('a' < '\\\\') + && y (Apat, bs_1, 0) == ('A' < '\\\\') + && y (apat, bs_1, 0) == ('a' < '\\\\') + && n (Apat, bs01, 0) == ('A' < '\\\\') + && n (apat, bs01, 0) == ('a' < '\\\\') + $gl_fnmatch_gnu_start + && y ("xxXX", "xXxX", FNM_CASEFOLD) + && y ("a++(x|yy)b", "a+xyyyyxb", FNM_EXTMATCH) + && n ("d*/*1", "d/s/1", FNM_FILE_NAME) + && y ("*", "x", FNM_FILE_NAME | FNM_LEADING_DIR) + && y ("x*", "x/y/z", FNM_FILE_NAME | FNM_LEADING_DIR) + && y ("*c*", "c/x", FNM_FILE_NAME | FNM_LEADING_DIR) + $gl_fnmatch_gnu_end + ); + ]])], + [eval "$gl_fnmatch_cache_var=yes"], + [eval "$gl_fnmatch_cache_var=no"], + [eval "$gl_fnmatch_cache_var=\"guessing no\""]) + ]) + eval "gl_fnmatch_result=\"\$$gl_fnmatch_cache_var\"" + if test "$gl_fnmatch_result" = yes; then + dnl Not strictly necessary. Only to avoid spurious leftover files if people + dnl don't do "make distclean". + rm -f "$gl_source_base/fnmatch.h" + else + FNMATCH_H=fnmatch.h + AC_LIBOBJ([fnmatch]) + dnl We must choose a different name for our function, since on ELF systems + dnl a broken fnmatch() in libc.so would override our fnmatch() if it is + dnl compiled into a shared library. + AC_DEFINE_UNQUOTED([fnmatch], [${gl_fnmatch_required_lowercase}_fnmatch], + [Define to a replacement function name for fnmatch().]) + dnl Prerequisites of lib/fnmatch.c. + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + AC_CHECK_DECLS([isblank], [], [], [#include ]) + AC_CHECK_FUNCS_ONCE([btowc isblank iswctype mbsrtowcs mempcpy wmemchr wmemcpy wmempcpy]) + AC_CHECK_HEADERS_ONCE([wctype.h]) + fi + AC_SUBST([FNMATCH_H]) +]) + +# Request a POSIX compliant fnmatch function with GNU extensions. +AC_DEFUN([gl_FUNC_FNMATCH_GNU], +[ + m4_divert_text([INIT_PREPARE], [gl_fnmatch_required=GNU]) + + AC_REQUIRE([gl_FUNC_FNMATCH_POSIX]) +]) diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 new file mode 100644 index 000000000..4beb1501c --- /dev/null +++ b/m4/getdelim.m4 @@ -0,0 +1,90 @@ +# getdelim.m4 serial 6 + +dnl Copyright (C) 2005-2007, 2009-2010 Free Software Foundation, Inc. +dnl +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_PREREQ([2.59]) + +AC_DEFUN([gl_FUNC_GETDELIM], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + + dnl Persuade glibc to declare getdelim(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([getdelim]) + + AC_CHECK_FUNCS_ONCE([getdelim]) + if test $ac_cv_func_getdelim = yes; then + dnl Found it in some library. Verify that it works. + AC_CACHE_CHECK([for working getdelim function], [gl_cv_func_working_getdelim], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +# include +# include +# include + int main () + { + FILE *in = fopen ("./conftest.data", "r"); + if (!in) + return 1; + { + /* Test result for a NULL buffer and a zero size. + Based on a test program from Karl Heuer. */ + char *line = NULL; + size_t siz = 0; + int len = getdelim (&line, &siz, '\n', in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) + return 1; + } + { + /* Test result for a NULL buffer and a non-zero size. + This crashes on FreeBSD 8.0. */ + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getdelim (&line, &siz, '\n', in) == -1) + return 1; + } + return 0; + } + ]])], [gl_cv_func_working_getdelim=yes] dnl The library version works. + , [gl_cv_func_working_getdelim=no] dnl The library version does NOT work. + , dnl We're cross compiling. Assume it works on glibc2 systems. + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) + Lucky GNU user + #endif +#endif + ], + [gl_cv_func_working_getdelim=yes], + [gl_cv_func_working_getdelim=no])] + )]) + else + gl_cv_func_working_getdelim=no + fi + + if test $ac_cv_have_decl_getdelim = no; then + HAVE_DECL_GETDELIM=0 + fi + + if test $gl_cv_func_working_getdelim = no; then + if test $ac_cv_func_getdelim = yes; then + REPLACE_GETDELIM=1 + fi + AC_LIBOBJ([getdelim]) + gl_PREREQ_GETDELIM + fi +]) + +# Prerequisites of lib/getdelim.c. +AC_DEFUN([gl_PREREQ_GETDELIM], +[ + AC_CHECK_FUNCS([flockfile funlockfile]) + AC_CHECK_DECLS([getc_unlocked]) +]) diff --git a/m4/getline.m4 b/m4/getline.m4 new file mode 100644 index 000000000..83005600d --- /dev/null +++ b/m4/getline.m4 @@ -0,0 +1,97 @@ +# getline.m4 serial 21 + +dnl Copyright (C) 1998-2003, 2005-2007, 2009-2010 Free Software Foundation, +dnl Inc. +dnl +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_PREREQ([2.59]) + +dnl See if there's a working, system-supplied version of the getline function. +dnl We can't just do AC_REPLACE_FUNCS([getline]) because some systems +dnl have a function by that name in -linet that doesn't have anything +dnl to do with the function we need. +AC_DEFUN([gl_FUNC_GETLINE], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + + dnl Persuade glibc to declare getline(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([getline]) + + gl_getline_needs_run_time_check=no + AC_CHECK_FUNC([getline], + [dnl Found it in some library. Verify that it works. + gl_getline_needs_run_time_check=yes], + [am_cv_func_working_getline=no]) + if test $gl_getline_needs_run_time_check = yes; then + AC_CACHE_CHECK([for working getline function], [am_cv_func_working_getline], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +# include +# include +# include + int main () + { + FILE *in = fopen ("./conftest.data", "r"); + if (!in) + return 1; + { + /* Test result for a NULL buffer and a zero size. + Based on a test program from Karl Heuer. */ + char *line = NULL; + size_t siz = 0; + int len = getline (&line, &siz, in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) + return 1; + } + { + /* Test result for a NULL buffer and a non-zero size. + This crashes on FreeBSD 8.0. */ + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getline (&line, &siz, in) == -1) + return 1; + } + return 0; + } + ]])], [am_cv_func_working_getline=yes] dnl The library version works. + , [am_cv_func_working_getline=no] dnl The library version does NOT work. + , dnl We're cross compiling. Assume it works on glibc2 systems. + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) + Lucky GNU user + #endif +#endif + ], + [am_cv_func_working_getline=yes], + [am_cv_func_working_getline=no])] + )]) + fi + + if test $ac_cv_have_decl_getline = no; then + HAVE_DECL_GETLINE=0 + fi + + if test $am_cv_func_working_getline = no; then + dnl Set REPLACE_GETLINE always: Even if we have not found the broken + dnl getline function among $LIBS, it may exist in libinet and the + dnl executable may be linked with -linet. + REPLACE_GETLINE=1 + AC_LIBOBJ([getline]) + + gl_PREREQ_GETLINE + fi +]) + +# Prerequisites of lib/getline.c. +AC_DEFUN([gl_PREREQ_GETLINE], +[ + gl_FUNC_GETDELIM +]) diff --git a/m4/getopt.m4 b/m4/getopt.m4 new file mode 100644 index 000000000..d05e9d914 --- /dev/null +++ b/m4/getopt.m4 @@ -0,0 +1,318 @@ +# getopt.m4 serial 31 +dnl Copyright (C) 2002-2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Request a POSIX compliant getopt function. +AC_DEFUN([gl_FUNC_GETOPT_POSIX], +[ + m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX]) + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + gl_GETOPT_IFELSE([ + gl_REPLACE_GETOPT + ], + []) +]) + +# Request a POSIX compliant getopt function with GNU extensions (such as +# options with optional arguments) and the functions getopt_long, +# getopt_long_only. +AC_DEFUN([gl_FUNC_GETOPT_GNU], +[ + m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU]) + + AC_REQUIRE([gl_FUNC_GETOPT_POSIX]) +]) + +# Request the gnulib implementation of the getopt functions unconditionally. +# argp.m4 uses this. +AC_DEFUN([gl_REPLACE_GETOPT], +[ + dnl Arrange for getopt.h to be created. + gl_GETOPT_SUBSTITUTE_HEADER + dnl Arrange for unistd.h to include getopt.h. + GNULIB_UNISTD_H_GETOPT=1 + dnl Arrange to compile the getopt implementation. + AC_LIBOBJ([getopt]) + AC_LIBOBJ([getopt1]) + gl_PREREQ_GETOPT +]) + +# emacs' configure.in uses this. +AC_DEFUN([gl_GETOPT_IFELSE], +[ + AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) + AS_IF([test -n "$gl_replace_getopt"], [$1], [$2]) +]) + +# Determine whether to replace the entire getopt facility. +AC_DEFUN([gl_GETOPT_CHECK_HEADERS], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([AC_PROG_AWK]) dnl for awk that supports ENVIRON + + dnl Persuade Solaris to declare optarg, optind, opterr, optopt. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + gl_CHECK_NEXT_HEADERS([getopt.h]) + AC_CHECK_HEADERS_ONCE([getopt.h]) + if test $ac_cv_header_getopt_h = yes; then + HAVE_GETOPT_H=1 + else + HAVE_GETOPT_H=0 + fi + AC_SUBST([HAVE_GETOPT_H]) + + gl_replace_getopt= + + dnl Test whether is available. + if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then + AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes]) + fi + + dnl Test whether the function getopt_long is available. + if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then + AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes]) + fi + + dnl BSD getopt_long uses an incompatible method to reset option processing. + dnl Existence of the variable, in and of itself, is not a reason to replace + dnl getopt, but knowledge of the variable is needed to determine how to + dnl reset and whether a reset reparses the environment. + dnl Solaris supports neither optreset nor optind=0, but keeps no state that + dnl needs a reset beyond setting optind=1; detect Solaris by getopt_clip. + if test -z "$gl_replace_getopt"; then + AC_CHECK_DECLS([optreset], [], + [AC_CHECK_DECLS([getopt_clip], [], [], + [[#include ]]) + ], + [[#include ]]) + fi + + dnl mingw's getopt (in libmingwex.a) does weird things when the options + dnl strings starts with '+' and it's not the first call. Some internal state + dnl is left over from earlier calls, and neither setting optind = 0 nor + dnl setting optreset = 1 get rid of this internal state. + dnl POSIX is silent on optind vs. optreset, so we allow either behavior. + dnl POSIX 2008 does not specify leading '+' behavior, but see + dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on + dnl the next version of POSIX. For now, we only guarantee leading '+' + dnl behavior with getopt-gnu. + if test -z "$gl_replace_getopt"; then + AC_CACHE_CHECK([whether getopt is POSIX compatible], + [gl_cv_func_getopt_posix], + [ + dnl This test fails on mingw and succeeds on many other platforms. + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include + +#if !HAVE_DECL_OPTRESET && !HAVE_DECL_GETOPT_CLIP +# define OPTIND_MIN 0 +#else +# define OPTIND_MIN 1 +#endif + +int +main () +{ + { + int argc = 0; + char *argv[10]; + int c; + + argv[argc++] = "program"; + argv[argc++] = "-a"; + argv[argc++] = "foo"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = OPTIND_MIN; + opterr = 0; + + c = getopt (argc, argv, "ab"); + if (!(c == 'a')) + return 1; + c = getopt (argc, argv, "ab"); + if (!(c == -1)) + return 2; + if (!(optind == 2)) + return 3; + } + /* Some internal state exists at this point. */ + { + int argc = 0; + char *argv[10]; + int c; + + argv[argc++] = "program"; + argv[argc++] = "donald"; + argv[argc++] = "-p"; + argv[argc++] = "billy"; + argv[argc++] = "duck"; + argv[argc++] = "-a"; + argv[argc++] = "bar"; + argv[argc] = NULL; + optind = OPTIND_MIN; + opterr = 0; + + c = getopt (argc, argv, "+abp:q:"); + if (!(c == -1)) + return 4; + if (!(strcmp (argv[0], "program") == 0)) + return 5; + if (!(strcmp (argv[1], "donald") == 0)) + return 6; + if (!(strcmp (argv[2], "-p") == 0)) + return 7; + if (!(strcmp (argv[3], "billy") == 0)) + return 8; + if (!(strcmp (argv[4], "duck") == 0)) + return 9; + if (!(strcmp (argv[5], "-a") == 0)) + return 10; + if (!(strcmp (argv[6], "bar") == 0)) + return 11; + if (!(optind == 1)) + return 12; + } + /* Detect MacOS 10.5, AIX 7.1 bug. */ + { + char *argv[3] = { "program", "-ab", NULL }; + optind = OPTIND_MIN; + opterr = 0; + if (getopt (2, argv, "ab:") != 'a') + return 13; + if (getopt (2, argv, "ab:") != '?') + return 14; + if (optopt != 'b') + return 15; + if (optind != 2) + return 16; + } + + return 0; +} +]])], + [gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no], + [case "$host_os" in + mingw*) gl_cv_func_getopt_posix="guessing no";; + darwin* | aix*) gl_cv_func_getopt_posix="guessing no";; + *) gl_cv_func_getopt_posix="guessing yes";; + esac + ]) + ]) + case "$gl_cv_func_getopt_posix" in + *no) gl_replace_getopt=yes ;; + esac + fi + + if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then + AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], + [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the + # optstring is necessary for programs like m4 that have POSIX-mandated + # semantics for supporting options interspersed with files. + # Also, since getopt_long is a GNU extension, we require optind=0. + # Bash ties 'set -o posix' to a non-exported POSIXLY_CORRECT; + # so take care to revert to the correct (non-)export state. +dnl GNU Coding Standards currently allow awk but not env; besides, env +dnl is ambiguous with environment values that contain newlines. + gl_awk_probe='BEGIN { if ("POSIXLY_CORRECT" in ENVIRON) print "x" }' + case ${POSIXLY_CORRECT+x}`$AWK "$gl_awk_probe" + #include + #include + ]], [[ + /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, + and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, + OSF/1 5.1, Solaris 10. */ + { + char *myargv[3]; + myargv[0] = "conftest"; + myargv[1] = "-+"; + myargv[2] = 0; + opterr = 0; + if (getopt (2, myargv, "+a") != '?') + return 1; + } + /* This code succeeds on glibc 2.8, mingw, + and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, + IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ + { + char *argv[] = { "program", "-p", "foo", "bar", NULL }; + + optind = 1; + if (getopt (4, argv, "p::") != 'p') + return 2; + if (optarg != NULL) + return 3; + if (getopt (4, argv, "p::") != -1) + return 4; + if (optind != 2) + return 5; + } + /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ + { + char *argv[] = { "program", "foo", "-p", NULL }; + optind = 0; + if (getopt (3, argv, "-p") != 1) + return 6; + if (getopt (3, argv, "-p") != 'p') + return 7; + } + /* This code fails on glibc 2.11. */ + { + char *argv[] = { "program", "-b", "-a", NULL }; + optind = opterr = 0; + if (getopt (3, argv, "+:a:b") != 'b') + return 8; + if (getopt (3, argv, "+:a:b") != ':') + return 9; + } + return 0; + ]])], + [gl_cv_func_getopt_gnu=yes], + [gl_cv_func_getopt_gnu=no], + [dnl Cross compiling. Guess based on host and declarations. + case $host_os:$ac_cv_have_decl_optreset in + *-gnu*:* | mingw*:*) gl_cv_func_getopt_gnu=no;; + *:yes) gl_cv_func_getopt_gnu=no;; + *) gl_cv_func_getopt_gnu=yes;; + esac + ]) + case $gl_had_POSIXLY_CORRECT in + exported) ;; + yes) AS_UNSET([POSIXLY_CORRECT]); POSIXLY_CORRECT=1 ;; + *) AS_UNSET([POSIXLY_CORRECT]) ;; + esac + ]) + if test "$gl_cv_func_getopt_gnu" = "no"; then + gl_replace_getopt=yes + fi + fi +]) + +# emacs' configure.in uses this. +AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], +[ + GETOPT_H=getopt.h + AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], + [Define to rpl_ if the getopt replacement functions and variables + should be used.]) + AC_SUBST([GETOPT_H]) +]) + +# Prerequisites of lib/getopt*. +# emacs' configure.in uses this. +AC_DEFUN([gl_PREREQ_GETOPT], +[ + AC_CHECK_DECLS_ONCE([getenv]) +]) diff --git a/m4/glibc21.m4 b/m4/glibc21.m4 new file mode 100644 index 000000000..68ada9d4d --- /dev/null +++ b/m4/glibc21.m4 @@ -0,0 +1,30 @@ +# glibc21.m4 serial 4 +dnl Copyright (C) 2000-2002, 2004, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([gl_GLIBC21], + [ + AC_CACHE_CHECK([whether we are using the GNU C Library 2.1 or newer], + [ac_cv_gnu_library_2_1], + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + [ac_cv_gnu_library_2_1=yes], + [ac_cv_gnu_library_2_1=no]) + ] + ) + AC_SUBST([GLIBC21]) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 new file mode 100644 index 000000000..799c4f954 --- /dev/null +++ b/m4/gnulib-cache.m4 @@ -0,0 +1,41 @@ +# Copyright (C) 2002-2010 Free Software Foundation, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the specification of how gnulib-tool is used. +# It acts as a cache: It is written and read by gnulib-tool. +# In projects that use version control, this file is meant to be put under +# version control, like the configure.ac and various Makefile.am files. + + +# Specification in the form of a command-line invocation: +# gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline progname regex + +# Specification in the form of a few gnulib-tool.m4 macro invocations: +gl_LOCAL_DIR([]) +gl_MODULES([ + argp + error + fnmatch + getdelim + getline + progname + regex +]) +gl_AVOID([]) +gl_SOURCE_BASE([grub-core/gnulib]) +gl_M4_BASE([m4]) +gl_PO_BASE([]) +gl_DOC_BASE([doc]) +gl_TESTS_BASE([tests]) +gl_LIB([libgnu]) +gl_MAKEFILE_NAME([]) +gl_MACRO_PREFIX([gl]) +gl_PO_DOMAIN([]) +gl_VC_FILES([false]) diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 new file mode 100644 index 000000000..4c7ac30d0 --- /dev/null +++ b/m4/gnulib-common.m4 @@ -0,0 +1,201 @@ +# gnulib-common.m4 serial 20 +dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# gl_COMMON +# is expanded unconditionally through gnulib-tool magic. +AC_DEFUN([gl_COMMON], [ + dnl Use AC_REQUIRE here, so that the code is expanded once only. + AC_REQUIRE([gl_00GNULIB]) + AC_REQUIRE([gl_COMMON_BODY]) +]) +AC_DEFUN([gl_COMMON_BODY], [ + AH_VERBATIM([isoc99_inline], +[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports + the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of + earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. + __APPLE__ && __MACH__ test for MacOS X. + __APPLE_CC__ tests for the Apple compiler and its version. + __STDC_VERSION__ tests for the C99 mode. */ +#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ +# define __GNUC_STDC_INLINE__ 1 +#endif]) + AH_VERBATIM([unused_parameter], +[/* Define as a marker that can be attached to declarations that might not + be used. This helps to reduce warnings, such as from + GCC -Wunused-parameter. */ +#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_UNUSED __attribute__ ((__unused__)) +#else +# define _GL_UNUSED +#endif +/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name + is a misnomer outside of parameter lists. */ +#define _UNUSED_PARAMETER_ _GL_UNUSED +]) + dnl Preparation for running test programs: + dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not + dnl to /dev/tty, so they can be redirected to log files. Such diagnostics + dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N. + LIBC_FATAL_STDERR_=1 + export LIBC_FATAL_STDERR_ +]) + +# gl_MODULE_INDICATOR_CONDITION +# expands to a C preprocessor expression that evaluates to 1 or 0, depending +# whether a gnulib module that has been requested shall be considered present +# or not. +AC_DEFUN([gl_MODULE_INDICATOR_CONDITION], [1]) + +# gl_MODULE_INDICATOR_SET_VARIABLE([modulename]) +# sets the shell variable that indicates the presence of the given module to +# a C preprocessor expression that will evaluate to 1. +AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE], +[ + GNULIB_[]m4_translit([[$1]], + [abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=gl_MODULE_INDICATOR_CONDITION +]) + +# gl_MODULE_INDICATOR([modulename]) +# defines a C macro indicating the presence of the given module +# in a location where it can be used. +# | Value | Value | +# | in lib/ | in tests/ | +# --------------------------------------------+---------+-----------+ +# Module present among main modules: | 1 | 1 | +# --------------------------------------------+---------+-----------+ +# Module present among tests-related modules: | 0 | 1 | +# --------------------------------------------+---------+-----------+ +# Module not present at all: | 0 | 0 | +# --------------------------------------------+---------+-----------+ +AC_DEFUN([gl_MODULE_INDICATOR], +[ + AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]], + [abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), + [gl_MODULE_INDICATOR_CONDITION], + [Define to a C preprocessor expression that evaluates to 1 or 0, + depending whether the gnulib module $1 shall be considered present.]) +]) + +# gl_MODULE_INDICATOR_FOR_TESTS([modulename]) +# defines a C macro indicating the presence of the given module +# in lib or tests. This is useful to determine whether the module +# should be tested. +# | Value | Value | +# | in lib/ | in tests/ | +# --------------------------------------------+---------+-----------+ +# Module present among main modules: | 1 | 1 | +# --------------------------------------------+---------+-----------+ +# Module present among tests-related modules: | 1 | 1 | +# --------------------------------------------+---------+-----------+ +# Module not present at all: | 0 | 0 | +# --------------------------------------------+---------+-----------+ +AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], +[ + AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]], + [abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1], + [Define to 1 when the gnulib module $1 should be tested.]) +]) + +# m4_foreach_w +# is a backport of autoconf-2.59c's m4_foreach_w. +# Remove this macro when we can assume autoconf >= 2.60. +m4_ifndef([m4_foreach_w], + [m4_define([m4_foreach_w], + [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])]) + +# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH]) +# ---------------------------------------------------- +# Backport of autoconf-2.63b's macro. +# Remove this macro when we can assume autoconf >= 2.64. +m4_ifndef([AS_VAR_IF], +[m4_define([AS_VAR_IF], +[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])]) + +# AC_PROG_MKDIR_P +# is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix +# for interoperability with automake-1.9.6 from autoconf-2.62. +# Remove this macro when we can assume autoconf >= 2.62 or +# autoconf >= 2.60 && automake >= 1.10. +m4_ifdef([AC_PROG_MKDIR_P], [ + dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. + m4_define([AC_PROG_MKDIR_P], + m4_defn([AC_PROG_MKDIR_P])[ + AC_SUBST([MKDIR_P])])], [ + dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P. + AC_DEFUN_ONCE([AC_PROG_MKDIR_P], + [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + MKDIR_P='$(mkdir_p)' + AC_SUBST([MKDIR_P])])]) + +# AC_C_RESTRICT +# This definition overrides the AC_C_RESTRICT macro from autoconf 2.60..2.61, +# so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++ +# works. +# This definition can be removed once autoconf >= 2.62 can be assumed. +m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.62]),[-1],[ +AC_DEFUN([AC_C_RESTRICT], +[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict], + [ac_cv_c_restrict=no + # The order here caters to the fact that C++ does not require restrict. + for ac_kw in __restrict __restrict__ _Restrict restrict; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[typedef int * int_ptr; + int foo (int_ptr $ac_kw ip) { + return ip[0]; + }]], + [[int s[1]; + int * $ac_kw t = s; + t[0] = 0; + return foo(t)]])], + [ac_cv_c_restrict=$ac_kw]) + test "$ac_cv_c_restrict" != no && break + done + ]) + AH_VERBATIM([restrict], +[/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#undef restrict +/* Work around a bug in Sun C++: it does not support _Restrict, even + though the corresponding Sun C compiler does, which causes + "#define restrict _Restrict" in the previous line. Perhaps some future + version of Sun C++ will work with _Restrict; if so, it'll probably + define __RESTRICT, just as Sun C does. */ +#if defined __SUNPRO_CC && !defined __RESTRICT +# define _Restrict +#endif]) + case $ac_cv_c_restrict in + restrict) ;; + no) AC_DEFINE([restrict], []) ;; + *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;; + esac +]) +]) + +# gl_BIGENDIAN +# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd. +# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some +# macros invoke AC_C_BIGENDIAN with arguments. +AC_DEFUN([gl_BIGENDIAN], +[ + AC_C_BIGENDIAN +]) + +# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it) +# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not +# output a spurious "(cached)" mark in the midst of other configure output. +# This macro should be used instead of AC_CACHE_VAL when it is not surrounded +# by an AC_MSG_CHECKING/AC_MSG_RESULT pair. +AC_DEFUN([gl_CACHE_VAL_SILENT], +[ + saved_as_echo_n="$as_echo_n" + as_echo_n=':' + AC_CACHE_VAL([$1], [$2]) + as_echo_n="$saved_as_echo_n" +]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 new file mode 100644 index 000000000..d77510f20 --- /dev/null +++ b/m4/gnulib-comp.m4 @@ -0,0 +1,573 @@ +# DO NOT EDIT! GENERATED AUTOMATICALLY! +# Copyright (C) 2002-2010 Free Software Foundation, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the compiled summary of the specification in +# gnulib-cache.m4. It lists the computed macro invocations that need +# to be invoked from configure.ac. +# In projects that use version control, this file can be treated like +# other built files. + + +# This macro should be invoked from ./configure.ac, in the section +# "Checks for programs", right after AC_PROG_CC, and certainly before +# any checks for libraries, header files, types and library functions. +AC_DEFUN([gl_EARLY], +[ + m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace + m4_pattern_allow([^gl_ES$])dnl a valid locale name + m4_pattern_allow([^gl_LIBOBJS$])dnl a variable + m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable + AC_REQUIRE([AC_PROG_RANLIB]) + # Code from module alloca: + # Code from module alloca-opt: + # Code from module arg-nonnull: + # Code from module argp: + # Code from module btowc: + # Code from module c++defs: + # Code from module configmake: + # Code from module dirname-lgpl: + # Code from module double-slash-root: + # Code from module errno: + # Code from module error: + # Code from module extensions: + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + # Code from module float: + # Code from module fnmatch: + # Code from module getdelim: + # Code from module getline: + # Code from module getopt-gnu: + # Code from module getopt-posix: + # Code from module gettext-h: + # Code from module include_next: + # Code from module intprops: + # Code from module langinfo: + # Code from module localcharset: + # Code from module malloc-gnu: + # Code from module malloc-posix: + # Code from module mbrtowc: + # Code from module mbsinit: + # Code from module mbsrtowcs: + # Code from module memchr: + # Code from module mempcpy: + # Code from module multiarch: + # Code from module nl_langinfo: + # Code from module progname: + # Code from module rawmemchr: + # Code from module realloc-posix: + # Code from module regex: + # Code from module size_max: + # Code from module sleep: + # Code from module ssize_t: + # Code from module stdbool: + # Code from module stddef: + # Code from module stdint: + # Code from module stdio: + # Code from module stdlib: + # Code from module strcase: + # Code from module strchrnul: + # Code from module streq: + # Code from module strerror: + # Code from module string: + # Code from module strings: + # Code from module strndup: + # Code from module strnlen: + # Code from module strnlen1: + # Code from module sys_wait: + # Code from module sysexits: + # Code from module unistd: + # Code from module vasnprintf: + # Code from module verify: + # Code from module vsnprintf: + # Code from module warn-on-use: + # Code from module wchar: + # Code from module wcrtomb: + # Code from module wctype: + # Code from module xsize: +]) + +# This macro should be invoked from ./configure.ac, in the section +# "Check for header files, types and library functions". +AC_DEFUN([gl_INIT], +[ + AM_CONDITIONAL([GL_COND_LIBTOOL], [false]) + gl_cond_libtool=false + gl_libdeps= + gl_ltlibdeps= + gl_m4_base='m4' + m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ])) + m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS])) + m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) + m4_pushdef([gl_LIBSOURCES_LIST], []) + m4_pushdef([gl_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='grub-core/gnulib' + # Code from module alloca: + # Code from module alloca-opt: + gl_FUNC_ALLOCA + # Code from module arg-nonnull: + # Code from module argp: + gl_ARGP + m4_ifdef([AM_XGETTEXT_OPTION], + [AM_][XGETTEXT_OPTION([--flag=argp_error:2:c-format]) + AM_][XGETTEXT_OPTION([--flag=argp_failure:4:c-format])]) + # Code from module btowc: + gl_FUNC_BTOWC + gl_WCHAR_MODULE_INDICATOR([btowc]) + # Code from module c++defs: + # Code from module configmake: + # Code from module dirname-lgpl: + gl_DIRNAME_LGPL + # Code from module double-slash-root: + gl_DOUBLE_SLASH_ROOT + # Code from module errno: + gl_HEADER_ERRNO_H + # Code from module error: + gl_ERROR + m4_ifdef([AM_XGETTEXT_OPTION], + [AM_][XGETTEXT_OPTION([--flag=error:3:c-format]) + AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])]) + # Code from module extensions: + # Code from module float: + gl_FLOAT_H + # Code from module fnmatch: + gl_FUNC_FNMATCH_POSIX + # Code from module getdelim: + gl_FUNC_GETDELIM + gl_STDIO_MODULE_INDICATOR([getdelim]) + # Code from module getline: + gl_FUNC_GETLINE + gl_STDIO_MODULE_INDICATOR([getline]) + # Code from module getopt-gnu: + gl_FUNC_GETOPT_GNU + gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) + # Code from module getopt-posix: + gl_FUNC_GETOPT_POSIX + # Code from module gettext-h: + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + # Code from module include_next: + # Code from module intprops: + # Code from module langinfo: + gl_LANGINFO_H + # Code from module localcharset: + gl_LOCALCHARSET + LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\"" + AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) + # Code from module malloc-gnu: + gl_FUNC_MALLOC_GNU + gl_MODULE_INDICATOR([malloc-gnu]) + # Code from module malloc-posix: + gl_FUNC_MALLOC_POSIX + gl_STDLIB_MODULE_INDICATOR([malloc-posix]) + # Code from module mbrtowc: + gl_FUNC_MBRTOWC + gl_WCHAR_MODULE_INDICATOR([mbrtowc]) + # Code from module mbsinit: + gl_FUNC_MBSINIT + gl_WCHAR_MODULE_INDICATOR([mbsinit]) + # Code from module mbsrtowcs: + gl_FUNC_MBSRTOWCS + gl_WCHAR_MODULE_INDICATOR([mbsrtowcs]) + # Code from module memchr: + gl_FUNC_MEMCHR + gl_STRING_MODULE_INDICATOR([memchr]) + # Code from module mempcpy: + gl_FUNC_MEMPCPY + gl_STRING_MODULE_INDICATOR([mempcpy]) + # Code from module multiarch: + gl_MULTIARCH + # Code from module nl_langinfo: + gl_FUNC_NL_LANGINFO + gl_LANGINFO_MODULE_INDICATOR([nl_langinfo]) + # Code from module progname: + AC_CHECK_DECLS([program_invocation_name], [], [], [#include ]) + AC_CHECK_DECLS([program_invocation_short_name], [], [], [#include ]) + # Code from module rawmemchr: + gl_FUNC_RAWMEMCHR + gl_STRING_MODULE_INDICATOR([rawmemchr]) + # Code from module realloc-posix: + gl_FUNC_REALLOC_POSIX + gl_STDLIB_MODULE_INDICATOR([realloc-posix]) + # Code from module regex: + gl_REGEX + # Code from module size_max: + gl_SIZE_MAX + # Code from module sleep: + gl_FUNC_SLEEP + gl_UNISTD_MODULE_INDICATOR([sleep]) + # Code from module ssize_t: + gt_TYPE_SSIZE_T + # Code from module stdbool: + AM_STDBOOL_H + # Code from module stddef: + gl_STDDEF_H + # Code from module stdint: + gl_STDINT_H + # Code from module stdio: + gl_STDIO_H + # Code from module stdlib: + gl_STDLIB_H + # Code from module strcase: + gl_STRCASE + # Code from module strchrnul: + gl_FUNC_STRCHRNUL + gl_STRING_MODULE_INDICATOR([strchrnul]) + # Code from module streq: + # Code from module strerror: + gl_FUNC_STRERROR + gl_STRING_MODULE_INDICATOR([strerror]) + # Code from module string: + gl_HEADER_STRING_H + # Code from module strings: + gl_HEADER_STRINGS_H + # Code from module strndup: + gl_FUNC_STRNDUP + gl_STRING_MODULE_INDICATOR([strndup]) + # Code from module strnlen: + gl_FUNC_STRNLEN + gl_STRING_MODULE_INDICATOR([strnlen]) + # Code from module strnlen1: + # Code from module sys_wait: + gl_SYS_WAIT_H + AC_PROG_MKDIR_P + # Code from module sysexits: + gl_SYSEXITS + # Code from module unistd: + gl_UNISTD_H + # Code from module vasnprintf: + gl_FUNC_VASNPRINTF + # Code from module verify: + # Code from module vsnprintf: + gl_FUNC_VSNPRINTF + gl_STDIO_MODULE_INDICATOR([vsnprintf]) + # Code from module warn-on-use: + # Code from module wchar: + gl_WCHAR_H + # Code from module wcrtomb: + gl_FUNC_WCRTOMB + gl_WCHAR_MODULE_INDICATOR([wcrtomb]) + # Code from module wctype: + gl_WCTYPE_H + # Code from module xsize: + gl_XSIZE + # End of code from modules + m4_ifval(gl_LIBSOURCES_LIST, [ + m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || + for gl_file in ]gl_LIBSOURCES_LIST[ ; do + if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then + echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2 + exit 1 + fi + done])dnl + m4_if(m4_sysval, [0], [], + [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) + ]) + m4_popdef([gl_LIBSOURCES_DIR]) + m4_popdef([gl_LIBSOURCES_LIST]) + m4_popdef([AC_LIBSOURCES]) + m4_popdef([AC_REPLACE_FUNCS]) + m4_popdef([AC_LIBOBJ]) + AC_CONFIG_COMMANDS_PRE([ + gl_libobjs= + gl_ltlibobjs= + if test -n "$gl_LIBOBJS"; then + # Remove the extension. + sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do + gl_libobjs="$gl_libobjs $i.$ac_objext" + gl_ltlibobjs="$gl_ltlibobjs $i.lo" + done + fi + AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) + AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) + ]) + gltests_libdeps= + gltests_ltlibdeps= + m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ])) + m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS])) + m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES])) + m4_pushdef([gltests_LIBSOURCES_LIST], []) + m4_pushdef([gltests_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='tests' +changequote(,)dnl + gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS +changequote([, ])dnl + AC_SUBST([gltests_WITNESS]) + gl_module_indicator_condition=$gltests_WITNESS + m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition]) + m4_popdef([gl_MODULE_INDICATOR_CONDITION]) + m4_ifval(gltests_LIBSOURCES_LIST, [ + m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ || + for gl_file in ]gltests_LIBSOURCES_LIST[ ; do + if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then + echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2 + exit 1 + fi + done])dnl + m4_if(m4_sysval, [0], [], + [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) + ]) + m4_popdef([gltests_LIBSOURCES_DIR]) + m4_popdef([gltests_LIBSOURCES_LIST]) + m4_popdef([AC_LIBSOURCES]) + m4_popdef([AC_REPLACE_FUNCS]) + m4_popdef([AC_LIBOBJ]) + AC_CONFIG_COMMANDS_PRE([ + gltests_libobjs= + gltests_ltlibobjs= + if test -n "$gltests_LIBOBJS"; then + # Remove the extension. + sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do + gltests_libobjs="$gltests_libobjs $i.$ac_objext" + gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" + done + fi + AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) + AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) + ]) + LIBGNU_LIBDEPS="$gl_libdeps" + AC_SUBST([LIBGNU_LIBDEPS]) + LIBGNU_LTLIBDEPS="$gl_ltlibdeps" + AC_SUBST([LIBGNU_LTLIBDEPS]) +]) + +# Like AC_LIBOBJ, except that the module name goes +# into gl_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gl_LIBOBJ], [ + AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl + gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext" +]) + +# Like AC_REPLACE_FUNCS, except that the module name goes +# into gl_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gl_REPLACE_FUNCS], [ + m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl + AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)]) +]) + +# Like AC_LIBSOURCES, except the directory where the source file is +# expected is derived from the gnulib-tool parameterization, +# and alloca is special cased (for the alloca-opt module). +# We could also entirely rely on EXTRA_lib..._SOURCES. +AC_DEFUN([gl_LIBSOURCES], [ + m4_foreach([_gl_NAME], [$1], [ + m4_if(_gl_NAME, [alloca.c], [], [ + m4_define([gl_LIBSOURCES_DIR], [grub-core/gnulib]) + m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ]) + ]) + ]) +]) + +# Like AC_LIBOBJ, except that the module name goes +# into gltests_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gltests_LIBOBJ], [ + AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl + gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext" +]) + +# Like AC_REPLACE_FUNCS, except that the module name goes +# into gltests_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gltests_REPLACE_FUNCS], [ + m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl + AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)]) +]) + +# Like AC_LIBSOURCES, except the directory where the source file is +# expected is derived from the gnulib-tool parameterization, +# and alloca is special cased (for the alloca-opt module). +# We could also entirely rely on EXTRA_lib..._SOURCES. +AC_DEFUN([gltests_LIBSOURCES], [ + m4_foreach([_gl_NAME], [$1], [ + m4_if(_gl_NAME, [alloca.c], [], [ + m4_define([gltests_LIBSOURCES_DIR], [tests]) + m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ]) + ]) + ]) +]) + +# This macro records the list of files which have been installed by +# gnulib-tool and may be removed by future gnulib-tool invocations. +AC_DEFUN([gl_FILE_LIST], [ + build-aux/arg-nonnull.h + build-aux/c++defs.h + build-aux/warn-on-use.h + lib/alloca.c + lib/alloca.in.h + lib/argp-ba.c + lib/argp-eexst.c + lib/argp-fmtstream.c + lib/argp-fmtstream.h + lib/argp-fs-xinl.c + lib/argp-help.c + lib/argp-namefrob.h + lib/argp-parse.c + lib/argp-pin.c + lib/argp-pv.c + lib/argp-pvh.c + lib/argp-xinl.c + lib/argp.h + lib/asnprintf.c + lib/basename-lgpl.c + lib/btowc.c + lib/config.charset + lib/dirname-lgpl.c + lib/dirname.h + lib/errno.in.h + lib/error.c + lib/error.h + lib/float+.h + lib/float.in.h + lib/fnmatch.c + lib/fnmatch.in.h + lib/fnmatch_loop.c + lib/getdelim.c + lib/getline.c + lib/getopt.c + lib/getopt.in.h + lib/getopt1.c + lib/getopt_int.h + lib/gettext.h + lib/intprops.h + lib/langinfo.in.h + lib/localcharset.c + lib/localcharset.h + lib/malloc.c + lib/mbrtowc.c + lib/mbsinit.c + lib/mbsrtowcs-state.c + lib/mbsrtowcs.c + lib/memchr.c + lib/memchr.valgrind + lib/mempcpy.c + lib/nl_langinfo.c + lib/printf-args.c + lib/printf-args.h + lib/printf-parse.c + lib/printf-parse.h + lib/progname.c + lib/progname.h + lib/rawmemchr.c + lib/rawmemchr.valgrind + lib/realloc.c + lib/ref-add.sin + lib/ref-del.sin + lib/regcomp.c + lib/regex.c + lib/regex.h + lib/regex_internal.c + lib/regex_internal.h + lib/regexec.c + lib/size_max.h + lib/sleep.c + lib/stdbool.in.h + lib/stddef.in.h + lib/stdint.in.h + lib/stdio-write.c + lib/stdio.in.h + lib/stdlib.in.h + lib/strcasecmp.c + lib/strchrnul.c + lib/strchrnul.valgrind + lib/streq.h + lib/strerror.c + lib/string.in.h + lib/strings.in.h + lib/stripslash.c + lib/strncasecmp.c + lib/strndup.c + lib/strnlen.c + lib/strnlen1.c + lib/strnlen1.h + lib/sys_wait.in.h + lib/sysexits.in.h + lib/unistd.in.h + lib/vasnprintf.c + lib/vasnprintf.h + lib/verify.h + lib/vsnprintf.c + lib/wchar.in.h + lib/wcrtomb.c + lib/wctype.in.h + lib/xsize.h + m4/00gnulib.m4 + m4/alloca.m4 + m4/argp.m4 + m4/asm-underscore.m4 + m4/btowc.m4 + m4/codeset.m4 + m4/dirname.m4 + m4/dos.m4 + m4/double-slash-root.m4 + m4/errno_h.m4 + m4/error.m4 + m4/extensions.m4 + m4/fcntl-o.m4 + m4/float_h.m4 + m4/fnmatch.m4 + m4/getdelim.m4 + m4/getline.m4 + m4/getopt.m4 + m4/glibc21.m4 + m4/gnulib-common.m4 + m4/include_next.m4 + m4/intmax_t.m4 + m4/inttypes_h.m4 + m4/langinfo_h.m4 + m4/localcharset.m4 + m4/locale-fr.m4 + m4/locale-ja.m4 + m4/locale-zh.m4 + m4/longlong.m4 + m4/malloc.m4 + m4/mbrtowc.m4 + m4/mbsinit.m4 + m4/mbsrtowcs.m4 + m4/mbstate_t.m4 + m4/memchr.m4 + m4/mempcpy.m4 + m4/mmap-anon.m4 + m4/multiarch.m4 + m4/nl_langinfo.m4 + m4/printf.m4 + m4/rawmemchr.m4 + m4/realloc.m4 + m4/regex.m4 + m4/size_max.m4 + m4/sleep.m4 + m4/ssize_t.m4 + m4/stdbool.m4 + m4/stddef_h.m4 + m4/stdint.m4 + m4/stdint_h.m4 + m4/stdio_h.m4 + m4/stdlib_h.m4 + m4/strcase.m4 + m4/strchrnul.m4 + m4/strerror.m4 + m4/string_h.m4 + m4/strings_h.m4 + m4/strndup.m4 + m4/strnlen.m4 + m4/sys_wait_h.m4 + m4/sysexits.m4 + m4/unistd_h.m4 + m4/vasnprintf.m4 + m4/vsnprintf.m4 + m4/warn-on-use.m4 + m4/wchar_h.m4 + m4/wchar_t.m4 + m4/wcrtomb.m4 + m4/wctype_h.m4 + m4/wint_t.m4 + m4/xsize.m4 +]) diff --git a/m4/gnulib-tool.m4 b/m4/gnulib-tool.m4 new file mode 100644 index 000000000..69e7733b9 --- /dev/null +++ b/m4/gnulib-tool.m4 @@ -0,0 +1,57 @@ +# gnulib-tool.m4 serial 2 +dnl Copyright (C) 2004-2005, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl The following macros need not be invoked explicitly. +dnl Invoking them does nothing except to declare default arguments +dnl for "gnulib-tool --import". + +dnl Usage: gl_LOCAL_DIR([DIR]) +AC_DEFUN([gl_LOCAL_DIR], []) + +dnl Usage: gl_MODULES([module1 module2 ...]) +AC_DEFUN([gl_MODULES], []) + +dnl Usage: gl_AVOID([module1 module2 ...]) +AC_DEFUN([gl_AVOID], []) + +dnl Usage: gl_SOURCE_BASE([DIR]) +AC_DEFUN([gl_SOURCE_BASE], []) + +dnl Usage: gl_M4_BASE([DIR]) +AC_DEFUN([gl_M4_BASE], []) + +dnl Usage: gl_PO_BASE([DIR]) +AC_DEFUN([gl_PO_BASE], []) + +dnl Usage: gl_DOC_BASE([DIR]) +AC_DEFUN([gl_DOC_BASE], []) + +dnl Usage: gl_TESTS_BASE([DIR]) +AC_DEFUN([gl_TESTS_BASE], []) + +dnl Usage: gl_WITH_TESTS +AC_DEFUN([gl_WITH_TESTS], []) + +dnl Usage: gl_LIB([LIBNAME]) +AC_DEFUN([gl_LIB], []) + +dnl Usage: gl_LGPL or gl_LGPL([VERSION]) +AC_DEFUN([gl_LGPL], []) + +dnl Usage: gl_MAKEFILE_NAME([FILENAME]) +AC_DEFUN([gl_MAKEFILE_NAME], []) + +dnl Usage: gl_LIBTOOL +AC_DEFUN([gl_LIBTOOL], []) + +dnl Usage: gl_MACRO_PREFIX([PREFIX]) +AC_DEFUN([gl_MACRO_PREFIX], []) + +dnl Usage: gl_PO_DOMAIN([DOMAIN]) +AC_DEFUN([gl_PO_DOMAIN], []) + +dnl Usage: gl_VC_FILES([BOOLEAN]) +AC_DEFUN([gl_VC_FILES], []) diff --git a/m4/include_next.m4 b/m4/include_next.m4 new file mode 100644 index 000000000..51a719b0a --- /dev/null +++ b/m4/include_next.m4 @@ -0,0 +1,192 @@ +# include_next.m4 serial 15 +dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert and Derek Price. + +dnl Sets INCLUDE_NEXT and PRAGMA_SYSTEM_HEADER. +dnl +dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to +dnl 'include' otherwise. +dnl +dnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler +dnl supports it in the special case that it is the first include directive in +dnl the given file, or to 'include' otherwise. +dnl +dnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next, +dnl so as to avoid GCC warnings when the gcc option -pedantic is used. +dnl '#pragma GCC system_header' has the same effect as if the file was found +dnl through the include search path specified with '-isystem' options (as +dnl opposed to the search path specified with '-I' options). Namely, gcc +dnl does not warn about some things, and on some systems (Solaris and Interix) +dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side +dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead +dnl of plain '__STDC__'. + +AC_DEFUN([gl_INCLUDE_NEXT], +[ + AC_LANG_PREPROC_REQUIRE() + AC_CACHE_CHECK([whether the preprocessor supports include_next], + [gl_cv_have_include_next], + [rm -rf conftestd1a conftestd1b conftestd2 + mkdir conftestd1a conftestd1b conftestd2 + dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on + dnl AIX 6.1 support include_next when used as first preprocessor directive + dnl in a file, but not when preceded by another include directive. Check + dnl for this bug by including . + dnl Additionally, with this same compiler, include_next is a no-op when + dnl used in a header file that was included by specifying its absolute + dnl file name. Despite these two bugs, include_next is used in the + dnl compiler's . By virtue of the second bug, we need to use + dnl include_next as well in this case. + cat < conftestd1a/conftest.h +#define DEFINED_IN_CONFTESTD1 +#include_next +#ifdef DEFINED_IN_CONFTESTD2 +int foo; +#else +#error "include_next doesn't work" +#endif +EOF + cat < conftestd1b/conftest.h +#define DEFINED_IN_CONFTESTD1 +#include +#include_next +#ifdef DEFINED_IN_CONFTESTD2 +int foo; +#else +#error "include_next doesn't work" +#endif +EOF + cat < conftestd2/conftest.h +#ifndef DEFINED_IN_CONFTESTD1 +#error "include_next test doesn't work" +#endif +#define DEFINED_IN_CONFTESTD2 +EOF + gl_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2" +dnl We intentionally avoid using AC_LANG_SOURCE here. + AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include ]], + [gl_cv_have_include_next=yes], + [CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2" + AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include ]], + [gl_cv_have_include_next=buggy], + [gl_cv_have_include_next=no]) + ]) + CPPFLAGS="$gl_save_CPPFLAGS" + rm -rf conftestd1a conftestd1b conftestd2 + ]) + PRAGMA_SYSTEM_HEADER= + if test $gl_cv_have_include_next = yes; then + INCLUDE_NEXT=include_next + INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next + if test -n "$GCC"; then + PRAGMA_SYSTEM_HEADER='#pragma GCC system_header' + fi + else + if test $gl_cv_have_include_next = buggy; then + INCLUDE_NEXT=include + INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next + else + INCLUDE_NEXT=include + INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include + fi + fi + AC_SUBST([INCLUDE_NEXT]) + AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE]) + AC_SUBST([PRAGMA_SYSTEM_HEADER]) +]) + +# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...) +# ------------------------------------------ +# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be +# ''; otherwise define it to be +# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. +# Also, if #include_next works as first preprocessing directive in a file, +# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be ''; otherwise define it to +# be +# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. +# That way, a header file with the following line: +# #@INCLUDE_NEXT@ @NEXT_FOO_H@ +# or +# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@ +# behaves (after sed substitution) as if it contained +# #include_next +# even if the compiler does not support include_next. +# The three "///" are to pacify Sun C 5.8, which otherwise would say +# "warning: #include of /usr/include/... may be non-portable". +# Use `""', not `<>', so that the /// cannot be confused with a C99 comment. +# Note: This macro assumes that the header file is not empty after +# preprocessing, i.e. it does not only define preprocessor macros but also +# provides some type/enum definitions or function/variable declarations. +AC_DEFUN([gl_CHECK_NEXT_HEADERS], +[ + AC_REQUIRE([gl_INCLUDE_NEXT]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_HEADERS_ONCE([$1]) + + m4_foreach_w([gl_HEADER_NAME], [$1], + [AS_VAR_PUSHDEF([gl_next_header], + [gl_cv_next_]m4_defn([gl_HEADER_NAME])) + if test $gl_cv_have_include_next = yes; then + AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) + else + AC_CACHE_CHECK( + [absolute name of <]m4_defn([gl_HEADER_NAME])[>], + m4_defn([gl_next_header]), + [AS_VAR_PUSHDEF([gl_header_exists], + [ac_cv_header_]m4_defn([gl_HEADER_NAME])) + if test AS_VAR_GET(gl_header_exists) = yes; then + AC_LANG_CONFTEST( + [AC_LANG_SOURCE( + [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] + )]) + dnl AIX "xlc -E" and "cc -E" omit #line directives for header files + dnl that contain only a #include of other header files and no + dnl non-comment tokens of their own. This leads to a failure to + dnl detect the absolute name of , , + dnl and others. The workaround is to force preservation of comments + dnl through option -C. This ensures all necessary #line directives + dnl are present. GCC supports option -C as well. + case "$host_os" in + aix*) gl_absname_cpp="$ac_cpp -C" ;; + *) gl_absname_cpp="$ac_cpp" ;; + esac + dnl eval is necessary to expand gl_absname_cpp. + dnl Ultrix and Pyramid sh refuse to redirect output of eval, + dnl so use subshell. + AS_VAR_SET([gl_next_header], + ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | + sed -n '\#/]m4_defn([gl_HEADER_NAME])[#{ + s#.*"\(.*/]m4_defn([gl_HEADER_NAME])[\)".*#\1# + s#^/[^/]#//&# + p + q + }'`'"']) + else + AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) + fi + AS_VAR_POPDEF([gl_header_exists])]) + fi + AC_SUBST( + AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])), + [AS_VAR_GET([gl_next_header])]) + if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then + # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' + gl_next_as_first_directive='<'gl_HEADER_NAME'>' + else + # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' + gl_next_as_first_directive=AS_VAR_GET([gl_next_header]) + fi + AC_SUBST( + AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])), + [$gl_next_as_first_directive]) + AS_VAR_POPDEF([gl_next_header])]) +]) + +# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE; +# this fallback is safe for all earlier autoconf versions. +m4_define_default([AC_LANG_DEFINES_PROVIDED]) diff --git a/m4/intmax_t.m4 b/m4/intmax_t.m4 new file mode 100644 index 000000000..493e4a932 --- /dev/null +++ b/m4/intmax_t.m4 @@ -0,0 +1,67 @@ +# intmax_t.m4 serial 8 +dnl Copyright (C) 1997-2004, 2006-2007, 2009-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +AC_PREREQ([2.53]) + +# Define intmax_t to 'long' or 'long long' +# if it is not already defined in or . + +AC_DEFUN([gl_AC_TYPE_INTMAX_T], +[ + dnl For simplicity, we assume that a header file defines 'intmax_t' if and + dnl only if it defines 'uintmax_t'. + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + test $ac_cv_type_long_long_int = yes \ + && ac_type='long long' \ + || ac_type='long' + AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], + [Define to long or long long if and don't define.]) + else + AC_DEFINE([HAVE_INTMAX_T], [1], + [Define if you have the 'intmax_t' type in or .]) + fi +]) + +dnl An alternative would be to explicitly test for 'intmax_t'. + +AC_DEFUN([gt_AC_TYPE_INTMAX_T], +[ + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +#include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +#include +#endif + ]], + [[intmax_t x = -1; return !x;]])], + [gt_cv_c_intmax_t=yes], + [gt_cv_c_intmax_t=no])]) + if test $gt_cv_c_intmax_t = yes; then + AC_DEFINE([HAVE_INTMAX_T], [1], + [Define if you have the 'intmax_t' type in or .]) + else + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + test $ac_cv_type_long_long_int = yes \ + && ac_type='long long' \ + || ac_type='long' + AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], + [Define to long or long long if and don't define.]) + fi +]) diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4 new file mode 100644 index 000000000..9d8f92692 --- /dev/null +++ b/m4/inttypes_h.m4 @@ -0,0 +1,29 @@ +# inttypes_h.m4 serial 10 +dnl Copyright (C) 1997-2004, 2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([gl_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], [gl_cv_header_inttypes_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[uintmax_t i = (uintmax_t) -1; return !i;]])], + [gl_cv_header_inttypes_h=yes], + [gl_cv_header_inttypes_h=no])]) + if test $gl_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED([HAVE_INTTYPES_H_WITH_UINTMAX], [1], + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/m4/langinfo_h.m4 b/m4/langinfo_h.m4 new file mode 100644 index 000000000..adc445e85 --- /dev/null +++ b/m4/langinfo_h.m4 @@ -0,0 +1,105 @@ +# langinfo_h.m4 serial 7 +dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_LANGINFO_H], +[ + AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) + + dnl Persuade glibc-2.0.6 to define CODESET. + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + dnl is always overridden, because of GNULIB_POSIXCHECK. + gl_CHECK_NEXT_HEADERS([langinfo.h]) + + dnl Determine whether exists. It is missing on mingw and BeOS. + HAVE_LANGINFO_CODESET=0 + HAVE_LANGINFO_T_FMT_AMPM=0 + HAVE_LANGINFO_ERA=0 + HAVE_LANGINFO_YESEXPR=0 + AC_CHECK_HEADERS_ONCE([langinfo.h]) + if test $ac_cv_header_langinfo_h = yes; then + HAVE_LANGINFO_H=1 + dnl Determine what defines. CODESET and ERA etc. are missing + dnl on OpenBSD 3.8. T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3. + AC_CACHE_CHECK([whether langinfo.h defines CODESET], + [gl_cv_header_langinfo_codeset], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include +int a = CODESET; +]])], + [gl_cv_header_langinfo_codeset=yes], + [gl_cv_header_langinfo_codeset=no]) + ]) + if test $gl_cv_header_langinfo_codeset = yes; then + HAVE_LANGINFO_CODESET=1 + fi + AC_CACHE_CHECK([whether langinfo.h defines T_FMT_AMPM], + [gl_cv_header_langinfo_t_fmt_ampm], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include +int a = T_FMT_AMPM; +]])], + [gl_cv_header_langinfo_t_fmt_ampm=yes], + [gl_cv_header_langinfo_t_fmt_ampm=no]) + ]) + if test $gl_cv_header_langinfo_t_fmt_ampm = yes; then + HAVE_LANGINFO_T_FMT_AMPM=1 + fi + AC_CACHE_CHECK([whether langinfo.h defines ERA], + [gl_cv_header_langinfo_era], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include +int a = ERA; +]])], + [gl_cv_header_langinfo_era=yes], + [gl_cv_header_langinfo_era=no]) + ]) + if test $gl_cv_header_langinfo_era = yes; then + HAVE_LANGINFO_ERA=1 + fi + AC_CACHE_CHECK([whether langinfo.h defines YESEXPR], + [gl_cv_header_langinfo_yesexpr], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include +int a = YESEXPR; +]])], + [gl_cv_header_langinfo_yesexpr=yes], + [gl_cv_header_langinfo_yesexpr=no]) + ]) + if test $gl_cv_header_langinfo_yesexpr = yes; then + HAVE_LANGINFO_YESEXPR=1 + fi + else + HAVE_LANGINFO_H=0 + fi + AC_SUBST([HAVE_LANGINFO_H]) + AC_SUBST([HAVE_LANGINFO_CODESET]) + AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM]) + AC_SUBST([HAVE_LANGINFO_ERA]) + AC_SUBST([HAVE_LANGINFO_YESEXPR]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[#include + ]], [nl_langinfo]) +]) + +AC_DEFUN([gl_LANGINFO_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_LANGINFO_H_DEFAULTS], +[ + GNULIB_NL_LANGINFO=0; AC_SUBST([GNULIB_NL_LANGINFO]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_NL_LANGINFO=1; AC_SUBST([HAVE_NL_LANGINFO]) + REPLACE_NL_LANGINFO=0; AC_SUBST([REPLACE_NL_LANGINFO]) +]) diff --git a/m4/localcharset.m4 b/m4/localcharset.m4 new file mode 100644 index 000000000..ee2e801bd --- /dev/null +++ b/m4/localcharset.m4 @@ -0,0 +1,17 @@ +# localcharset.m4 serial 7 +dnl Copyright (C) 2002, 2004, 2006, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_LOCALCHARSET], +[ + dnl Prerequisites of lib/localcharset.c. + AC_REQUIRE([AM_LANGINFO_CODESET]) + AC_REQUIRE([gl_FCNTL_O_FLAGS]) + AC_CHECK_DECLS_ONCE([getc_unlocked]) + + dnl Prerequisites of the lib/Makefile.am snippet. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_GLIBC21]) +]) diff --git a/m4/locale-fr.m4 b/m4/locale-fr.m4 new file mode 100644 index 000000000..001f53906 --- /dev/null +++ b/m4/locale-fr.m4 @@ -0,0 +1,185 @@ +# locale-fr.m4 serial 11 +dnl Copyright (C) 2003, 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Determine the name of a french locale with traditional encoding. +AC_DEFUN([gt_LOCALE_FR], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AM_LANGINFO_CODESET]) + AC_CACHE_CHECK([for a traditional french locale], [gt_cv_locale_fr], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ +changequote(,)dnl +#include +#include +#if HAVE_LANGINFO_CODESET +# include +#endif +#include +#include +struct tm t; +char buf[16]; +int main () { + /* Check whether the given locale name is recognized by the system. */ + if (setlocale (LC_ALL, "") == NULL) return 1; + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". + On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, + some unit tests fail. */ +#if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); + if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) + return 1; + } +#endif +#ifdef __CYGWIN__ + /* On Cygwin, avoid locale names without encoding suffix, because the + locale_charset() function relies on the encoding suffix. Note that + LC_ALL is set on the command line. */ + if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; +#endif + /* Check whether in the abbreviation of the second month, the second + character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is only + one byte long. This excludes the UTF-8 encoding. */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1; + /* Check whether the decimal separator is a comma. + On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point + are nl_langinfo(RADIXCHAR) are both ".". */ + if (localeconv () ->decimal_point[0] != ',') return 1; + return 0; +} +changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the usual locale name. + if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR + else + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR.ISO-8859-1 + else + # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name. + if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR.ISO8859-1 + else + # Test for the HP-UX locale name. + if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr_FR.iso88591 + else + # Test for the Solaris 7 locale name. + if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr=fr + else + # None found. + gt_cv_locale_fr=none + fi + fi + fi + fi + fi + fi + rm -fr conftest* + ]) + LOCALE_FR=$gt_cv_locale_fr + AC_SUBST([LOCALE_FR]) +]) + +dnl Determine the name of a french locale with UTF-8 encoding. +AC_DEFUN([gt_LOCALE_FR_UTF8], +[ + AC_REQUIRE([AM_LANGINFO_CODESET]) + AC_CACHE_CHECK([for a french Unicode locale], [gt_cv_locale_fr_utf8], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ +changequote(,)dnl +#include +#include +#if HAVE_LANGINFO_CODESET +# include +#endif +#include +#include +struct tm t; +char buf[16]; +int main () { + /* On BeOS and Haiku, locales are not implemented in libc. Rather, libintl + imitates locale dependent behaviour by looking at the environment + variables, and all locales use the UTF-8 encoding. */ +#if !(defined __BEOS__ || defined __HAIKU__) + /* Check whether the given locale name is recognized by the system. */ + if (setlocale (LC_ALL, "") == NULL) return 1; + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". + On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, + some unit tests fail. */ +# if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); + if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) + return 1; + } +# endif +# ifdef __CYGWIN__ + /* On Cygwin, avoid locale names without encoding suffix, because the + locale_charset() function relies on the encoding suffix. Note that + LC_ALL is set on the command line. */ + if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; +# endif + /* Check whether in the abbreviation of the second month, the second + character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is + two bytes long, with UTF-8 encoding. */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%b", &t) < 4 + || buf[1] != (char) 0xc3 || buf[2] != (char) 0xa9 || buf[3] != 'v') + return 1; +#endif + /* Check whether the decimal separator is a comma. + On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point + are nl_langinfo(RADIXCHAR) are both ".". */ + if (localeconv () ->decimal_point[0] != ',') return 1; + return 0; +} +changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the usual locale name. + if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr_utf8=fr_FR + else + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr_utf8=fr_FR.UTF-8 + else + # Test for the Solaris 7 locale name. + if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_fr_utf8=fr.UTF-8 + else + # None found. + gt_cv_locale_fr_utf8=none + fi + fi + fi + fi + rm -fr conftest* + ]) + LOCALE_FR_UTF8=$gt_cv_locale_fr_utf8 + AC_SUBST([LOCALE_FR_UTF8]) +]) diff --git a/m4/locale-ja.m4 b/m4/locale-ja.m4 new file mode 100644 index 000000000..0eedaf149 --- /dev/null +++ b/m4/locale-ja.m4 @@ -0,0 +1,107 @@ +# locale-ja.m4 serial 7 +dnl Copyright (C) 2003, 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Determine the name of a japanese locale with EUC-JP encoding. +AC_DEFUN([gt_LOCALE_JA], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AM_LANGINFO_CODESET]) + AC_CACHE_CHECK([for a traditional japanese locale], [gt_cv_locale_ja], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ +changequote(,)dnl +#include +#include +#if HAVE_LANGINFO_CODESET +# include +#endif +#include +#include +struct tm t; +char buf[16]; +int main () +{ + const char *p; + /* Check whether the given locale name is recognized by the system. */ + if (setlocale (LC_ALL, "") == NULL) return 1; + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". + On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, + some unit tests fail. */ +#if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); + if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) + return 1; + } +#endif +#ifdef __CYGWIN__ + /* On Cygwin, avoid locale names without encoding suffix, because the + locale_charset() function relies on the encoding suffix. Note that + LC_ALL is set on the command line. */ + if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; +#endif + /* Check whether MB_CUR_MAX is > 1. This excludes the dysfunctional locales + on Cygwin 1.5.x. */ + if (MB_CUR_MAX == 1) + return 1; + /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. + This excludes the UTF-8 encoding. */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; + for (p = buf; *p != '\0'; p++) + if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) + return 1; + return 0; +} +changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the AIX locale name. + if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP + else + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP.EUC-JP + else + # Test for the HP-UX, OSF/1, NetBSD locale name. + if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP.eucJP + else + # Test for the IRIX, FreeBSD locale name. + if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja_JP.EUC + else + # Test for the Solaris 7 locale name. + if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_ja=ja + else + # Special test for NetBSD 1.6. + if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then + gt_cv_locale_ja=ja_JP.eucJP + else + # None found. + gt_cv_locale_ja=none + fi + fi + fi + fi + fi + fi + fi + rm -fr conftest* + ]) + LOCALE_JA=$gt_cv_locale_ja + AC_SUBST([LOCALE_JA]) +]) diff --git a/m4/locale-zh.m4 b/m4/locale-zh.m4 new file mode 100644 index 000000000..777fd1418 --- /dev/null +++ b/m4/locale-zh.m4 @@ -0,0 +1,92 @@ +# locale-zh.m4 serial 6 +dnl Copyright (C) 2003, 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Determine the name of a chinese locale with GB18030 encoding. +AC_DEFUN([gt_LOCALE_ZH_CN], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AM_LANGINFO_CODESET]) + AC_CACHE_CHECK([for a transitional chinese locale], [gt_cv_locale_zh_CN], [ + AC_LANG_CONFTEST([AC_LANG_SOURCE([ +changequote(,)dnl +#include +#include +#include +#if HAVE_LANGINFO_CODESET +# include +#endif +#include +#include +struct tm t; +char buf[16]; +int main () +{ + const char *p; + /* Check whether the given locale name is recognized by the system. */ + if (setlocale (LC_ALL, "") == NULL) return 1; + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". + On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, + some unit tests fail. */ +#if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); + if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) + return 1; + } +#endif +#ifdef __CYGWIN__ + /* On Cygwin, avoid locale names without encoding suffix, because the + locale_charset() function relies on the encoding suffix. Note that + LC_ALL is set on the command line. */ + if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; +#endif + /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. + This excludes the UTF-8 encoding. */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; + for (p = buf; *p != '\0'; p++) + if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) + return 1; + /* Check whether a typical GB18030 multibyte sequence is recognized as a + single wide character. This excludes the GB2312 and GBK encodings. */ + if (mblen ("\203\062\332\066", 5) != 4) + return 1; + return 0; +} +changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because + # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the + # configure script would override the LC_ALL setting. Likewise for + # LC_CTYPE, which is also set at the beginning of the configure script. + # Test for the locale name without encoding suffix. + if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_zh_CN=zh_CN + else + # Test for the locale name with explicit encoding suffix. + if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then + gt_cv_locale_zh_CN=zh_CN.GB18030 + else + # None found. + gt_cv_locale_zh_CN=none + fi + fi + else + # If there was a link error, due to mblen(), the system is so old that + # it certainly doesn't have a chinese locale. + gt_cv_locale_zh_CN=none + fi + rm -fr conftest* + ]) + LOCALE_ZH_CN=$gt_cv_locale_zh_CN + AC_SUBST([LOCALE_ZH_CN]) +]) diff --git a/m4/longlong.m4 b/m4/longlong.m4 new file mode 100644 index 000000000..cca3c1a90 --- /dev/null +++ b/m4/longlong.m4 @@ -0,0 +1,106 @@ +# longlong.m4 serial 14 +dnl Copyright (C) 1999-2007, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG_INT if 'long long int' works. +# This fixes a bug in Autoconf 2.61, but can be removed once we +# assume 2.62 everywhere. + +# Note: If the type 'long long int' exists but is only 32 bits large +# (as on some very old compilers), HAVE_LONG_LONG_INT will not be +# defined. In this case you can treat 'long long int' like 'long int'. + +AC_DEFUN([AC_TYPE_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], + [AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. + dnl If cross compiling, assume the bug isn't important, since + dnl nobody cross compiles for this platform as far as we know. + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[@%:@include + @%:@ifndef LLONG_MAX + @%:@ define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + @%:@ define LLONG_MAX (HALF - 1 + HALF) + @%:@endif]], + [[long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0;]])], + [ac_cv_type_long_long_int=yes], + [ac_cv_type_long_long_int=no], + [ac_cv_type_long_long_int=yes])], + [ac_cv_type_long_long_int=no])]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], [1], + [Define to 1 if the system has the type `long long int'.]) + fi +]) + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.61, but can be removed once we +# assume 2.62 everywhere. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [ac_cv_type_unsigned_long_long_int=yes], + [ac_cv_type_unsigned_long_long_int=no])]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], + [Define to 1 if the system has the type `unsigned long long int'.]) + fi +]) + +# Expands to a C program that can be used to test for simultaneous support +# of 'long long' and 'unsigned long long'. We don't want to say that +# 'long long' is available if 'unsigned long long' is not, or vice versa, +# because too many programs rely on the symmetry between signed and unsigned +# integer types (excluding 'bool'). +AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], +[ + AC_LANG_PROGRAM( + [[/* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull));]]) +]) diff --git a/m4/malloc.m4 b/m4/malloc.m4 new file mode 100644 index 000000000..7a749254a --- /dev/null +++ b/m4/malloc.m4 @@ -0,0 +1,66 @@ +# malloc.m4 serial 12 +dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# gl_FUNC_MALLOC_GNU +# ------------------ +# Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if +# it is not. +AC_DEFUN([gl_FUNC_MALLOC_GNU], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + dnl _AC_FUNC_MALLOC_IF is defined in Autoconf. + _AC_FUNC_MALLOC_IF( + [AC_DEFINE([HAVE_MALLOC_GNU], [1], + [Define to 1 if your system has a GNU libc compatible 'malloc' + function, and to 0 otherwise.])], + [AC_DEFINE([HAVE_MALLOC_GNU], [0]) + gl_REPLACE_MALLOC + ]) +]) + +# gl_FUNC_MALLOC_POSIX +# -------------------- +# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it +# fails), and replace malloc if it is not. +AC_DEFUN([gl_FUNC_MALLOC_POSIX], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) + if test $gl_cv_func_malloc_posix = yes; then + AC_DEFINE([HAVE_MALLOC_POSIX], [1], + [Define if the 'malloc' function is POSIX compliant.]) + else + gl_REPLACE_MALLOC + fi +]) + +# Test whether malloc, realloc, calloc are POSIX compliant, +# Set gl_cv_func_malloc_posix to yes or no accordingly. +AC_DEFUN([gl_CHECK_MALLOC_POSIX], +[ + AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant], + [gl_cv_func_malloc_posix], + [ + dnl It is too dangerous to try to allocate a large amount of memory: + dnl some systems go to their knees when you do that. So assume that + dnl all Unix implementations of the function are POSIX compliant. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[]], + [[#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + choke me + #endif + ]])], + [gl_cv_func_malloc_posix=yes], + [gl_cv_func_malloc_posix=no]) + ]) +]) + +AC_DEFUN([gl_REPLACE_MALLOC], +[ + AC_LIBOBJ([malloc]) + REPLACE_MALLOC=1 +]) diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4 new file mode 100644 index 000000000..28b9c43bf --- /dev/null +++ b/m4/mbrtowc.m4 @@ -0,0 +1,393 @@ +# mbrtowc.m4 serial 18 +dnl Copyright (C) 2001-2002, 2004-2005, 2008-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_MBRTOWC], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + gl_MBSTATE_T_BROKEN + + AC_CHECK_FUNCS_ONCE([mbrtowc]) + if test $ac_cv_func_mbrtowc = no; then + HAVE_MBRTOWC=0 + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_MBRTOWC=1 + else + gl_MBRTOWC_NULL_ARG + gl_MBRTOWC_RETVAL + gl_MBRTOWC_NUL_RETVAL + case "$gl_cv_func_mbrtowc_null_arg" in + *yes) ;; + *) AC_DEFINE([MBRTOWC_NULL_ARG_BUG], [1], + [Define if the mbrtowc function has the NULL string argument bug.]) + REPLACE_MBRTOWC=1 + ;; + esac + case "$gl_cv_func_mbrtowc_retval" in + *yes) ;; + *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1], + [Define if the mbrtowc function returns a wrong return value.]) + REPLACE_MBRTOWC=1 + ;; + esac + case "$gl_cv_func_mbrtowc_nul_retval" in + *yes) ;; + *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1], + [Define if the mbrtowc function does not return 0 for a NUL character.]) + REPLACE_MBRTOWC=1 + ;; + esac + fi + fi + if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then + gl_REPLACE_WCHAR_H + AC_LIBOBJ([mbrtowc]) + gl_PREREQ_MBRTOWC + fi +]) + +dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that +dnl redefines the semantics of the given mbstate_t type. +dnl Result is REPLACE_MBSTATE_T. +dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to +dnl avoid inconsistencies. + +AC_DEFUN([gl_MBSTATE_T_BROKEN], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + AC_CHECK_FUNCS_ONCE([mbsinit]) + AC_CHECK_FUNCS_ONCE([mbrtowc]) + if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then + gl_MBRTOWC_INCOMPLETE_STATE + gl_MBRTOWC_SANITYCHECK + REPLACE_MBSTATE_T=0 + case "$gl_cv_func_mbrtowc_incomplete_state" in + *yes) ;; + *) REPLACE_MBSTATE_T=1 ;; + esac + case "$gl_cv_func_mbrtowc_sanitycheck" in + *yes) ;; + *) REPLACE_MBSTATE_T=1 ;; + esac + else + REPLACE_MBSTATE_T=1 + fi + if test $REPLACE_MBSTATE_T = 1; then + gl_REPLACE_WCHAR_H + fi +]) + +dnl Test whether mbrtowc puts the state into non-initial state when parsing an +dnl incomplete multibyte character. +dnl Result is gl_cv_func_mbrtowc_incomplete_state. + +AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], + [gl_cv_func_mbrtowc_incomplete_state], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on AIX and OSF/1. + aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_JA != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + const char input[] = "B\217\253\344\217\251\316er"; /* "BĂĽĂźer" */ + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) + if (mbsinit (&state)) + return 1; + } + return 0; +}]])], + [gl_cv_func_mbrtowc_incomplete_state=yes], + [gl_cv_func_mbrtowc_incomplete_state=no], + [:]) + fi + ]) +]) + +dnl Test whether mbrtowc works not worse than mbtowc. +dnl Result is gl_cv_func_mbrtowc_sanitycheck. + +AC_DEFUN([gl_MBRTOWC_SANITYCHECK], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc], + [gl_cv_func_mbrtowc_sanitycheck], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on Solaris 8. + solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_ZH_CN != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#include +int main () +{ + /* This fails on Solaris 8: + mbrtowc returns 2, and sets wc to 0x00F0. + mbtowc returns 4 (correct) and sets wc to 0x5EDC. */ + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + char input[] = "B\250\271\201\060\211\070er"; /* "BĂĽĂźer" */ + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, input + 3, 6, &state) != 4 + && mbtowc (&wc, input + 3, 6) == 4) + return 1; + } + return 0; +}]])], + [gl_cv_func_mbrtowc_sanitycheck=yes], + [gl_cv_func_mbrtowc_sanitycheck=no], + [:]) + fi + ]) +]) + +dnl Test whether mbrtowc supports a NULL string argument correctly. +dnl Result is gl_cv_func_mbrtowc_null_arg. + +AC_DEFUN([gl_MBRTOWC_NULL_ARG], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], + [gl_cv_func_mbrtowc_null_arg], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on OSF/1. + osf*) gl_cv_func_mbrtowc_null_arg="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_null_arg="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR_UTF8 != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + mbstate_t state; + wchar_t wc; + int ret; + + memset (&state, '\0', sizeof (mbstate_t)); + wc = (wchar_t) 0xBADFACE; + mbrtowc (&wc, NULL, 5, &state); + /* Check that wc was not modified. */ + if (wc != (wchar_t) 0xBADFACE) + return 1; + } + return 0; +}]])], + [gl_cv_func_mbrtowc_null_arg=yes], + [gl_cv_func_mbrtowc_null_arg=no], + [:]) + fi + ]) +]) + +dnl Test whether mbrtowc, when parsing the end of a multibyte character, +dnl correctly returns the number of bytes that were needed to complete the +dnl character (not the total number of bytes of the multibyte character). +dnl Result is gl_cv_func_mbrtowc_retval. + +AC_DEFUN([gl_MBRTOWC_RETVAL], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc has a correct return value], + [gl_cv_func_mbrtowc_retval], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on HP-UX and Solaris. + hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_retval="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + /* This fails on Solaris. */ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + char input[] = "B\303\274\303\237er"; /* "BĂĽĂźer" */ + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) + { + input[1] = '\0'; + if (mbrtowc (&wc, input + 2, 5, &state) != 1) + return 1; + } + } + /* This fails on HP-UX 11.11. */ + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + char input[] = "B\217\253\344\217\251\316er"; /* "BĂĽĂźer" */ + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) + { + input[1] = '\0'; + if (mbrtowc (&wc, input + 2, 5, &state) != 2) + return 1; + } + } + return 0; +}]])], + [gl_cv_func_mbrtowc_retval=yes], + [gl_cv_func_mbrtowc_retval=no], + [:]) + fi + ]) +]) + +dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0. +dnl Result is gl_cv_func_mbrtowc_nul_retval. + +AC_DEFUN([gl_MBRTOWC_NUL_RETVAL], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character], + [gl_cv_func_mbrtowc_nul_retval], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on Solaris 8 and 9. + solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_ZH_CN != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + /* This fails on Solaris 8 and 9. */ + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + mbstate_t state; + wchar_t wc; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (&wc, "", 1, &state) != 0) + return 1; + } + return 0; +}]])], + [gl_cv_func_mbrtowc_nul_retval=yes], + [gl_cv_func_mbrtowc_nul_retval=no], + [:]) + fi + ]) +]) + +# Prerequisites of lib/mbrtowc.c. +AC_DEFUN([gl_PREREQ_MBRTOWC], [ + : +]) + + +dnl From Paul Eggert + +dnl This override of an autoconf macro can be removed when autoconf 2.60 or +dnl newer can be assumed everywhere. + +m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.60]),[-1],[ +AC_DEFUN([AC_FUNC_MBRTOWC], +[ + dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. + AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], + gl_cv_func_mbrtowc, + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[wchar_t wc; + char const s[] = ""; + size_t n = 1; + mbstate_t state; + return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], + gl_cv_func_mbrtowc=yes, + gl_cv_func_mbrtowc=no)]) + if test $gl_cv_func_mbrtowc = yes; then + AC_DEFINE([HAVE_MBRTOWC], [1], + [Define to 1 if mbrtowc and mbstate_t are properly declared.]) + fi +]) +]) diff --git a/m4/mbsinit.m4 b/m4/mbsinit.m4 new file mode 100644 index 000000000..46c106fc4 --- /dev/null +++ b/m4/mbsinit.m4 @@ -0,0 +1,32 @@ +# mbsinit.m4 serial 4 +dnl Copyright (C) 2008, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_MBSINIT], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + gl_MBSTATE_T_BROKEN + + AC_CHECK_FUNCS_ONCE([mbsinit]) + if test $ac_cv_func_mbsinit = no; then + HAVE_MBSINIT=0 + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_MBSINIT=1 + fi + fi + if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then + gl_REPLACE_WCHAR_H + AC_LIBOBJ([mbsinit]) + gl_PREREQ_MBSINIT + fi +]) + +# Prerequisites of lib/mbsinit.c. +AC_DEFUN([gl_PREREQ_MBSINIT], [ + : +]) diff --git a/m4/mbsrtowcs.m4 b/m4/mbsrtowcs.m4 new file mode 100644 index 000000000..e854337ff --- /dev/null +++ b/m4/mbsrtowcs.m4 @@ -0,0 +1,123 @@ +# mbsrtowcs.m4 serial 7 +dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_MBSRTOWCS], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + gl_MBSTATE_T_BROKEN + + AC_CHECK_FUNCS_ONCE([mbsrtowcs]) + if test $ac_cv_func_mbsrtowcs = no; then + HAVE_MBSRTOWCS=0 + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_MBSRTOWCS=1 + else + gl_MBSRTOWCS_WORKS + case "$gl_cv_func_mbsrtowcs_works" in + *yes) ;; + *) REPLACE_MBSRTOWCS=1 ;; + esac + fi + fi + if test $HAVE_MBSRTOWCS = 0 || test $REPLACE_MBSRTOWCS = 1; then + gl_REPLACE_WCHAR_H + AC_LIBOBJ([mbsrtowcs]) + AC_LIBOBJ([mbsrtowcs-state]) + gl_PREREQ_MBSRTOWCS + fi +]) + +dnl Test whether mbsrtowcs works. +dnl Result is gl_cv_func_mbsrtowcs_works. + +AC_DEFUN([gl_MBSRTOWCS_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbsrtowcs works], + [gl_cv_func_mbsrtowcs_works], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on HP-UX and Solaris. + hpux* | solaris*) gl_cv_func_mbsrtowcs_works="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_mbsrtowcs_works="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +int main () +{ + /* Test whether the function works when started with a conversion state + in non-initial state. This fails on HP-UX 11.11 and Solaris 10. */ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + const char input[] = "B\303\274\303\237er"; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2)) + if (!mbsinit (&state)) + { + const char *src = input + 2; + if (mbsrtowcs (NULL, &src, 10, &state) != 4) + return 1; + } + } + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + const char input[] = "<\306\374\313\334\270\354>"; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (NULL, input + 3, 1, &state) == (size_t)(-2)) + if (!mbsinit (&state)) + { + const char *src = input + 4; + if (mbsrtowcs (NULL, &src, 10, &state) != 3) + return 1; + } + } + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + const char input[] = "B\250\271\201\060\211\070er"; + mbstate_t state; + + memset (&state, '\0', sizeof (mbstate_t)); + if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2)) + if (!mbsinit (&state)) + { + const char *src = input + 2; + if (mbsrtowcs (NULL, &src, 10, &state) != 4) + return 1; + } + } + return 0; +}]])], + [gl_cv_func_mbsrtowcs_works=yes], + [gl_cv_func_mbsrtowcs_works=no], + [:]) + fi + ]) +]) + +# Prerequisites of lib/mbsrtowcs.c. +AC_DEFUN([gl_PREREQ_MBSRTOWCS], [ + : +]) diff --git a/m4/mbstate_t.m4 b/m4/mbstate_t.m4 new file mode 100644 index 000000000..3e2df29f8 --- /dev/null +++ b/m4/mbstate_t.m4 @@ -0,0 +1,34 @@ +# mbstate_t.m4 serial 12 +dnl Copyright (C) 2000-2002, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# From Paul Eggert. + +# BeOS 5 has but does not define mbstate_t, +# so you can't declare an object of that type. +# Check for this incompatibility with Standard C. + +# AC_TYPE_MBSTATE_T +# ----------------- +AC_DEFUN([AC_TYPE_MBSTATE_T], +[ + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl for HP-UX 11.11 + + AC_CACHE_CHECK([for mbstate_t], [ac_cv_type_mbstate_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT[ +# include ]], + [[mbstate_t x; return sizeof x;]])], + [ac_cv_type_mbstate_t=yes], + [ac_cv_type_mbstate_t=no])]) + if test $ac_cv_type_mbstate_t = yes; then + AC_DEFINE([HAVE_MBSTATE_T], [1], + [Define to 1 if declares mbstate_t.]) + else + AC_DEFINE([mbstate_t], [int], + [Define to a type if does not define.]) + fi +]) diff --git a/m4/memchr.m4 b/m4/memchr.m4 new file mode 100644 index 000000000..b05a79a02 --- /dev/null +++ b/m4/memchr.m4 @@ -0,0 +1,87 @@ +# memchr.m4 serial 9 +dnl Copyright (C) 2002-2004, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN_ONCE([gl_FUNC_MEMCHR], +[ + dnl Check for prerequisites for memory fence checks. + gl_FUNC_MMAP_ANON + AC_CHECK_HEADERS_ONCE([sys/mman.h]) + AC_CHECK_FUNCS_ONCE([mprotect]) + + dnl These days, we assume memchr is present. But just in case... + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([memchr]) + if test $ac_cv_func_memchr = yes; then + # Detect platform-specific bugs in some versions of glibc: + # memchr should not dereference anything with length 0 + # http://bugzilla.redhat.com/499689 + # memchr should not dereference overestimated length after a match + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 + # http://sourceware.org/bugzilla/show_bug.cgi?id=10162 + # Assume that memchr works on platforms that lack mprotect. + AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#if HAVE_SYS_MMAN_H +# include +# include +# include +# include +# ifndef MAP_FILE +# define MAP_FILE 0 +# endif +#endif +]], [[ + char *fence = NULL; +#if HAVE_SYS_MMAN_H && HAVE_MPROTECT +# if HAVE_MAP_ANONYMOUS + const int flags = MAP_ANONYMOUS | MAP_PRIVATE; + const int fd = -1; +# else /* !HAVE_MAP_ANONYMOUS */ + const int flags = MAP_FILE | MAP_PRIVATE; + int fd = open ("/dev/zero", O_RDONLY, 0666); + if (fd >= 0) +# endif + { + int pagesize = getpagesize (); + char *two_pages = + (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, + flags, fd, 0); + if (two_pages != (char *)(-1) + && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) + fence = two_pages + pagesize; + } +#endif + if (fence) + { + if (memchr (fence, 0, 0)) + return 1; + strcpy (fence - 9, "12345678"); + if (memchr (fence - 9, 0, 79) != fence - 1) + return 2; + if (memchr (fence - 1, 0, 3) != fence - 1) + return 3; + } + return 0; +]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no], + [dnl Be pessimistic for now. + gl_cv_func_memchr_works="guessing no"])]) + if test "$gl_cv_func_memchr_works" != yes; then + REPLACE_MEMCHR=1 + fi + else + HAVE_MEMCHR=0 + fi + if test $HAVE_MEMCHR = 0 || test $REPLACE_MEMCHR = 1; then + AC_LIBOBJ([memchr]) + gl_PREREQ_MEMCHR + fi +]) + +# Prerequisites of lib/memchr.c. +AC_DEFUN([gl_PREREQ_MEMCHR], [ + AC_CHECK_HEADERS([bp-sym.h]) +]) diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4 new file mode 100644 index 000000000..12df771e4 --- /dev/null +++ b/m4/mempcpy.m4 @@ -0,0 +1,27 @@ +# mempcpy.m4 serial 10 +dnl Copyright (C) 2003-2004, 2006-2007, 2009-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_MEMPCPY], +[ + dnl Persuade glibc to declare mempcpy(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + dnl The mempcpy() declaration in lib/string.in.h uses 'restrict'. + AC_REQUIRE([AC_C_RESTRICT]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REPLACE_FUNCS([mempcpy]) + if test $ac_cv_func_mempcpy = no; then + HAVE_MEMPCPY=0 + gl_PREREQ_MEMPCPY + fi +]) + +# Prerequisites of lib/mempcpy.c. +AC_DEFUN([gl_PREREQ_MEMPCPY], [ + : +]) diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4 new file mode 100644 index 000000000..a6b7b9ac3 --- /dev/null +++ b/m4/mmap-anon.m4 @@ -0,0 +1,59 @@ +# mmap-anon.m4 serial 8 +dnl Copyright (C) 2005, 2007, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Detect how mmap can be used to create anonymous (not file-backed) memory +# mappings. +# - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS +# and MAP_ANON exist and have the same value. +# - On HP-UX, only MAP_ANONYMOUS exists. +# - On MacOS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists. +# - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be +# used. + +AC_DEFUN([gl_FUNC_MMAP_ANON], +[ + dnl Work around a bug of AC_EGREP_CPP in autoconf-2.57. + AC_REQUIRE([AC_PROG_CPP]) + AC_REQUIRE([AC_PROG_EGREP]) + + dnl Persuade glibc to define MAP_ANONYMOUS. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + # Check for mmap(). Don't use AC_FUNC_MMAP, because it checks too much: it + # fails on HP-UX 11, because MAP_FIXED mappings do not work. But this is + # irrelevant for anonymous mappings. + AC_CHECK_FUNC([mmap], [gl_have_mmap=yes], [gl_have_mmap=no]) + + # Try to allow MAP_ANONYMOUS. + gl_have_mmap_anonymous=no + if test $gl_have_mmap = yes; then + AC_MSG_CHECKING([for MAP_ANONYMOUS]) + AC_EGREP_CPP([I cant identify this map.], [ +#include +#ifdef MAP_ANONYMOUS + I cant identify this map. +#endif +], + [gl_have_mmap_anonymous=yes]) + if test $gl_have_mmap_anonymous != yes; then + AC_EGREP_CPP([I cant identify this map.], [ +#include +#ifdef MAP_ANON + I cant identify this map. +#endif +], + [AC_DEFINE([MAP_ANONYMOUS], [MAP_ANON], + [Define to a substitute value for mmap()'s MAP_ANONYMOUS flag.]) + gl_have_mmap_anonymous=yes]) + fi + AC_MSG_RESULT([$gl_have_mmap_anonymous]) + if test $gl_have_mmap_anonymous = yes; then + AC_DEFINE([HAVE_MAP_ANONYMOUS], [1], + [Define to 1 if mmap()'s MAP_ANONYMOUS flag is available after including + config.h and .]) + fi + fi +]) diff --git a/m4/multiarch.m4 b/m4/multiarch.m4 new file mode 100644 index 000000000..389bd2bba --- /dev/null +++ b/m4/multiarch.m4 @@ -0,0 +1,65 @@ +# multiarch.m4 serial 5 +dnl Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Determine whether the compiler is or may be producing universal binaries. +# +# On MacOS X 10.5 and later systems, the user can create libraries and +# executables that work on multiple system types--known as "fat" or +# "universal" binaries--by specifying multiple '-arch' options to the +# compiler but only a single '-arch' option to the preprocessor. Like +# this: +# +# ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +# CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +# CPP="gcc -E" CXXCPP="g++ -E" +# +# Detect this situation and set the macro AA_APPLE_UNIVERSAL_BUILD at the +# beginning of config.h and set APPLE_UNIVERSAL_BUILD accordingly. + +AC_DEFUN_ONCE([gl_MULTIARCH], +[ + dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN. + gl_cv_c_multiarch=no + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + ]])], + [ + dnl Check for potential -arch flags. It is not universal unless + dnl there are at least two -arch flags with different values. + arch= + prev= + for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do + if test -n "$prev"; then + case $word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$arch" || test "$arch" = "$word"; then + arch="$word" + else + gl_cv_c_multiarch=yes + fi + ;; + esac + prev= + else + if test "x$word" = "x-arch"; then + prev=arch + fi + fi + done + ]) + if test $gl_cv_c_multiarch = yes; then + AC_DEFINE([AA_APPLE_UNIVERSAL_BUILD], [1], + [Define if the compiler is building for multiple architectures of Apple platforms at once.]) + APPLE_UNIVERSAL_BUILD=1 + else + APPLE_UNIVERSAL_BUILD=0 + fi + AC_SUBST([APPLE_UNIVERSAL_BUILD]) +]) diff --git a/m4/nl_langinfo.m4 b/m4/nl_langinfo.m4 new file mode 100644 index 000000000..ad456a264 --- /dev/null +++ b/m4/nl_langinfo.m4 @@ -0,0 +1,25 @@ +# nl_langinfo.m4 serial 3 +dnl Copyright (C) 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_NL_LANGINFO], +[ + AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) + AC_REQUIRE([gl_LANGINFO_H]) + AC_CHECK_FUNCS_ONCE([nl_langinfo]) + if test $ac_cv_func_nl_langinfo = yes; then + if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1; then + : + else + REPLACE_NL_LANGINFO=1 + AC_DEFINE([REPLACE_NL_LANGINFO], [1], + [Define if nl_langinfo exists but is overridden by gnulib.]) + AC_LIBOBJ([nl_langinfo]) + fi + else + HAVE_NL_LANGINFO=0 + AC_LIBOBJ([nl_langinfo]) + fi +]) diff --git a/m4/printf.m4 b/m4/printf.m4 new file mode 100644 index 000000000..e850862c0 --- /dev/null +++ b/m4/printf.m4 @@ -0,0 +1,1462 @@ +# printf.m4 serial 35 +dnl Copyright (C) 2003, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Test whether the *printf family of functions supports the 'j', 'z', 't', +dnl 'L' size specifiers. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_sizes_c99. + +AC_DEFUN([gl_PRINTF_SIZES_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports size specifiers as in C99], + [gl_cv_func_printf_sizes_c99], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +# include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +# include +#endif +static char buf[100]; +int main () +{ +#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX + buf[0] = '\0'; + if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0 + || strcmp (buf, "12345671 33") != 0) + return 1; +#endif + buf[0] = '\0'; + if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0 + || strcmp (buf, "12345672 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0 + || strcmp (buf, "12345673 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0 + || strcmp (buf, "1.5 33") != 0) + return 1; + return 0; +}]])], + [gl_cv_func_printf_sizes_c99=yes], + [gl_cv_func_printf_sizes_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_printf_sizes_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_sizes_c99="guessing no";; + darwin*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_printf_sizes_c99="guessing no";; + openbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on Solaris >= 2.10. + solaris2.[0-9]*) gl_cv_func_printf_sizes_c99="guessing no";; + solaris*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_sizes_c99="guessing no";; + netbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_sizes_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports 'long double' +dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_long_double. + +AC_DEFUN([gl_PRINTF_LONG_DOUBLE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports 'long double' arguments], + [gl_cv_func_printf_long_double], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[10000]; +int main () +{ + buf[0] = '\0'; + if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.750000 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.750000e+00 33") != 0) + return 1; + buf[0] = '\0'; + if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.75 33") != 0) + return 1; + return 0; +}]])], + [gl_cv_func_printf_long_double=yes], + [gl_cv_func_printf_long_double=no], + [ +changequote(,)dnl + case "$host_os" in + beos*) gl_cv_func_printf_long_double="guessing no";; + mingw* | pw*) gl_cv_func_printf_long_double="guessing no";; + *) gl_cv_func_printf_long_double="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports infinite and NaN +dnl 'double' arguments and negative zero arguments in the %f, %e, %g +dnl directives. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_infinite. + +AC_DEFUN([gl_PRINTF_INFINITE], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports infinite 'double' arguments], + [gl_cv_func_printf_infinite], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static int +strisnan (const char *string, size_t start_index, size_t end_index) +{ + if (start_index < end_index) + { + if (string[start_index] == '-') + start_index++; + if (start_index + 3 <= end_index + && memcmp (string + start_index, "nan", 3) == 0) + { + start_index += 3; + if (start_index == end_index + || (string[start_index] == '(' && string[end_index - 1] == ')')) + return 1; + } + } + return 0; +} +static int +have_minus_zero () +{ + static double plus_zero = 0.0; + double minus_zero = - plus_zero; + return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0; +} +static char buf[10000]; +static double zero = 0.0; +int main () +{ + if (sprintf (buf, "%f", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%f", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%f", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%e", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%e", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%e", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%g", 1.0 / 0.0) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%g", -1.0 / 0.0) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%g", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + /* This test fails on HP-UX 10.20. */ + if (have_minus_zero ()) + if (sprintf (buf, "%g", - zero) < 0 + || strcmp (buf, "-0") != 0) + return 1; + return 0; +}]])], + [gl_cv_func_printf_infinite=yes], + [gl_cv_func_printf_infinite=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_infinite="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_infinite="guessing no";; + darwin*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";; + hpux*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_infinite="guessing no";; + netbsd*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_infinite="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_infinite="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports infinite and NaN +dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_infinite_long_double. + +AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_BIGENDIAN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + dnl The user can set or unset the variable gl_printf_safe to indicate + dnl that he wishes a safe handling of non-IEEE-754 'long double' values. + if test -n "$gl_printf_safe"; then + AC_DEFINE([CHECK_PRINTF_SAFE], [1], + [Define if you wish *printf() functions that have a safe handling of + non-IEEE-754 'long double' values.]) + fi + case "$gl_cv_func_printf_long_double" in + *yes) + AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments], + [gl_cv_func_printf_infinite_long_double], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +]GL_NOCRASH[ +#include +#include +#include +static int +strisnan (const char *string, size_t start_index, size_t end_index) +{ + if (start_index < end_index) + { + if (string[start_index] == '-') + start_index++; + if (start_index + 3 <= end_index + && memcmp (string + start_index, "nan", 3) == 0) + { + start_index += 3; + if (start_index == end_index + || (string[start_index] == '(' && string[end_index - 1] == ')')) + return 1; + } + } + return 0; +} +static char buf[10000]; +static long double zeroL = 0.0L; +int main () +{ + nocrash_init(); + if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%Lf", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%Le", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) + return 1; + if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) + return 1; + if (sprintf (buf, "%Lg", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; +#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) +/* Representation of an 80-bit 'long double' as an initializer for a sequence + of 'unsigned int' words. */ +# ifdef WORDS_BIGENDIAN +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ + ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ + (unsigned int) (mantlo) << 16 \ + } +# else +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { mantlo, manthi, exponent } +# endif + { /* Quiet NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { + /* Signalling NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-Infinity. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-Zero. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Unnormalized number. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } + { /* Pseudo-Denormal. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) + return 1; + } +#endif + return 0; +}]])], + [gl_cv_func_printf_infinite_long_double=yes], + [gl_cv_func_printf_infinite_long_double=no], + [ +changequote(,)dnl + case "$host_cpu" in + # Guess no on ia64, x86_64, i386. + ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";; + *) + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_infinite_long_double="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_infinite_long_double="guessing no";; + darwin*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";; + hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_infinite_long_double="guessing no";; + netbsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_infinite_long_double="guessing no";; + esac + ;; + esac +changequote([,])dnl + ]) + ]) + ;; + *) + gl_cv_func_printf_infinite_long_double="irrelevant" + ;; + esac +]) + +dnl Test whether the *printf family of functions supports the 'a' and 'A' +dnl conversion specifier for hexadecimal output of floating-point numbers. +dnl (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_directive_a. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_A], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives], + [gl_cv_func_printf_directive_a], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0 + || (strcmp (buf, "0x1.922p+1 33") != 0 + && strcmp (buf, "0x3.244p+0 33") != 0 + && strcmp (buf, "0x6.488p-1 33") != 0 + && strcmp (buf, "0xc.91p-2 33") != 0)) + return 1; + if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0 + || (strcmp (buf, "-0X1.922P+1 33") != 0 + && strcmp (buf, "-0X3.244P+0 33") != 0 + && strcmp (buf, "-0X6.488P-1 33") != 0 + && strcmp (buf, "-0XC.91P-2 33") != 0)) + return 1; + /* This catches a FreeBSD 6.1 bug: it doesn't round. */ + if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 + || (strcmp (buf, "0x1.83p+0 33") != 0 + && strcmp (buf, "0x3.05p-1 33") != 0 + && strcmp (buf, "0x6.0ap-2 33") != 0 + && strcmp (buf, "0xc.14p-3 33") != 0)) + return 1; + /* This catches a FreeBSD 6.1 bug. See + */ + if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0 + || buf[0] == '0') + return 1; + /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug. */ + if (sprintf (buf, "%.1a", 1.999) < 0 + || (strcmp (buf, "0x1.0p+1") != 0 + && strcmp (buf, "0x2.0p+0") != 0 + && strcmp (buf, "0x4.0p-1") != 0 + && strcmp (buf, "0x8.0p-2") != 0)) + return 1; + /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a + glibc 2.4 bug . */ + if (sprintf (buf, "%.1La", 1.999L) < 0 + || (strcmp (buf, "0x1.0p+1") != 0 + && strcmp (buf, "0x2.0p+0") != 0 + && strcmp (buf, "0x4.0p-1") != 0 + && strcmp (buf, "0x8.0p-2") != 0)) + return 1; + return 0; +}]])], + [gl_cv_func_printf_directive_a=yes], + [gl_cv_func_printf_directive_a=no], + [ + case "$host_os" in + # Guess yes on glibc >= 2.5 systems. + *-gnu*) + AC_EGREP_CPP([BZ2908], [ + #include + #ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2) + BZ2908 + #endif + #endif + ], + [gl_cv_func_printf_directive_a="guessing yes"], + [gl_cv_func_printf_directive_a="guessing no"]) + ;; + # If we don't know, assume the worst. + *) gl_cv_func_printf_directive_a="guessing no";; + esac + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the %F format +dnl directive. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_directive_f. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_F], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'F' directive], + [gl_cv_func_printf_directive_f], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0 + || strcmp (buf, "1234567.000000 33") != 0) + return 1; + if (sprintf (buf, "%F", 1.0 / 0.0) < 0 + || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0)) + return 1; + /* This catches a Cygwin 1.5.x bug. */ + if (sprintf (buf, "%.F", 1234.0) < 0 + || strcmp (buf, "1234") != 0) + return 1; + return 0; +}]])], + [gl_cv_func_printf_directive_f=yes], + [gl_cv_func_printf_directive_f=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_directive_f="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_directive_f="guessing no";; + darwin*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on Solaris >= 2.10. + solaris2.[0-9]*) gl_cv_func_printf_directive_f="guessing no";; + solaris*) gl_cv_func_printf_directive_f="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_directive_f="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the %n format +dnl directive. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_printf_directive_n. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_N], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'n' directive], + [gl_cv_func_printf_directive_n], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char fmtstring[10]; +static char buf[100]; +int main () +{ + int count = -1; + /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) + support %n in format strings in read-only memory but not in writable + memory. */ + strcpy (fmtstring, "%d %n"); + if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0 + || strcmp (buf, "123 ") != 0 + || count != 4) + return 1; + return 0; +}]])], + [gl_cv_func_printf_directive_n=yes], + [gl_cv_func_printf_directive_n=no], + [ +changequote(,)dnl + case "$host_os" in + *) gl_cv_func_printf_directive_n="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the %ls format +dnl directive and in particular, when a precision is specified, whether +dnl the functions stop converting the wide string argument when the number +dnl of bytes that have been produced by this conversion equals or exceeds +dnl the precision. +dnl Result is gl_cv_func_printf_directive_ls. + +AC_DEFUN([gl_PRINTF_DIRECTIVE_LS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the 'ls' directive], + [gl_cv_func_printf_directive_ls], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . */ +#include +#include +#include +#include +#include +int main () +{ + char buf[100]; + /* Test whether %ls works at all. + This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on + Cygwin 1.5. */ + { + static const wchar_t wstring[] = { 'a', 'b', 'c', 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "abc") != 0) + return 1; + } + /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an + assertion failure inside libc), but not on OpenBSD 4.0. */ + { + static const wchar_t wstring[] = { 'a', 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "a") != 0) + return 1; + } + /* Test whether precisions in %ls are supported as specified in ISO C 99 + section 7.19.6.1: + "If a precision is specified, no more than that many bytes are written + (including shift sequences, if any), and the array shall contain a + null wide character if, to equal the multibyte character sequence + length given by the precision, the function would need to access a + wide character one past the end of the array." + This test fails on Solaris 10. */ + { + static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 }; + buf[0] = '\0'; + if (sprintf (buf, "%.2ls", wstring) < 0 + || strcmp (buf, "ab") != 0) + return 1; + } + return 0; +}]])], + [gl_cv_func_printf_directive_ls=yes], + [gl_cv_func_printf_directive_ls=no], + [ +changequote(,)dnl + case "$host_os" in + openbsd*) gl_cv_func_printf_directive_ls="guessing no";; + irix*) gl_cv_func_printf_directive_ls="guessing no";; + solaris*) gl_cv_func_printf_directive_ls="guessing no";; + cygwin*) gl_cv_func_printf_directive_ls="guessing no";; + beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";; + *) gl_cv_func_printf_directive_ls="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports POSIX/XSI format +dnl strings with positions. (POSIX:2001) +dnl Result is gl_cv_func_printf_positions. + +AC_DEFUN([gl_PRINTF_POSITIONS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions], + [gl_cv_func_printf_positions], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +/* The string "%2$d %1$d", with dollar characters protected from the shell's + dollar expansion (possibly an autoconf bug). */ +static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; +static char buf[100]; +int main () +{ + sprintf (buf, format, 33, 55); + return (strcmp (buf, "55 33") != 0); +}]])], + [gl_cv_func_printf_positions=yes], + [gl_cv_func_printf_positions=no], + [ +changequote(,)dnl + case "$host_os" in + netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*) + gl_cv_func_printf_positions="guessing no";; + beos*) gl_cv_func_printf_positions="guessing no";; + mingw* | pw*) gl_cv_func_printf_positions="guessing no";; + *) gl_cv_func_printf_positions="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports POSIX/XSI format +dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001) +dnl Result is gl_cv_func_printf_flag_grouping. + +AC_DEFUN([gl_PRINTF_FLAG_GROUPING], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the grouping flag], + [gl_cv_func_printf_flag_grouping], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%'d %d", 1234567, 99) < 0 + || buf[strlen (buf) - 1] != '9') + return 1; + return 0; +}]])], + [gl_cv_func_printf_flag_grouping=yes], + [gl_cv_func_printf_flag_grouping=no], + [ +changequote(,)dnl + case "$host_os" in + cygwin*) gl_cv_func_printf_flag_grouping="guessing no";; + netbsd*) gl_cv_func_printf_flag_grouping="guessing no";; + mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";; + *) gl_cv_func_printf_flag_grouping="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports the - flag correctly. +dnl (ISO C99.) See +dnl +dnl Result is gl_cv_func_printf_flag_leftadjust. + +AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly], + [gl_cv_func_printf_flag_leftadjust], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + /* Check that a '-' flag is not annihilated by a negative width. */ + if (sprintf (buf, "a%-*sc", -3, "b") < 0 + || strcmp (buf, "ab c") != 0) + return 1; + return 0; +}]])], + [gl_cv_func_printf_flag_leftadjust=yes], + [gl_cv_func_printf_flag_leftadjust=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on HP-UX 11. + hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";; + # Guess no on HP-UX 10 and older. + hpux*) gl_cv_func_printf_flag_leftadjust="guessing no";; + # Guess yes otherwise. + *) gl_cv_func_printf_flag_leftadjust="guessing yes";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports padding of non-finite +dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See +dnl +dnl Result is gl_cv_func_printf_flag_zero. + +AC_DEFUN([gl_PRINTF_FLAG_ZERO], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports the zero flag correctly], + [gl_cv_func_printf_flag_zero], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0 + || (strcmp (buf, " inf") != 0 + && strcmp (buf, " infinity") != 0)) + return 1; + return 0; +}]])], + [gl_cv_func_printf_flag_zero=yes], + [gl_cv_func_printf_flag_zero=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_flag_zero="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_flag_zero="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions supports large precisions. +dnl On mingw, precisions larger than 512 are treated like 512, in integer, +dnl floating-point or pointer output. On BeOS, precisions larger than 1044 +dnl crash the program. +dnl Result is gl_cv_func_printf_precision. + +AC_DEFUN([gl_PRINTF_PRECISION], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf supports large precisions], + [gl_cv_func_printf_precision], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[5000]; +int main () +{ +#ifdef __BEOS__ + /* On BeOS, this would crash and show a dialog box. Avoid the crash. */ + return 1; +#endif + if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3) + return 1; + return 0; +}]])], + [gl_cv_func_printf_precision=yes], + [gl_cv_func_printf_precision=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess no only on native Win32 and BeOS systems. + mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; + beos*) gl_cv_func_printf_precision="guessing no" ;; + *) gl_cv_func_printf_precision="guessing yes" ;; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the *printf family of functions recovers gracefully in case +dnl of an out-of-memory condition, or whether it crashes the entire program. +dnl Result is gl_cv_func_printf_enomem. + +AC_DEFUN([gl_PRINTF_ENOMEM], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_MULTIARCH]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether printf survives out-of-memory conditions], + [gl_cv_func_printf_enomem], + [ + gl_cv_func_printf_enomem="guessing no" + if test "$cross_compiling" = no; then + if test $APPLE_UNIVERSAL_BUILD = 0; then + AC_LANG_CONFTEST([AC_LANG_SOURCE([ +]GL_NOCRASH[ +changequote(,)dnl +#include +#include +#include +#include +#include +int main() +{ + struct rlimit limit; + int ret; + nocrash_init (); + /* Some printf implementations allocate temporary space with malloc. */ + /* On BSD systems, malloc() is limited by RLIMIT_DATA. */ +#ifdef RLIMIT_DATA + if (getrlimit (RLIMIT_DATA, &limit) < 0) + return 77; + if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) + limit.rlim_max = 5000000; + limit.rlim_cur = limit.rlim_max; + if (setrlimit (RLIMIT_DATA, &limit) < 0) + return 77; +#endif + /* On Linux systems, malloc() is limited by RLIMIT_AS. */ +#ifdef RLIMIT_AS + if (getrlimit (RLIMIT_AS, &limit) < 0) + return 77; + if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) + limit.rlim_max = 5000000; + limit.rlim_cur = limit.rlim_max; + if (setrlimit (RLIMIT_AS, &limit) < 0) + return 77; +#endif + /* Some printf implementations allocate temporary space on the stack. */ +#ifdef RLIMIT_STACK + if (getrlimit (RLIMIT_STACK, &limit) < 0) + return 77; + if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) + limit.rlim_max = 5000000; + limit.rlim_cur = limit.rlim_max; + if (setrlimit (RLIMIT_STACK, &limit) < 0) + return 77; +#endif + ret = printf ("%.5000000f", 1.0); + return !(ret == 5000002 || (ret < 0 && errno == ENOMEM)); +} +changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then + (./conftest + result=$? + if test $result != 0 && test $result != 77; then result=1; fi + exit $result + ) >/dev/null 2>/dev/null + case $? in + 0) gl_cv_func_printf_enomem="yes" ;; + 77) gl_cv_func_printf_enomem="guessing no" ;; + *) gl_cv_func_printf_enomem="no" ;; + esac + else + gl_cv_func_printf_enomem="guessing no" + fi + rm -fr conftest* + else + dnl A universal build on Apple MacOS X platforms. + dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode. + dnl But we need a configuration result that is valid in both modes. + gl_cv_func_printf_enomem="guessing no" + fi + fi + if test "$gl_cv_func_printf_enomem" = "guessing no"; then +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on Solaris. + solaris*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on AIX. + aix*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on HP-UX/hppa. + hpux*) case "$host_cpu" in + hppa*) gl_cv_func_printf_enomem="guessing yes";; + *) gl_cv_func_printf_enomem="guessing no";; + esac + ;; + # Guess yes on IRIX. + irix*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on OSF/1. + osf*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_printf_enomem="guessing yes";; + # Guess yes on Haiku. + haiku*) gl_cv_func_printf_enomem="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_enomem="guessing no";; + esac +changequote([,])dnl + fi + ]) +]) + +dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001) +dnl Result is ac_cv_func_snprintf. + +AC_DEFUN([gl_SNPRINTF_PRESENCE], +[ + AC_CHECK_FUNCS_ONCE([snprintf]) +]) + +dnl Test whether the string produced by the snprintf function is always NUL +dnl terminated. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_snprintf_truncation_c99. + +AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether snprintf truncates the result as in C99], + [gl_cv_func_snprintf_truncation_c99], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + strcpy (buf, "ABCDEF"); + snprintf (buf, 3, "%d %d", 4567, 89); + if (memcmp (buf, "45\0DEF", 6) != 0) + return 1; + return 0; +}]])], + [gl_cv_func_snprintf_truncation_c99=yes], + [gl_cv_func_snprintf_truncation_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";; + darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_snprintf_truncation_c99="guessing no";; + openbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + solaris*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + aix*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";; + hpux*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on IRIX >= 6.5. + irix6.5) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on OSF/1 >= 5. + osf[3-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + osf*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_snprintf_truncation_c99="guessing no";; + netbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_snprintf_truncation_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the return value of the snprintf function is the number +dnl of bytes (excluding the terminating NUL) that would have been produced +dnl if the buffer had been large enough. (ISO C99, POSIX:2001) +dnl For example, this test program fails on IRIX 6.5: +dnl --------------------------------------------------------------------- +dnl #include +dnl int main() +dnl { +dnl static char buf[8]; +dnl int retval = snprintf (buf, 3, "%d", 12345); +dnl return retval >= 0 && retval < 3; +dnl } +dnl --------------------------------------------------------------------- +dnl Result is gl_cv_func_snprintf_retval_c99. + +AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether snprintf returns a byte count as in C99], + [gl_cv_func_snprintf_retval_c99], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char buf[100]; +int main () +{ + strcpy (buf, "ABCDEF"); + if (snprintf (buf, 3, "%d %d", 4567, 89) != 7) + return 1; + return 0; +}]])], + [gl_cv_func_snprintf_retval_c99=yes], + [gl_cv_func_snprintf_retval_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_retval_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_retval_c99="guessing no";; + darwin*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_snprintf_retval_c99="guessing no";; + openbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_snprintf_retval_c99="guessing no";; + solaris*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_retval_c99="guessing no";; + aix*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_snprintf_retval_c99="guessing no";; + netbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_snprintf_retval_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the snprintf function supports the %n format directive +dnl also in truncated portions of the format string. (ISO C99, POSIX:2001) +dnl Result is gl_cv_func_snprintf_directive_n. + +AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive], + [gl_cv_func_snprintf_directive_n], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static char fmtstring[10]; +static char buf[100]; +int main () +{ + int count = -1; + /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) + support %n in format strings in read-only memory but not in writable + memory. */ + strcpy (fmtstring, "%d %n"); + snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55); + if (count != 6) + return 1; + return 0; +}]])], + [gl_cv_func_snprintf_directive_n=yes], + [gl_cv_func_snprintf_directive_n=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_directive_n="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_directive_n="guessing no";; + darwin*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_snprintf_directive_n="guessing no";; + solaris*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_directive_n="guessing no";; + aix*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on IRIX >= 6.5. + irix6.5) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on OSF/1 >= 5. + osf[3-4]*) gl_cv_func_snprintf_directive_n="guessing no";; + osf*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_snprintf_directive_n="guessing no";; + netbsd*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_snprintf_directive_n="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_snprintf_directive_n="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl Test whether the snprintf function, when passed a size = 1, writes any +dnl output without bounds in this case, behaving like sprintf. This is the +dnl case on Linux libc5. +dnl Result is gl_cv_func_snprintf_size1. + +AC_DEFUN([gl_SNPRINTF_SIZE1], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_CACHE_CHECK([whether snprintf respects a size of 1], + [gl_cv_func_snprintf_size1], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +int main() +{ + static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; + snprintf (buf, 1, "%d", 12345); + return buf[1] != 'E'; +}]])], + [gl_cv_func_snprintf_size1=yes], + [gl_cv_func_snprintf_size1=no], + [gl_cv_func_snprintf_size1="guessing yes"]) + ]) +]) + +dnl Test whether the vsnprintf function, when passed a zero size, produces no +dnl output. (ISO C99, POSIX:2001) +dnl For example, snprintf nevertheless writes a NUL byte in this case +dnl on OSF/1 5.1: +dnl --------------------------------------------------------------------- +dnl #include +dnl int main() +dnl { +dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; +dnl snprintf (buf, 0, "%d", 12345); +dnl return buf[0] != 'D'; +dnl } +dnl --------------------------------------------------------------------- +dnl And vsnprintf writes any output without bounds in this case, behaving like +dnl vsprintf, on HP-UX 11 and OSF/1 5.1: +dnl --------------------------------------------------------------------- +dnl #include +dnl #include +dnl static int my_snprintf (char *buf, int size, const char *format, ...) +dnl { +dnl va_list args; +dnl int ret; +dnl va_start (args, format); +dnl ret = vsnprintf (buf, size, format, args); +dnl va_end (args); +dnl return ret; +dnl } +dnl int main() +dnl { +dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; +dnl my_snprintf (buf, 0, "%d", 12345); +dnl return buf[0] != 'D'; +dnl } +dnl --------------------------------------------------------------------- +dnl Result is gl_cv_func_vsnprintf_zerosize_c99. + +AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99], + [gl_cv_func_vsnprintf_zerosize_c99], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +static int my_snprintf (char *buf, int size, const char *format, ...) +{ + va_list args; + int ret; + va_start (args, format); + ret = vsnprintf (buf, size, format, args); + va_end (args); + return ret; +} +int main() +{ + static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; + my_snprintf (buf, 0, "%d", 12345); + return buf[0] != 'D'; +}]])], + [gl_cv_func_vsnprintf_zerosize_c99=yes], + [gl_cv_func_vsnprintf_zerosize_c99=no], + [ +changequote(,)dnl + case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on MacOS X >= 10.3. + darwin[1-6].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + darwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on Cygwin. + cygwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. + solaris2.[0-5]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + solaris*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + aix*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on IRIX >= 6.5. + irix6.5) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + netbsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on BeOS. + beos*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on mingw. + mingw* | pw*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + esac +changequote([,])dnl + ]) + ]) +]) + +dnl The results of these tests on various platforms are: +dnl +dnl 1 = gl_PRINTF_SIZES_C99 +dnl 2 = gl_PRINTF_LONG_DOUBLE +dnl 3 = gl_PRINTF_INFINITE +dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE +dnl 5 = gl_PRINTF_DIRECTIVE_A +dnl 6 = gl_PRINTF_DIRECTIVE_F +dnl 7 = gl_PRINTF_DIRECTIVE_N +dnl 8 = gl_PRINTF_DIRECTIVE_LS +dnl 9 = gl_PRINTF_POSITIONS +dnl 10 = gl_PRINTF_FLAG_GROUPING +dnl 11 = gl_PRINTF_FLAG_LEFTADJUST +dnl 12 = gl_PRINTF_FLAG_ZERO +dnl 13 = gl_PRINTF_PRECISION +dnl 14 = gl_PRINTF_ENOMEM +dnl 15 = gl_SNPRINTF_PRESENCE +dnl 16 = gl_SNPRINTF_TRUNCATION_C99 +dnl 17 = gl_SNPRINTF_RETVAL_C99 +dnl 18 = gl_SNPRINTF_DIRECTIVE_N +dnl 19 = gl_SNPRINTF_SIZE1 +dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99 +dnl +dnl 1 = checking whether printf supports size specifiers as in C99... +dnl 2 = checking whether printf supports 'long double' arguments... +dnl 3 = checking whether printf supports infinite 'double' arguments... +dnl 4 = checking whether printf supports infinite 'long double' arguments... +dnl 5 = checking whether printf supports the 'a' and 'A' directives... +dnl 6 = checking whether printf supports the 'F' directive... +dnl 7 = checking whether printf supports the 'n' directive... +dnl 8 = checking whether printf supports the 'ls' directive... +dnl 9 = checking whether printf supports POSIX/XSI format strings with positions... +dnl 10 = checking whether printf supports the grouping flag... +dnl 11 = checking whether printf supports the left-adjust flag correctly... +dnl 12 = checking whether printf supports the zero flag correctly... +dnl 13 = checking whether printf supports large precisions... +dnl 14 = checking whether printf survives out-of-memory conditions... +dnl 15 = checking for snprintf... +dnl 16 = checking whether snprintf truncates the result as in C99... +dnl 17 = checking whether snprintf returns a byte count as in C99... +dnl 18 = checking whether snprintf fully supports the 'n' directive... +dnl 19 = checking whether snprintf respects a size of 1... +dnl 20 = checking whether vsnprintf respects a zero size as in C99... +dnl +dnl . = yes, # = no. +dnl +dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . . +dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . . +dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . . +dnl MacOS X 10.3.9 . . . . # . . . . . . # . # . . . . . . +dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . . +dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . . +dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . . +dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . . +dnl Solaris 10 . . # # # . . # . . . # . . . . . . . . +dnl Solaris 2.6 ... 9 # . # # # # . # . . . # . . . . . . . . +dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # # +dnl AIX 5.2, 7.1 . . # # # . . . . . . # . . . . . . . . +dnl AIX 4.3.2, 5.1 # . # # # # . . . . . # . . . . . . . . +dnl HP-UX 11.31 . . . . # . . . . . . # . . . . # # . . +dnl HP-UX 11.{00,11,23} # . . . # # . . . . . # . . . . # # . # +dnl HP-UX 10.20 # . # . # # . ? . . # # . . . . # # ? # +dnl IRIX 6.5 # . # # # # . # . . . # . . . . # . . . +dnl OSF/1 5.1 # . # # # # . . . . . # . . . . # . . # +dnl OSF/1 4.0d # . # # # # . . . . . # . . # # # # # # +dnl NetBSD 4.0 . ? ? ? ? ? . ? . ? ? ? ? ? . . . ? ? ? +dnl NetBSD 3.0 . . . . # # . ? # # ? # . # . . . . . . +dnl Haiku . . . # # # . # . . . . . ? . . . . . . +dnl BeOS # # . # # # . ? # . ? . # ? . . . . . . +dnl mingw # # # # # # . . # # . # # ? . # # # . . diff --git a/m4/rawmemchr.m4 b/m4/rawmemchr.m4 new file mode 100644 index 000000000..2a25a4904 --- /dev/null +++ b/m4/rawmemchr.m4 @@ -0,0 +1,21 @@ +# rawmemchr.m4 serial 1 +dnl Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_RAWMEMCHR], +[ + dnl Persuade glibc to declare rawmemchr(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REPLACE_FUNCS([rawmemchr]) + if test $ac_cv_func_rawmemchr = no; then + HAVE_RAWMEMCHR=0 + gl_PREREQ_RAWMEMCHR + fi +]) + +# Prerequisites of lib/strchrnul.c. +AC_DEFUN([gl_PREREQ_RAWMEMCHR], [:]) diff --git a/m4/realloc.m4 b/m4/realloc.m4 new file mode 100644 index 000000000..01c1234f7 --- /dev/null +++ b/m4/realloc.m4 @@ -0,0 +1,44 @@ +# realloc.m4 serial 11 +dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# gl_FUNC_REALLOC_GNU +# ------------------- +# Test whether 'realloc (0, 0)' is handled like in GNU libc, and replace +# realloc if it is not. +AC_DEFUN([gl_FUNC_REALLOC_GNU], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + dnl _AC_FUNC_REALLOC_IF is defined in Autoconf. + _AC_FUNC_REALLOC_IF( + [AC_DEFINE([HAVE_REALLOC_GNU], [1], + [Define to 1 if your system has a GNU libc compatible 'realloc' + function, and to 0 otherwise.])], + [AC_DEFINE([HAVE_REALLOC_GNU], [0]) + gl_REPLACE_REALLOC + ]) +])# gl_FUNC_REALLOC_GNU + +# gl_FUNC_REALLOC_POSIX +# --------------------- +# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it +# fails), and replace realloc if it is not. +AC_DEFUN([gl_FUNC_REALLOC_POSIX], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) + if test $gl_cv_func_malloc_posix = yes; then + AC_DEFINE([HAVE_REALLOC_POSIX], [1], + [Define if the 'realloc' function is POSIX compliant.]) + else + gl_REPLACE_REALLOC + fi +]) + +AC_DEFUN([gl_REPLACE_REALLOC], +[ + AC_LIBOBJ([realloc]) + REPLACE_REALLOC=1 +]) diff --git a/m4/regex.m4 b/m4/regex.m4 new file mode 100644 index 000000000..38f1dd76b --- /dev/null +++ b/m4/regex.m4 @@ -0,0 +1,235 @@ +# serial 56 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +dnl Initially derived from code in GNU grep. +dnl Mostly written by Jim Meyering. + +AC_PREREQ([2.50]) + +AC_DEFUN([gl_REGEX], +[ + AC_CHECK_HEADERS_ONCE([locale.h]) + + AC_ARG_WITH([included-regex], + [AS_HELP_STRING([--without-included-regex], + [don't compile regex; this is the default on systems + with recent-enough versions of the GNU C Library + (use with caution on other systems).])]) + + case $with_included_regex in #( + yes|no) ac_use_included_regex=$with_included_regex + ;; + '') + # If the system regex support is good enough that it passes the + # following run test, then default to *not* using the included regex.c. + # If cross compiling, assume the test would fail and use the included + # regex.c. + AC_CACHE_CHECK([for working re_compile_pattern], + [gl_cv_func_re_compile_pattern_working], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT[ + #if HAVE_LOCALE_H + #include + #endif + #include + #include + ]], + [[static struct re_pattern_buffer regex; + unsigned char folded_chars[UCHAR_MAX + 1]; + int i; + const char *s; + struct re_registers regs; + + #if HAVE_LOCALE_H + /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html + This test needs valgrind to catch the bug on Debian + GNU/Linux 3.1 x86, but it might catch the bug better + on other platforms and it shouldn't hurt to try the + test here. */ + if (setlocale (LC_ALL, "en_US.UTF-8")) + { + static char const pat[] = "insert into"; + static char const data[] = + "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK"; + re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE + | RE_ICASE); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern (pat, sizeof pat - 1, ®ex); + if (s) + return 1; + if (re_search (®ex, data, sizeof data - 1, + 0, sizeof data - 1, ®s) + != -1) + return 1; + if (! setlocale (LC_ALL, "C")) + return 1; + } + #endif + + /* This test is from glibc bug 3957, reported by Andrew Mackey. */ + re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("a[^x]b", 6, ®ex); + if (s) + return 1; + + /* This should fail, but succeeds for glibc-2.5. */ + if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) + return 1; + + /* This regular expression is from Spencer ere test number 75 + in grep-2.3. */ + re_set_syntax (RE_SYNTAX_POSIX_EGREP); + memset (®ex, 0, sizeof regex); + for (i = 0; i <= UCHAR_MAX; i++) + folded_chars[i] = i; + regex.translate = folded_chars; + s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); + /* This should fail with _Invalid character class name_ error. */ + if (!s) + return 1; + + /* Ensure that [b-a] is diagnosed as invalid, when + using RE_NO_EMPTY_RANGES. */ + re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("a[b-a]", 6, ®ex); + if (s == 0) + return 1; + + /* This should succeed, but does not for glibc-2.1.3. */ + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("{1", 2, ®ex); + + if (s) + return 1; + + /* The following example is derived from a problem report + against gawk from Jorge Stolfi . */ + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("[an\371]*n", 7, ®ex); + if (s) + return 1; + + /* This should match, but does not for glibc-2.2.1. */ + if (re_match (®ex, "an", 2, 0, ®s) != 2) + return 1; + + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("x", 1, ®ex); + if (s) + return 1; + + /* glibc-2.2.93 does not work with a negative RANGE argument. */ + if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) + return 1; + + /* The version of regex.c in older versions of gnulib + ignored RE_ICASE. Detect that problem too. */ + re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("x", 1, ®ex); + if (s) + return 1; + + if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) + return 1; + + /* Catch a bug reported by Vin Shelton in + http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html + */ + re_set_syntax (RE_SYNTAX_POSIX_BASIC + & ~RE_CONTEXT_INVALID_DUP + & ~RE_NO_EMPTY_RANGES); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); + if (s) + return 1; + + /* REG_STARTEND was added to glibc on 2004-01-15. + Reject older versions. */ + if (! REG_STARTEND) + return 1; + +#if 0 + /* It would be nice to reject hosts whose regoff_t values are too + narrow (including glibc on hosts with 64-bit ptrdiff_t and + 32-bit int), but we should wait until glibc implements this + feature. Otherwise, support for equivalence classes and + multibyte collation symbols would always be broken except + when compiling --without-included-regex. */ + if (sizeof (regoff_t) < sizeof (ptrdiff_t) + || sizeof (regoff_t) < sizeof (ssize_t)) + return 1; +#endif + + return 0;]])], + [gl_cv_func_re_compile_pattern_working=yes], + [gl_cv_func_re_compile_pattern_working=no], + dnl When crosscompiling, assume it is not working. + [gl_cv_func_re_compile_pattern_working=no])]) + case $gl_cv_func_re_compile_pattern_working in #( + yes) ac_use_included_regex=no;; #( + no) ac_use_included_regex=yes;; + esac + ;; + *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) + ;; + esac + + if test $ac_use_included_regex = yes; then + AC_DEFINE([_REGEX_LARGE_OFFSETS], [1], + [Define if you want regoff_t to be at least as wide POSIX requires.]) + AC_DEFINE([re_syntax_options], [rpl_re_syntax_options], + [Define to rpl_re_syntax_options if the replacement should be used.]) + AC_DEFINE([re_set_syntax], [rpl_re_set_syntax], + [Define to rpl_re_set_syntax if the replacement should be used.]) + AC_DEFINE([re_compile_pattern], [rpl_re_compile_pattern], + [Define to rpl_re_compile_pattern if the replacement should be used.]) + AC_DEFINE([re_compile_fastmap], [rpl_re_compile_fastmap], + [Define to rpl_re_compile_fastmap if the replacement should be used.]) + AC_DEFINE([re_search], [rpl_re_search], + [Define to rpl_re_search if the replacement should be used.]) + AC_DEFINE([re_search_2], [rpl_re_search_2], + [Define to rpl_re_search_2 if the replacement should be used.]) + AC_DEFINE([re_match], [rpl_re_match], + [Define to rpl_re_match if the replacement should be used.]) + AC_DEFINE([re_match_2], [rpl_re_match_2], + [Define to rpl_re_match_2 if the replacement should be used.]) + AC_DEFINE([re_set_registers], [rpl_re_set_registers], + [Define to rpl_re_set_registers if the replacement should be used.]) + AC_DEFINE([re_comp], [rpl_re_comp], + [Define to rpl_re_comp if the replacement should be used.]) + AC_DEFINE([re_exec], [rpl_re_exec], + [Define to rpl_re_exec if the replacement should be used.]) + AC_DEFINE([regcomp], [rpl_regcomp], + [Define to rpl_regcomp if the replacement should be used.]) + AC_DEFINE([regexec], [rpl_regexec], + [Define to rpl_regexec if the replacement should be used.]) + AC_DEFINE([regerror], [rpl_regerror], + [Define to rpl_regerror if the replacement should be used.]) + AC_DEFINE([regfree], [rpl_regfree], + [Define to rpl_regfree if the replacement should be used.]) + AC_LIBOBJ([regex]) + gl_PREREQ_REGEX + fi +]) + +# Prerequisites of lib/regex.c and lib/regex_internal.c. +AC_DEFUN([gl_PREREQ_REGEX], +[ + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + AC_CHECK_HEADERS([libintl.h]) + AC_CHECK_FUNCS_ONCE([isblank iswctype wcscoll]) + AC_CHECK_DECLS([isblank], [], [], [#include ]) +]) diff --git a/m4/size_max.m4 b/m4/size_max.m4 new file mode 100644 index 000000000..f3b1a9dfb --- /dev/null +++ b/m4/size_max.m4 @@ -0,0 +1,79 @@ +# size_max.m4 serial 10 +dnl Copyright (C) 2003, 2005-2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gl_SIZE_MAX], +[ + AC_CHECK_HEADERS([stdint.h]) + dnl First test whether the system already has SIZE_MAX. + AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [ + gl_cv_size_max= + AC_EGREP_CPP([Found it], [ +#include +#if HAVE_STDINT_H +#include +#endif +#ifdef SIZE_MAX +Found it +#endif +], [gl_cv_size_max=yes]) + if test -z "$gl_cv_size_max"; then + dnl Define it ourselves. Here we assume that the type 'size_t' is not wider + dnl than the type 'unsigned long'. Try hard to find a definition that can + dnl be used in a preprocessor #if, i.e. doesn't contain a cast. + AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1], + [#include +#include ], [size_t_bits_minus_1=]) + AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned int)], + [#include ], [fits_in_uint=]) + if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then + if test $fits_in_uint = 1; then + dnl Even though SIZE_MAX fits in an unsigned int, it must be of type + dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + extern size_t foo; + extern unsigned long foo; + ]], + [[]])], + [fits_in_uint=0]) + fi + dnl We cannot use 'expr' to simplify this expression, because 'expr' + dnl works only with 'long' integers in the host environment, while we + dnl might be cross-compiling from a 32-bit platform to a 64-bit platform. + if test $fits_in_uint = 1; then + gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)" + else + gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)" + fi + else + dnl Shouldn't happen, but who knows... + gl_cv_size_max='((size_t)~(size_t)0)' + fi + fi + ]) + if test "$gl_cv_size_max" != yes; then + AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max], + [Define as the maximum value of type 'size_t', if the system doesn't define it.]) + fi + dnl Don't redefine SIZE_MAX in config.h if config.h is re-included after + dnl . Remember that the #undef in AH_VERBATIM gets replaced with + dnl #define by AC_DEFINE_UNQUOTED. + AH_VERBATIM([SIZE_MAX], +[/* Define as the maximum value of type 'size_t', if the system doesn't define + it. */ +#ifndef SIZE_MAX +# undef SIZE_MAX +#endif]) +]) + +dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +dnl Remove this when we can assume autoconf >= 2.61. +m4_ifdef([AC_COMPUTE_INT], [], [ + AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +]) diff --git a/m4/sleep.m4 b/m4/sleep.m4 new file mode 100644 index 000000000..a5ec65520 --- /dev/null +++ b/m4/sleep.m4 @@ -0,0 +1,49 @@ +# sleep.m4 serial 3 +dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_SLEEP], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + dnl We expect to see the declaration of sleep() in a header file. + dnl Older versions of mingw have a sleep() function that is an alias to + dnl _sleep() in MSVCRT. It has a different signature than POSIX sleep(): + dnl it takes the number of milliseconds as argument and returns void. + dnl mingw does not declare this function. + AC_CHECK_DECLS([sleep], , , [#include ]) + AC_CHECK_FUNCS_ONCE([sleep]) + if test $ac_cv_have_decl_sleep != yes; then + HAVE_SLEEP=0 + AC_LIBOBJ([sleep]) + else + dnl Cygwin 1.5.x has a bug where sleep can't exceed 49.7 days. + AC_CACHE_CHECK([for working sleep], [gl_cv_func_sleep_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +static void +handle_alarm (int sig) +{ + if (sig != SIGALRM) + _exit (2); +} +]], [[ + /* Failure to compile this test due to missing alarm is okay, + since all such platforms (mingw) also lack sleep. */ + unsigned int pentecost = 50 * 24 * 60 * 60; /* 50 days. */ + unsigned int remaining; + signal (SIGALRM, handle_alarm); + alarm (1); + remaining = sleep (pentecost); + return !(pentecost - 10 < remaining && remaining <= pentecost);]])], + [gl_cv_func_sleep_works=yes], [gl_cv_func_sleep_works=no], + [gl_cv_func_sleep_works="guessing no"])]) + if test "$gl_cv_func_sleep_works" != yes; then + REPLACE_SLEEP=1 + AC_LIBOBJ([sleep]) + fi + fi +]) diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4 new file mode 100644 index 000000000..e4c160b50 --- /dev/null +++ b/m4/ssize_t.m4 @@ -0,0 +1,23 @@ +# ssize_t.m4 serial 5 (gettext-0.18.2) +dnl Copyright (C) 2001-2003, 2006, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether ssize_t is defined. + +AC_DEFUN([gt_TYPE_SSIZE_T], +[ + AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[int x = sizeof (ssize_t *) + sizeof (ssize_t); + return !x;]])], + [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])]) + if test $gt_cv_ssize_t = no; then + AC_DEFINE([ssize_t], [int], + [Define as a signed type of the same size as size_t.]) + fi +]) diff --git a/m4/stdbool.m4 b/m4/stdbool.m4 new file mode 100644 index 000000000..1efe59ea1 --- /dev/null +++ b/m4/stdbool.m4 @@ -0,0 +1,103 @@ +# Check for stdbool.h that conforms to C99. + +dnl Copyright (C) 2002-2006, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +#serial 3 + +# Prepare for substituting if it is not supported. + +AC_DEFUN([AM_STDBOOL_H], +[ + AC_REQUIRE([AC_HEADER_STDBOOL]) + + # Define two additional variables used in the Makefile substitution. + + if test "$ac_cv_header_stdbool_h" = yes; then + STDBOOL_H='' + else + STDBOOL_H='stdbool.h' + fi + AC_SUBST([STDBOOL_H]) + + if test "$ac_cv_type__Bool" = yes; then + HAVE__BOOL=1 + else + HAVE__BOOL=0 + fi + AC_SUBST([HAVE__BOOL]) +]) + +# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future. +AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H]) + +# This version of the macro is needed in autoconf <= 2.67. Autoconf has +# it built in since 2.60, but we want the tweaks from the 2.68 version +# to avoid rejecting xlc and clang due to relying on extensions. + +AC_DEFUN([AC_HEADER_STDBOOL], + [AC_CACHE_CHECK([for stdbool.h that conforms to C99], + [ac_cv_header_stdbool_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + #ifndef bool + "error: bool is not defined" + #endif + #ifndef false + "error: false is not defined" + #endif + #if false + "error: false is not 0" + #endif + #ifndef true + "error: true is not defined" + #endif + #if true != 1 + "error: true is not 1" + #endif + #ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" + #endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + ]], + [[ + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + ]])], + [ac_cv_header_stdbool_h=yes], + [ac_cv_header_stdbool_h=no])]) + AC_CHECK_TYPES([_Bool]) + if test $ac_cv_header_stdbool_h = yes; then + AC_DEFINE([HAVE_STDBOOL_H], [1], [Define to 1 if stdbool.h conforms to C99.]) + fi]) diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 new file mode 100644 index 000000000..c3ae56943 --- /dev/null +++ b/m4/stddef_h.m4 @@ -0,0 +1,45 @@ +dnl A placeholder for POSIX 2008 , for platforms that have issues. +# stddef_h.m4 serial 2 +dnl Copyright (C) 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STDDEF_H], +[ + AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + if test $gt_cv_c_wchar_t = no; then + HAVE_WCHAR_T=0 + STDDEF_H=stddef.h + fi + AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], + [gl_cv_decl_null_works], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + int test[2 * (sizeof NULL == sizeof (void *)) -1]; +]])], + [gl_cv_decl_null_works=yes], + [gl_cv_decl_null_works=no])]) + if test $gl_cv_decl_null_works = no; then + REPLACE_NULL=1 + STDDEF_H=stddef.h + fi + if test -n "$STDDEF_H"; then + gl_CHECK_NEXT_HEADERS([stddef.h]) + fi +]) + +AC_DEFUN([gl_STDDEF_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +]) + +AC_DEFUN([gl_STDDEF_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) + HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) + STDDEF_H=''; AC_SUBST([STDDEF_H]) +]) diff --git a/m4/stdint.m4 b/m4/stdint.m4 new file mode 100644 index 000000000..c5e813a96 --- /dev/null +++ b/m4/stdint.m4 @@ -0,0 +1,472 @@ +# stdint.m4 serial 35 +dnl Copyright (C) 2001-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert and Bruno Haible. +dnl Test whether is supported or must be substituted. + +AC_DEFUN([gl_STDINT_H], +[ + AC_PREREQ([2.59])dnl + + dnl Check for long long int and unsigned long long int. + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + if test $ac_cv_type_long_long_int = yes; then + HAVE_LONG_LONG_INT=1 + else + HAVE_LONG_LONG_INT=0 + fi + AC_SUBST([HAVE_LONG_LONG_INT]) + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + HAVE_UNSIGNED_LONG_LONG_INT=1 + else + HAVE_UNSIGNED_LONG_LONG_INT=0 + fi + AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) + + dnl Check for . + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. + if test $ac_cv_header_inttypes_h = yes; then + HAVE_INTTYPES_H=1 + else + HAVE_INTTYPES_H=0 + fi + AC_SUBST([HAVE_INTTYPES_H]) + + dnl Check for . + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h. + if test $ac_cv_header_sys_types_h = yes; then + HAVE_SYS_TYPES_H=1 + else + HAVE_SYS_TYPES_H=0 + fi + AC_SUBST([HAVE_SYS_TYPES_H]) + + gl_CHECK_NEXT_HEADERS([stdint.h]) + if test $ac_cv_header_stdint_h = yes; then + HAVE_STDINT_H=1 + else + HAVE_STDINT_H=0 + fi + AC_SUBST([HAVE_STDINT_H]) + + dnl Now see whether we need a substitute . + if test $ac_cv_header_stdint_h = yes; then + AC_CACHE_CHECK([whether stdint.h conforms to C99], + [gl_cv_header_working_stdint_h], + [gl_cv_header_working_stdint_h=no + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#include +/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ +#if !(defined WCHAR_MIN && defined WCHAR_MAX) +#error "WCHAR_MIN, WCHAR_MAX not defined in " +#endif +] +gl_STDINT_INCLUDES +[ +#ifdef INT8_MAX +int8_t a1 = INT8_MAX; +int8_t a1min = INT8_MIN; +#endif +#ifdef INT16_MAX +int16_t a2 = INT16_MAX; +int16_t a2min = INT16_MIN; +#endif +#ifdef INT32_MAX +int32_t a3 = INT32_MAX; +int32_t a3min = INT32_MIN; +#endif +#ifdef INT64_MAX +int64_t a4 = INT64_MAX; +int64_t a4min = INT64_MIN; +#endif +#ifdef UINT8_MAX +uint8_t b1 = UINT8_MAX; +#else +typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; +#endif +#ifdef UINT16_MAX +uint16_t b2 = UINT16_MAX; +#endif +#ifdef UINT32_MAX +uint32_t b3 = UINT32_MAX; +#endif +#ifdef UINT64_MAX +uint64_t b4 = UINT64_MAX; +#endif +int_least8_t c1 = INT8_C (0x7f); +int_least8_t c1max = INT_LEAST8_MAX; +int_least8_t c1min = INT_LEAST8_MIN; +int_least16_t c2 = INT16_C (0x7fff); +int_least16_t c2max = INT_LEAST16_MAX; +int_least16_t c2min = INT_LEAST16_MIN; +int_least32_t c3 = INT32_C (0x7fffffff); +int_least32_t c3max = INT_LEAST32_MAX; +int_least32_t c3min = INT_LEAST32_MIN; +int_least64_t c4 = INT64_C (0x7fffffffffffffff); +int_least64_t c4max = INT_LEAST64_MAX; +int_least64_t c4min = INT_LEAST64_MIN; +uint_least8_t d1 = UINT8_C (0xff); +uint_least8_t d1max = UINT_LEAST8_MAX; +uint_least16_t d2 = UINT16_C (0xffff); +uint_least16_t d2max = UINT_LEAST16_MAX; +uint_least32_t d3 = UINT32_C (0xffffffff); +uint_least32_t d3max = UINT_LEAST32_MAX; +uint_least64_t d4 = UINT64_C (0xffffffffffffffff); +uint_least64_t d4max = UINT_LEAST64_MAX; +int_fast8_t e1 = INT_FAST8_MAX; +int_fast8_t e1min = INT_FAST8_MIN; +int_fast16_t e2 = INT_FAST16_MAX; +int_fast16_t e2min = INT_FAST16_MIN; +int_fast32_t e3 = INT_FAST32_MAX; +int_fast32_t e3min = INT_FAST32_MIN; +int_fast64_t e4 = INT_FAST64_MAX; +int_fast64_t e4min = INT_FAST64_MIN; +uint_fast8_t f1 = UINT_FAST8_MAX; +uint_fast16_t f2 = UINT_FAST16_MAX; +uint_fast32_t f3 = UINT_FAST32_MAX; +uint_fast64_t f4 = UINT_FAST64_MAX; +#ifdef INTPTR_MAX +intptr_t g = INTPTR_MAX; +intptr_t gmin = INTPTR_MIN; +#endif +#ifdef UINTPTR_MAX +uintptr_t h = UINTPTR_MAX; +#endif +intmax_t i = INTMAX_MAX; +uintmax_t j = UINTMAX_MAX; + +#include /* for CHAR_BIT */ +#define TYPE_MINIMUM(t) \ + ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) +#define TYPE_MAXIMUM(t) \ + ((t) ((t) 0 < (t) -1 ? (t) -1 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) +struct s { + int check_PTRDIFF: + PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) + && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) + ? 1 : -1; + /* Detect bug in FreeBSD 6.0 / ia64. */ + int check_SIG_ATOMIC: + SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) + && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) + ? 1 : -1; + int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1; + int check_WCHAR: + WCHAR_MIN == TYPE_MINIMUM (wchar_t) + && WCHAR_MAX == TYPE_MAXIMUM (wchar_t) + ? 1 : -1; + /* Detect bug in mingw. */ + int check_WINT: + WINT_MIN == TYPE_MINIMUM (wint_t) + && WINT_MAX == TYPE_MAXIMUM (wint_t) + ? 1 : -1; + + /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ + int check_UINT8_C: + (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; + int check_UINT16_C: + (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; + + /* Detect bugs in OpenBSD 3.9 stdint.h. */ +#ifdef UINT8_MAX + int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; +#endif +#ifdef UINT16_MAX + int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; +#endif +#ifdef UINT32_MAX + int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; +#endif +#ifdef UINT64_MAX + int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; +#endif + int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; + int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; + int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; + int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; + int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; + int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; + int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; + int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; + int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; + int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; + int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; +}; + ]])], + [dnl Determine whether the various *_MIN, *_MAX macros are usable + dnl in preprocessor expression. We could do it by compiling a test + dnl program for each of these macros. It is faster to run a program + dnl that inspects the macro expansion. + dnl This detects a bug on HP-UX 11.23/ia64. + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ +#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +#include +] +gl_STDINT_INCLUDES +[ +#include +#include +#define MVAL(macro) MVAL1(macro) +#define MVAL1(expression) #expression +static const char *macro_values[] = + { +#ifdef INT8_MAX + MVAL (INT8_MAX), +#endif +#ifdef INT16_MAX + MVAL (INT16_MAX), +#endif +#ifdef INT32_MAX + MVAL (INT32_MAX), +#endif +#ifdef INT64_MAX + MVAL (INT64_MAX), +#endif +#ifdef UINT8_MAX + MVAL (UINT8_MAX), +#endif +#ifdef UINT16_MAX + MVAL (UINT16_MAX), +#endif +#ifdef UINT32_MAX + MVAL (UINT32_MAX), +#endif +#ifdef UINT64_MAX + MVAL (UINT64_MAX), +#endif + NULL + }; +]], [[ + const char **mv; + for (mv = macro_values; *mv != NULL; mv++) + { + const char *value = *mv; + /* Test whether it looks like a cast expression. */ + if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0 + || strncmp (value, "((unsigned short)"/*)*/, 17) == 0 + || strncmp (value, "((unsigned char)"/*)*/, 16) == 0 + || strncmp (value, "((int)"/*)*/, 6) == 0 + || strncmp (value, "((signed short)"/*)*/, 15) == 0 + || strncmp (value, "((signed char)"/*)*/, 14) == 0) + return 1; + } + return 0; +]])], + [gl_cv_header_working_stdint_h=yes], + [], + [dnl When cross-compiling, assume it works. + gl_cv_header_working_stdint_h=yes + ]) + ]) + ]) + fi + if test "$gl_cv_header_working_stdint_h" = yes; then + STDINT_H= + else + dnl Check for , and for + dnl (used in Linux libc4 >= 4.6.7 and libc5). + AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) + if test $ac_cv_header_sys_inttypes_h = yes; then + HAVE_SYS_INTTYPES_H=1 + else + HAVE_SYS_INTTYPES_H=0 + fi + AC_SUBST([HAVE_SYS_INTTYPES_H]) + if test $ac_cv_header_sys_bitypes_h = yes; then + HAVE_SYS_BITYPES_H=1 + else + HAVE_SYS_BITYPES_H=0 + fi + AC_SUBST([HAVE_SYS_BITYPES_H]) + + dnl Check for (missing in Linux uClibc when built without wide + dnl character support). + AC_CHECK_HEADERS_ONCE([wchar.h]) + + gl_STDINT_TYPE_PROPERTIES + STDINT_H=stdint.h + fi + AC_SUBST([STDINT_H]) +]) + +dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) +dnl Determine the size of each of the given types in bits. +AC_DEFUN([gl_STDINT_BITSIZEOF], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + m4_foreach_w([gltype], [$1], + [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), + [Define to the number of bits in type ']gltype['.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}], + [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT], + [$2 +#include ], [result=unknown]) + eval gl_cv_bitsizeof_${gltype}=\$result + ]) + eval result=\$gl_cv_bitsizeof_${gltype} + if test $result = unknown; then + dnl Use a nonempty default, because some compilers, such as IRIX 5 cc, + dnl do a syntax check even on unused #if conditions and give an error + dnl on valid C code like this: + dnl #if 0 + dnl # if > 32 + dnl # endif + dnl #endif + result=0 + fi + GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result]) + eval BITSIZEOF_${GLTYPE}=\$result + done + m4_foreach_w([gltype], [$1], + [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +]) + +dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES) +dnl Determine the signedness of each of the given types. +dnl Define HAVE_SIGNED_TYPE if type is signed. +AC_DEFUN([gl_CHECK_TYPES_SIGNED], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + m4_foreach_w([gltype], [$1], + [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), + [Define to 1 if ']gltype[' is a signed integer type.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2[ + int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])], + result=yes, result=no) + eval gl_cv_type_${gltype}_signed=\$result + ]) + eval result=\$gl_cv_type_${gltype}_signed + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + if test "$result" = yes; then + AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1]) + eval HAVE_SIGNED_${GLTYPE}=1 + else + eval HAVE_SIGNED_${GLTYPE}=0 + fi + done + m4_foreach_w([gltype], [$1], + [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +]) + +dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES) +dnl Determine the suffix to use for integer constants of the given types. +dnl Define t_SUFFIX for each such type. +AC_DEFUN([gl_INTEGER_TYPE_SUFFIX], +[ + dnl Use a shell loop, to avoid bloating configure, and + dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into + dnl config.h.in, + dnl - extra AC_SUBST calls, so that the right substitutions are made. + m4_foreach_w([gltype], [$1], + [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX], + [Define to l, ll, u, ul, ull, etc., as suitable for + constants of type ']gltype['.])]) + for gltype in $1 ; do + AC_CACHE_CHECK([for $gltype integer literal suffix], + [gl_cv_type_${gltype}_suffix], + [eval gl_cv_type_${gltype}_suffix=no + eval result=\$gl_cv_type_${gltype}_signed + if test "$result" = yes; then + glsufu= + else + glsufu=u + fi + for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do + case $glsuf in + '') gltype1='int';; + l) gltype1='long int';; + ll) gltype1='long long int';; + i64) gltype1='__int64';; + u) gltype1='unsigned int';; + ul) gltype1='unsigned long int';; + ull) gltype1='unsigned long long int';; + ui64)gltype1='unsigned __int64';; + esac + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([$2[ + extern $gltype foo; + extern $gltype1 foo;]])], + [eval gl_cv_type_${gltype}_suffix=\$glsuf]) + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" != no && break + done]) + GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` + eval result=\$gl_cv_type_${gltype}_suffix + test "$result" = no && result= + eval ${GLTYPE}_SUFFIX=\$result + AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result]) + done + m4_foreach_w([gltype], [$1], + [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])]) +]) + +dnl gl_STDINT_INCLUDES +AC_DEFUN([gl_STDINT_INCLUDES], +[[ + /* BSD/OS 4.0.1 has a bug: , and must be + included before . */ + #include + #include + #if HAVE_WCHAR_H + # include + # include + # include + #endif +]]) + +dnl gl_STDINT_TYPE_PROPERTIES +dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t +dnl of interest to stdint.in.h. +AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], +[ + AC_REQUIRE([gl_MULTIARCH]) + if test $APPLE_UNIVERSAL_BUILD = 0; then + gl_STDINT_BITSIZEOF([ptrdiff_t size_t], + [gl_STDINT_INCLUDES]) + fi + gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) + gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) + gl_cv_type_ptrdiff_t_signed=yes + gl_cv_type_size_t_signed=no + if test $APPLE_UNIVERSAL_BUILD = 0; then + gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t], + [gl_STDINT_INCLUDES]) + fi + gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) +]) + +dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +dnl Remove this when we can assume autoconf >= 2.61. +m4_ifdef([AC_COMPUTE_INT], [], [ + AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +]) + +# Hey Emacs! +# Local Variables: +# indent-tabs-mode: nil +# End: diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4 new file mode 100644 index 000000000..670c0cc2b --- /dev/null +++ b/m4/stdint_h.m4 @@ -0,0 +1,27 @@ +# stdint_h.m4 serial 9 +dnl Copyright (C) 1997-2004, 2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([gl_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], [gl_cv_header_stdint_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include ]], + [[uintmax_t i = (uintmax_t) -1; return !i;]])], + [gl_cv_header_stdint_h=yes], + [gl_cv_header_stdint_h=no])]) + if test $gl_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED([HAVE_STDINT_H_WITH_UINTMAX], [1], + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 new file mode 100644 index 000000000..f5650cdea --- /dev/null +++ b/m4/stdio_h.m4 @@ -0,0 +1,159 @@ +# stdio_h.m4 serial 31 +dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STDIO_H], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([gl_ASM_SYMBOL_PREFIX]) + gl_CHECK_NEXT_HEADERS([stdio.h]) + dnl No need to create extra modules for these functions. Everyone who uses + dnl likely needs them. + GNULIB_FPRINTF=1 + GNULIB_PRINTF=1 + GNULIB_VFPRINTF=1 + GNULIB_VPRINTF=1 + GNULIB_FPUTC=1 + GNULIB_PUTC=1 + GNULIB_PUTCHAR=1 + GNULIB_FPUTS=1 + GNULIB_PUTS=1 + GNULIB_FWRITE=1 + dnl This ifdef is just an optimization, to avoid performing a configure + dnl check whose result is not used. It does not make the test of + dnl GNULIB_STDIO_H_SIGPIPE or GNULIB_SIGPIPE redundant. + m4_ifdef([gl_SIGNAL_SIGPIPE], [ + gl_SIGNAL_SIGPIPE + if test $gl_cv_header_signal_h_SIGPIPE != yes; then + REPLACE_STDIO_WRITE_FUNCS=1 + AC_LIBOBJ([stdio-write]) + fi + ]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not + dnl guaranteed by C89. + gl_WARN_ON_USE_PREPARE([[#include + ]], [dprintf fpurge fseeko ftello getdelim getline popen renameat + snprintf tmpfile vdprintf vsnprintf]) +]) + +AC_DEFUN([gl_STDIO_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_STDIO_H_DEFAULTS], +[ + GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) + GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE]) + GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH]) + GNULIB_FOPEN=0; AC_SUBST([GNULIB_FOPEN]) + GNULIB_FPRINTF=0; AC_SUBST([GNULIB_FPRINTF]) + GNULIB_FPRINTF_POSIX=0; AC_SUBST([GNULIB_FPRINTF_POSIX]) + GNULIB_FPURGE=0; AC_SUBST([GNULIB_FPURGE]) + GNULIB_FPUTC=0; AC_SUBST([GNULIB_FPUTC]) + GNULIB_FPUTS=0; AC_SUBST([GNULIB_FPUTS]) + GNULIB_FREOPEN=0; AC_SUBST([GNULIB_FREOPEN]) + GNULIB_FSEEK=0; AC_SUBST([GNULIB_FSEEK]) + GNULIB_FSEEKO=0; AC_SUBST([GNULIB_FSEEKO]) + GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL]) + GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO]) + GNULIB_FWRITE=0; AC_SUBST([GNULIB_FWRITE]) + GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM]) + GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE]) + GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) + GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) + GNULIB_PERROR=0; AC_SUBST([GNULIB_PERROR]) + GNULIB_POPEN=0; AC_SUBST([GNULIB_POPEN]) + GNULIB_PRINTF=0; AC_SUBST([GNULIB_PRINTF]) + GNULIB_PRINTF_POSIX=0; AC_SUBST([GNULIB_PRINTF_POSIX]) + GNULIB_PUTC=0; AC_SUBST([GNULIB_PUTC]) + GNULIB_PUTCHAR=0; AC_SUBST([GNULIB_PUTCHAR]) + GNULIB_PUTS=0; AC_SUBST([GNULIB_PUTS]) + GNULIB_REMOVE=0; AC_SUBST([GNULIB_REMOVE]) + GNULIB_RENAME=0; AC_SUBST([GNULIB_RENAME]) + GNULIB_RENAMEAT=0; AC_SUBST([GNULIB_RENAMEAT]) + GNULIB_SNPRINTF=0; AC_SUBST([GNULIB_SNPRINTF]) + GNULIB_SPRINTF_POSIX=0; AC_SUBST([GNULIB_SPRINTF_POSIX]) + GNULIB_STDIO_H_SIGPIPE=0; AC_SUBST([GNULIB_STDIO_H_SIGPIPE]) + GNULIB_TMPFILE=0; AC_SUBST([GNULIB_TMPFILE]) + GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) + GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) + GNULIB_VFPRINTF=0; AC_SUBST([GNULIB_VFPRINTF]) + GNULIB_VFPRINTF_POSIX=0; AC_SUBST([GNULIB_VFPRINTF_POSIX]) + GNULIB_VPRINTF=0; AC_SUBST([GNULIB_VPRINTF]) + GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) + GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) + GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) + HAVE_DECL_GETDELIM=1; AC_SUBST([HAVE_DECL_GETDELIM]) + HAVE_DECL_GETLINE=1; AC_SUBST([HAVE_DECL_GETLINE]) + HAVE_DECL_OBSTACK_PRINTF=1; AC_SUBST([HAVE_DECL_OBSTACK_PRINTF]) + HAVE_DECL_SNPRINTF=1; AC_SUBST([HAVE_DECL_SNPRINTF]) + HAVE_DECL_VSNPRINTF=1; AC_SUBST([HAVE_DECL_VSNPRINTF]) + HAVE_DPRINTF=1; AC_SUBST([HAVE_DPRINTF]) + HAVE_FSEEKO=1; AC_SUBST([HAVE_FSEEKO]) + HAVE_FTELLO=1; AC_SUBST([HAVE_FTELLO]) + HAVE_RENAMEAT=1; AC_SUBST([HAVE_RENAMEAT]) + HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) + HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) + REPLACE_DPRINTF=0; AC_SUBST([REPLACE_DPRINTF]) + REPLACE_FCLOSE=0; AC_SUBST([REPLACE_FCLOSE]) + REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) + REPLACE_FOPEN=0; AC_SUBST([REPLACE_FOPEN]) + REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF]) + REPLACE_FPURGE=0; AC_SUBST([REPLACE_FPURGE]) + REPLACE_FREOPEN=0; AC_SUBST([REPLACE_FREOPEN]) + REPLACE_FSEEK=0; AC_SUBST([REPLACE_FSEEK]) + REPLACE_FSEEKO=0; AC_SUBST([REPLACE_FSEEKO]) + REPLACE_FTELL=0; AC_SUBST([REPLACE_FTELL]) + REPLACE_FTELLO=0; AC_SUBST([REPLACE_FTELLO]) + REPLACE_GETDELIM=0; AC_SUBST([REPLACE_GETDELIM]) + REPLACE_GETLINE=0; AC_SUBST([REPLACE_GETLINE]) + REPLACE_OBSTACK_PRINTF=0; AC_SUBST([REPLACE_OBSTACK_PRINTF]) + REPLACE_PERROR=0; AC_SUBST([REPLACE_PERROR]) + REPLACE_POPEN=0; AC_SUBST([REPLACE_POPEN]) + REPLACE_PRINTF=0; AC_SUBST([REPLACE_PRINTF]) + REPLACE_REMOVE=0; AC_SUBST([REPLACE_REMOVE]) + REPLACE_RENAME=0; AC_SUBST([REPLACE_RENAME]) + REPLACE_RENAMEAT=0; AC_SUBST([REPLACE_RENAMEAT]) + REPLACE_SNPRINTF=0; AC_SUBST([REPLACE_SNPRINTF]) + REPLACE_SPRINTF=0; AC_SUBST([REPLACE_SPRINTF]) + REPLACE_STDIO_WRITE_FUNCS=0; AC_SUBST([REPLACE_STDIO_WRITE_FUNCS]) + REPLACE_TMPFILE=0; AC_SUBST([REPLACE_TMPFILE]) + REPLACE_VASPRINTF=0; AC_SUBST([REPLACE_VASPRINTF]) + REPLACE_VDPRINTF=0; AC_SUBST([REPLACE_VDPRINTF]) + REPLACE_VFPRINTF=0; AC_SUBST([REPLACE_VFPRINTF]) + REPLACE_VPRINTF=0; AC_SUBST([REPLACE_VPRINTF]) + REPLACE_VSNPRINTF=0; AC_SUBST([REPLACE_VSNPRINTF]) + REPLACE_VSPRINTF=0; AC_SUBST([REPLACE_VSPRINTF]) +]) + +dnl Code shared by fseeko and ftello. Determine if large files are supported, +dnl but stdin does not start as a large file by default. +AC_DEFUN([gl_STDIN_LARGE_OFFSET], + [ + AC_CACHE_CHECK([whether stdin defaults to large file offsets], + [gl_cv_var_stdin_large_offset], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], +[[#if defined __SL64 && defined __SCLE /* cygwin */ + /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making + fseeko/ftello needlessly fail. This bug was fixed in 1.5.25, and + it is easier to do a version check than building a runtime test. */ +# include +# if CYGWIN_VERSION_DLL_COMBINED < CYGWIN_VERSION_DLL_MAKE_COMBINED (1005, 25) + choke me +# endif +#endif]])], + [gl_cv_var_stdin_large_offset=yes], + [gl_cv_var_stdin_large_offset=no])]) +]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 new file mode 100644 index 000000000..fc150197b --- /dev/null +++ b/m4/stdlib_h.m4 @@ -0,0 +1,112 @@ +# stdlib_h.m4 serial 30 +dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STDLIB_H], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([stdlib.h]) + AC_CHECK_HEADERS([random.h], [], [], [AC_INCLUDES_DEFAULT]) + if test $ac_cv_header_random_h = yes; then + HAVE_RANDOM_H=1 + else + HAVE_RANDOM_H=0 + fi + AC_SUBST([HAVE_RANDOM_H]) + AC_CHECK_TYPES([struct random_data], + [], [HAVE_STRUCT_RANDOM_DATA=0], + [[#include + #if HAVE_RANDOM_H + # include + #endif + ]]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not + dnl guaranteed by C89. + gl_WARN_ON_USE_PREPARE([[#include +#if HAVE_SYS_LOADAVG_H +# include +#endif +#if HAVE_RANDOM_H +# include +#endif + ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt mkdtemp + mkostemp mkostemps mkstemp mkstemps ptsname random_r initstat_r srandom_r + setstate_r realpath rpmatch setenv strtod strtoll strtoull unlockpt + unsetenv]) +]) + +AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_STDLIB_H_DEFAULTS], +[ + GNULIB__EXIT=0; AC_SUBST([GNULIB__EXIT]) + GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL]) + GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX]) + GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME]) + GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG]) + GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) + GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT]) + GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX]) + GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) + GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP]) + GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS]) + GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP]) + GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS]) + GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME]) + GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) + GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) + GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) + GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH]) + GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH]) + GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV]) + GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD]) + GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL]) + GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL]) + GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) + GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) + HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL]) + HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME]) + HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) + HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) + HAVE_GRANTPT=1; AC_SUBST([HAVE_GRANTPT]) + HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP]) + HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP]) + HAVE_MKOSTEMPS=1; AC_SUBST([HAVE_MKOSTEMPS]) + HAVE_MKSTEMP=1; AC_SUBST([HAVE_MKSTEMP]) + HAVE_MKSTEMPS=1; AC_SUBST([HAVE_MKSTEMPS]) + HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME]) + HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) + HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH]) + HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) + HAVE_SETENV=1; AC_SUBST([HAVE_SETENV]) + HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD]) + HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL]) + HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL]) + HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) + HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) + HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) + HAVE_UNSETENV=1; AC_SUBST([HAVE_UNSETENV]) + REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC]) + REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME]) + REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC]) + REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP]) + REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) + REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC]) + REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) + REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV]) + REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD]) + REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) +]) diff --git a/m4/strcase.m4 b/m4/strcase.m4 new file mode 100644 index 000000000..33de423a0 --- /dev/null +++ b/m4/strcase.m4 @@ -0,0 +1,44 @@ +# strcase.m4 serial 10 +dnl Copyright (C) 2002, 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STRCASE], +[ + gl_FUNC_STRCASECMP + gl_FUNC_STRNCASECMP +]) + +AC_DEFUN([gl_FUNC_STRCASECMP], +[ + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + AC_REPLACE_FUNCS([strcasecmp]) + if test $ac_cv_func_strcasecmp = no; then + HAVE_STRCASECMP=0 + gl_PREREQ_STRCASECMP + fi +]) + +AC_DEFUN([gl_FUNC_STRNCASECMP], +[ + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + AC_REPLACE_FUNCS([strncasecmp]) + if test $ac_cv_func_strncasecmp = no; then + gl_PREREQ_STRNCASECMP + fi + AC_CHECK_DECLS([strncasecmp]) + if test $ac_cv_have_decl_strncasecmp = no; then + HAVE_DECL_STRNCASECMP=0 + fi +]) + +# Prerequisites of lib/strcasecmp.c. +AC_DEFUN([gl_PREREQ_STRCASECMP], [ + : +]) + +# Prerequisites of lib/strncasecmp.c. +AC_DEFUN([gl_PREREQ_STRNCASECMP], [ + : +]) diff --git a/m4/strchrnul.m4 b/m4/strchrnul.m4 new file mode 100644 index 000000000..0072e60e7 --- /dev/null +++ b/m4/strchrnul.m4 @@ -0,0 +1,21 @@ +# strchrnul.m4 serial 7 +dnl Copyright (C) 2003, 2007, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRCHRNUL], +[ + dnl Persuade glibc to declare strchrnul(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REPLACE_FUNCS([strchrnul]) + if test $ac_cv_func_strchrnul = no; then + HAVE_STRCHRNUL=0 + gl_PREREQ_STRCHRNUL + fi +]) + +# Prerequisites of lib/strchrnul.c. +AC_DEFUN([gl_PREREQ_STRCHRNUL], [:]) diff --git a/m4/strerror.m4 b/m4/strerror.m4 new file mode 100644 index 000000000..1649b2451 --- /dev/null +++ b/m4/strerror.m4 @@ -0,0 +1,68 @@ +# strerror.m4 serial 9 +dnl Copyright (C) 2002, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRERROR], +[ + AC_REQUIRE([gl_FUNC_STRERROR_SEPARATE]) + if test $REPLACE_STRERROR = 1; then + AC_LIBOBJ([strerror]) + AC_DEFINE_UNQUOTED([REPLACE_STRERROR], [$REPLACE_STRERROR], + [Define this to 1 if strerror is broken.]) + fi +]) + +# Like gl_FUNC_STRERROR, except prepare for separate compilation (no AC_LIBOBJ). +AC_DEFUN([gl_FUNC_STRERROR_SEPARATE], +[ + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REQUIRE([gl_HEADER_ERRNO_H]) + if test -z "$ERRNO_H"; then + AC_CACHE_CHECK([for working strerror function], + [gl_cv_func_working_strerror], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[return !*strerror (-2);]])], + [gl_cv_func_working_strerror=yes], + [gl_cv_func_working_strerror=no], + [dnl Assume crossbuild works if it compiles. + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[return !*strerror (-2);]])], + [gl_cv_func_working_strerror=yes], + [gl_cv_func_working_strerror=no]) + ]) + ]) + if test $gl_cv_func_working_strerror = no; then + dnl The system's strerror() fails to return a string for out-of-range + dnl integers. Replace it. + REPLACE_STRERROR=1 + fi + else + dnl The system's strerror() cannot know about the new errno values we add + dnl to . Replace it. + REPLACE_STRERROR=1 + fi + if test $REPLACE_STRERROR = 1; then + gl_PREREQ_STRERROR + fi +]) + +# Prerequisites of lib/strerror.c. +AC_DEFUN([gl_PREREQ_STRERROR], [ + AC_CHECK_DECLS([strerror]) + AC_CHECK_HEADERS_ONCE([sys/socket.h]) + if test $ac_cv_header_sys_socket_h != yes; then + dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make + dnl the check for those headers unconditional; yet cygwin reports + dnl that the headers are present but cannot be compiled (since on + dnl cygwin, all socket information should come from sys/socket.h). + AC_CHECK_HEADERS([winsock2.h]) + fi +]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 new file mode 100644 index 000000000..1977aecf9 --- /dev/null +++ b/m4/string_h.m4 @@ -0,0 +1,112 @@ +# Configure a GNU-like replacement for . + +# Copyright (C) 2007-2010 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 17 + +# Written by Paul Eggert. + +AC_DEFUN([gl_HEADER_STRING_H], +[ + dnl Use AC_REQUIRE here, so that the default behavior below is expanded + dnl once only, before all statements that occur in other macros. + AC_REQUIRE([gl_HEADER_STRING_H_BODY]) +]) + +AC_DEFUN([gl_HEADER_STRING_H_BODY], +[ + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([string.h]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not + dnl guaranteed by C89. + gl_WARN_ON_USE_PREPARE([[#include + ]], + [memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul strdup + strncat strndup strnlen strpbrk strsep strcasestr strtok_r strsignal + strverscmp]) +]) + +AC_DEFUN([gl_STRING_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], +[ + GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) + GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) + GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) + GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) + GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR]) + GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY]) + GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY]) + GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL]) + GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP]) + GNULIB_STRNCAT=0; AC_SUBST([GNULIB_STRNCAT]) + GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP]) + GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN]) + GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK]) + GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP]) + GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR]) + GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR]) + GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R]) + GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN]) + GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN]) + GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR]) + GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR]) + GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR]) + GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP]) + GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP]) + GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP]) + GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR]) + GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN]) + GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK]) + GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN]) + GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) + GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R]) + GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) + GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) + GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) + HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR]) + HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) + HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) + HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR]) + HAVE_RAWMEMCHR=1; AC_SUBST([HAVE_RAWMEMCHR]) + HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY]) + HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY]) + HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL]) + HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP]) + HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP]) + HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN]) + HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK]) + HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP]) + HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) + HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) + HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) + HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) + REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) + REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) + REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY]) + REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) + REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) + REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) + REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) + REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) + REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) + REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) + REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) + REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) + UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R]) +]) diff --git a/m4/strings_h.m4 b/m4/strings_h.m4 new file mode 100644 index 000000000..4374c7cbe --- /dev/null +++ b/m4/strings_h.m4 @@ -0,0 +1,39 @@ +# Configure a replacement for . +# serial 3 + +# Copyright (C) 2007, 2009-2010 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_HEADER_STRINGS_H], +[ + dnl Use AC_REQUIRE here, so that the default behavior below is expanded + dnl once only, before all statements that occur in other macros. + AC_REQUIRE([gl_HEADER_STRINGS_H_BODY]) +]) + +AC_DEFUN([gl_HEADER_STRINGS_H_BODY], +[ + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + gl_CHECK_NEXT_HEADERS([strings.h]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[#include + ]], [strcasecmp strncasecmp]) +]) + +AC_DEFUN([gl_STRINGS_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +]) + +AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) + HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) +]) diff --git a/m4/strndup.m4 b/m4/strndup.m4 new file mode 100644 index 000000000..b3567d898 --- /dev/null +++ b/m4/strndup.m4 @@ -0,0 +1,53 @@ +# strndup.m4 serial 18 +dnl Copyright (C) 2002-2003, 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRNDUP], +[ + dnl Persuade glibc to declare strndup(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_CHECK_DECLS_ONCE([strndup]) + AC_CHECK_FUNCS_ONCE([strndup]) + if test $ac_cv_have_decl_strndup = no; then + HAVE_DECL_STRNDUP=0 + fi + + if test $ac_cv_func_strndup = yes; then + # AIX 4.3.3, AIX 5.1 have a function that fails to add the terminating '\0'. + AC_CACHE_CHECK([for working strndup], [gl_cv_func_strndup_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[#include + #include ]], [[ +#ifndef HAVE_DECL_STRNDUP + extern char *strndup (const char *, size_t); +#endif + char *s; + s = strndup ("some longer string", 15); + free (s); + s = strndup ("shorter string", 13); + return s[13] != '\0';]])], + [gl_cv_func_strndup_works=yes], + [gl_cv_func_strndup_works=no], + [ +changequote(,)dnl + case $host_os in + aix | aix[3-6]*) gl_cv_func_strndup_works="guessing no";; + *) gl_cv_func_strndup_works="guessing yes";; + esac +changequote([,])dnl + ])]) + case $gl_cv_func_strndup_works in + *no) + REPLACE_STRNDUP=1 + AC_LIBOBJ([strndup]) + ;; + esac + else + AC_LIBOBJ([strndup]) + fi +]) diff --git a/m4/strnlen.m4 b/m4/strnlen.m4 new file mode 100644 index 000000000..52bb838f9 --- /dev/null +++ b/m4/strnlen.m4 @@ -0,0 +1,32 @@ +# strnlen.m4 serial 12 +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRNLEN], +[ + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + + dnl Persuade glibc to declare strnlen(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([strnlen]) + if test $ac_cv_have_decl_strnlen = no; then + HAVE_DECL_STRNLEN=0 + else + AC_FUNC_STRNLEN + dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). + if test $ac_cv_func_strnlen_working = no; then + REPLACE_STRNLEN=1 + fi + fi + if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then + AC_LIBOBJ([strnlen]) + gl_PREREQ_STRNLEN + fi +]) + +# Prerequisites of lib/strnlen.c. +AC_DEFUN([gl_PREREQ_STRNLEN], [:]) diff --git a/m4/sys_wait_h.m4 b/m4/sys_wait_h.m4 new file mode 100644 index 000000000..b0d23fac7 --- /dev/null +++ b/m4/sys_wait_h.m4 @@ -0,0 +1,25 @@ +# sys_wait_h.m4 serial 4 +dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_SYS_WAIT_H], +[ + AC_REQUIRE([gl_SYS_WAIT_H_DEFAULTS]) + + dnl is always overridden, because of GNULIB_POSIXCHECK. + gl_CHECK_NEXT_HEADERS([sys/wait.h]) +]) + +AC_DEFUN([gl_SYS_WAIT_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_SYS_WAIT_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +]) + +AC_DEFUN([gl_SYS_WAIT_H_DEFAULTS], +[ + dnl Assume proper GNU behavior unless another module says otherwise. +]) diff --git a/m4/sysexits.m4 b/m4/sysexits.m4 new file mode 100644 index 000000000..b3baa51ca --- /dev/null +++ b/m4/sysexits.m4 @@ -0,0 +1,43 @@ +# sysexits.m4 serial 5 +dnl Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_SYSEXITS], +[ + AC_CHECK_HEADERS_ONCE([sysexits.h]) + if test $ac_cv_header_sysexits_h = yes; then + HAVE_SYSEXITS_H=1 + gl_CHECK_NEXT_HEADERS([sysexits.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[switch (0) + { + case EX_OK: + case EX_USAGE: + case EX_DATAERR: + case EX_NOINPUT: + case EX_NOUSER: + case EX_NOHOST: + case EX_UNAVAILABLE: + case EX_SOFTWARE: + case EX_OSERR: + case EX_OSFILE: + case EX_CANTCREAT: + case EX_IOERR: + case EX_TEMPFAIL: + case EX_PROTOCOL: + case EX_NOPERM: + case EX_CONFIG: + break; + } + ]])], + [SYSEXITS_H=], + [SYSEXITS_H=sysexits.h]) + else + HAVE_SYSEXITS_H=0 + SYSEXITS_H=sysexits.h + fi + AC_SUBST([HAVE_SYSEXITS_H]) + AC_SUBST([SYSEXITS_H]) +]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 new file mode 100644 index 000000000..48d06c742 --- /dev/null +++ b/m4/unistd_h.m4 @@ -0,0 +1,159 @@ +# unistd_h.m4 serial 46 +dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Simon Josefsson, Bruno Haible. + +AC_DEFUN([gl_UNISTD_H], +[ + dnl Use AC_REQUIRE here, so that the default behavior below is expanded + dnl once only, before all statements that occur in other macros. + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_C_INLINE]) + + gl_CHECK_NEXT_HEADERS([unistd.h]) + + AC_CHECK_HEADERS_ONCE([unistd.h]) + if test $ac_cv_header_unistd_h = yes; then + HAVE_UNISTD_H=1 + else + HAVE_UNISTD_H=0 + fi + AC_SUBST([HAVE_UNISTD_H]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[#include +/* Some systems declare various items in the wrong headers. */ +#ifndef __GLIBC__ +# include +# include +# include +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# include +# endif +#endif + ]], [chown dup2 dup3 environ euidaccess faccessat fchdir fchownat + fsync ftruncate getcwd getdomainname getdtablesize getgroups + gethostname getlogin getlogin_r getpagesize getusershell setusershell + endusershell lchown link linkat lseek pipe2 pread pwrite readlink + readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat + usleep]) +]) + +AC_DEFUN([gl_UNISTD_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_UNISTD_H_DEFAULTS], +[ + GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) + GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE]) + GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) + GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) + GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) + GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS]) + GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) + GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) + GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) + GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) + GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) + GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) + GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME]) + GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE]) + GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS]) + GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME]) + GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN]) + GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) + GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) + GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL]) + GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) + GNULIB_LINK=0; AC_SUBST([GNULIB_LINK]) + GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT]) + GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) + GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2]) + GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD]) + GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE]) + GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) + GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT]) + GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR]) + GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) + GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK]) + GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT]) + GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R]) + GNULIB_UNISTD_H_GETOPT=0; AC_SUBST([GNULIB_UNISTD_H_GETOPT]) + GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) + GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK]) + GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) + GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) + GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) + HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) + HAVE_DUP3=1; AC_SUBST([HAVE_DUP3]) + HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS]) + HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) + HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) + HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) + HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) + HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) + HAVE_GETDOMAINNAME=1; AC_SUBST([HAVE_GETDOMAINNAME]) + HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) + HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS]) + HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) + HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN]) + HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE]) + HAVE_LCHOWN=1; AC_SUBST([HAVE_LCHOWN]) + HAVE_LINK=1; AC_SUBST([HAVE_LINK]) + HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT]) + HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2]) + HAVE_PREAD=1; AC_SUBST([HAVE_PREAD]) + HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE]) + HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) + HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT]) + HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) + HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK]) + HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT]) + HAVE_TTYNAME_R=1; AC_SUBST([HAVE_TTYNAME_R]) + HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT]) + HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP]) + HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) + HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R]) + HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE]) + HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL]) + HAVE_OS_H=0; AC_SUBST([HAVE_OS_H]) + HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H]) + REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN]) + REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) + REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) + REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) + REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) + REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) + REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) + REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) + REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) + REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) + REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT]) + REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) + REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD]) + REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE]) + REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) + REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) + REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) + REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) + REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R]) + REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK]) + REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) + REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP]) + REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE]) + UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H]) + UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0; + AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS]) +]) diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 new file mode 100644 index 000000000..ebe3c52cd --- /dev/null +++ b/m4/vasnprintf.m4 @@ -0,0 +1,288 @@ +# vasnprintf.m4 serial 31 +dnl Copyright (C) 2002-2004, 2006-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_VASNPRINTF], +[ + AC_CHECK_FUNCS_ONCE([vasnprintf]) + if test $ac_cv_func_vasnprintf = no; then + gl_REPLACE_VASNPRINTF + fi +]) + +AC_DEFUN([gl_REPLACE_VASNPRINTF], +[ + AC_CHECK_FUNCS_ONCE([vasnprintf]) + AC_LIBOBJ([vasnprintf]) + AC_LIBOBJ([printf-args]) + AC_LIBOBJ([printf-parse]) + AC_LIBOBJ([asnprintf]) + if test $ac_cv_func_vasnprintf = yes; then + AC_DEFINE([REPLACE_VASNPRINTF], [1], + [Define if vasnprintf exists but is overridden by gnulib.]) + fi + gl_PREREQ_PRINTF_ARGS + gl_PREREQ_PRINTF_PARSE + gl_PREREQ_VASNPRINTF + gl_PREREQ_ASNPRINTF +]) + +# Prequisites of lib/printf-args.h, lib/printf-args.c. +AC_DEFUN([gl_PREREQ_PRINTF_ARGS], +[ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) +]) + +# Prequisites of lib/printf-parse.h, lib/printf-parse.c. +AC_DEFUN([gl_PREREQ_PRINTF_PARSE], +[ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) + AC_REQUIRE([AC_TYPE_SIZE_T]) + AC_CHECK_TYPE([ptrdiff_t], , + [AC_DEFINE([ptrdiff_t], [long], + [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) + ]) + AC_REQUIRE([gt_AC_TYPE_INTMAX_T]) +]) + +# Prerequisites of lib/vasnprintf.c. +AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], +[ + AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([AC_FUNC_ALLOCA]) + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) + AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) + dnl Use the _snprintf function only if it is declared (because on NetBSD it + dnl is defined as a weak alias of snprintf; we prefer to use the latter). + AC_CHECK_DECLS([_snprintf], , , [#include ]) + dnl We can avoid a lot of code by assuming that snprintf's return value + dnl conforms to ISO C99. So check that. + AC_REQUIRE([gl_SNPRINTF_RETVAL_C99]) + case "$gl_cv_func_snprintf_retval_c99" in + *yes) + AC_DEFINE([HAVE_SNPRINTF_RETVAL_C99], [1], + [Define if the return value of the snprintf function is the number of + of bytes (excluding the terminating NUL) that would have been produced + if the buffer had been large enough.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting 'long double' +# arguments. +AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) + case "$gl_cv_func_printf_long_double" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'double' +# arguments. +AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_INFINITE]) + case "$gl_cv_func_printf_infinite" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_INFINITE_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + infinite 'double' arguments.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'long double' +# arguments. +AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE], +[ + AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE]) + dnl There is no need to set NEED_PRINTF_INFINITE_LONG_DOUBLE if + dnl NEED_PRINTF_LONG_DOUBLE is already set. + AC_REQUIRE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE]) + case "$gl_cv_func_printf_long_double" in + *yes) + case "$gl_cv_func_printf_infinite_long_double" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_INFINITE_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + infinite 'long double' arguments.]) + ;; + esac + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 'a' directive. +AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_A], +[ + AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) + case "$gl_cv_func_printf_directive_a" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], [1], + [Define if the vasnprintf implementation needs special code for + the 'a' and 'A' directives.]) + AC_CHECK_FUNCS([nl_langinfo]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 'F' directive. +AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_F], +[ + AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) + case "$gl_cv_func_printf_directive_f" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_DIRECTIVE_F], [1], + [Define if the vasnprintf implementation needs special code for + the 'F' directive.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 'ls' directive. +AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LS], +[ + AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS]) + case "$gl_cv_func_printf_directive_ls" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_DIRECTIVE_LS], [1], + [Define if the vasnprintf implementation needs special code for + the 'ls' directive.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the ' flag. +AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING], +[ + AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) + case "$gl_cv_func_printf_flag_grouping" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], + [Define if the vasnprintf implementation needs special code for the + ' flag.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the '-' flag. +AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST], +[ + AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST]) + case "$gl_cv_func_printf_flag_leftadjust" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_LEFTADJUST], [1], + [Define if the vasnprintf implementation needs special code for the + '-' flag.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag. +AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO], +[ + AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) + case "$gl_cv_func_printf_flag_zero" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_FLAG_ZERO], [1], + [Define if the vasnprintf implementation needs special code for the + 0 flag.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for supporting large precisions. +AC_DEFUN([gl_PREREQ_VASNPRINTF_PRECISION], +[ + AC_REQUIRE([gl_PRINTF_PRECISION]) + case "$gl_cv_func_printf_precision" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_UNBOUNDED_PRECISION], [1], + [Define if the vasnprintf implementation needs special code for + supporting large precisions without arbitrary bounds.]) + AC_DEFINE([NEED_PRINTF_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'double' arguments.]) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + +# Extra prerequisites of lib/vasnprintf.c for surviving out-of-memory +# conditions. +AC_DEFUN([gl_PREREQ_VASNPRINTF_ENOMEM], +[ + AC_REQUIRE([gl_PRINTF_ENOMEM]) + case "$gl_cv_func_printf_enomem" in + *yes) + ;; + *) + AC_DEFINE([NEED_PRINTF_ENOMEM], [1], + [Define if the vasnprintf implementation needs special code for + surviving out-of-memory conditions.]) + AC_DEFINE([NEED_PRINTF_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'double' arguments.]) + AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], + [Define if the vasnprintf implementation needs special code for + 'long double' arguments.]) + ;; + esac +]) + +# Prerequisites of lib/vasnprintf.c including all extras for POSIX compliance. +AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS], +[ + AC_REQUIRE([gl_PREREQ_VASNPRINTF]) + gl_PREREQ_VASNPRINTF_LONG_DOUBLE + gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE + gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE + gl_PREREQ_VASNPRINTF_DIRECTIVE_A + gl_PREREQ_VASNPRINTF_DIRECTIVE_F + gl_PREREQ_VASNPRINTF_DIRECTIVE_LS + gl_PREREQ_VASNPRINTF_FLAG_GROUPING + gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST + gl_PREREQ_VASNPRINTF_FLAG_ZERO + gl_PREREQ_VASNPRINTF_PRECISION + gl_PREREQ_VASNPRINTF_ENOMEM +]) + +# Prerequisites of lib/asnprintf.c. +AC_DEFUN([gl_PREREQ_ASNPRINTF], +[ +]) diff --git a/m4/vsnprintf.m4 b/m4/vsnprintf.m4 new file mode 100644 index 000000000..ed189c238 --- /dev/null +++ b/m4/vsnprintf.m4 @@ -0,0 +1,40 @@ +# vsnprintf.m4 serial 5 +dnl Copyright (C) 2002-2004, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_VSNPRINTF], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + gl_cv_func_vsnprintf_usable=no + AC_CHECK_FUNCS([vsnprintf]) + if test $ac_cv_func_vsnprintf = yes; then + gl_SNPRINTF_SIZE1 + case "$gl_cv_func_snprintf_size1" in + *yes) + gl_cv_func_vsnprintf_usable=yes + ;; + esac + fi + if test $gl_cv_func_vsnprintf_usable = no; then + gl_REPLACE_VSNPRINTF + fi + AC_CHECK_DECLS_ONCE([vsnprintf]) + if test $ac_cv_have_decl_vsnprintf = no; then + HAVE_DECL_VSNPRINTF=0 + fi +]) + +AC_DEFUN([gl_REPLACE_VSNPRINTF], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_LIBOBJ([vsnprintf]) + if test $ac_cv_func_vsnprintf = yes; then + REPLACE_VSNPRINTF=1 + fi + gl_PREREQ_VSNPRINTF +]) + +# Prerequisites of lib/vsnprintf.c. +AC_DEFUN([gl_PREREQ_VSNPRINTF], [:]) diff --git a/m4/warn-on-use.m4 b/m4/warn-on-use.m4 new file mode 100644 index 000000000..42daae87b --- /dev/null +++ b/m4/warn-on-use.m4 @@ -0,0 +1,45 @@ +# warn-on-use.m4 serial 2 +dnl Copyright (C) 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) +# --------------------------------------- +# For each whitespace-separated element in the list of NAMES, define +# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES +# even after being undefined as a macro. +# +# See warn-on-use.h for some hints on how to poison function names, as +# well as ideas on poisoning global variables and macros. NAMES may +# include global variables, but remember that only functions work with +# _GL_WARN_ON_USE. Typically, INCLUDES only needs to list a single +# header, but if the replacement header pulls in other headers because +# some systems declare functions in the wrong header, then INCLUDES +# should do likewise. +# +# If you assume C89, then it is generally safe to assume declarations +# for functions declared in that standard (such as gets) without +# needing gl_WARN_ON_USE_PREPARE. +AC_DEFUN([gl_WARN_ON_USE_PREPARE], +[ + m4_foreach_w([gl_decl], [$2], + [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), + [Define to 1 if ]m4_defn([gl_decl])[ is declared even after + undefining macros.])])dnl + for gl_func in m4_flatten([$2]); do + AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl + AC_CACHE_CHECK([whether $gl_func is declared without a macro], + gl_Symbol, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1], +[@%:@undef $gl_func + (void) $gl_func;])], + [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])]) + AS_VAR_IF(gl_Symbol, [yes], + [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) + dnl shortcut - if the raw declaration exists, then set a cache + dnl variable to allow skipping any later AC_CHECK_DECL efforts + eval ac_cv_have_decl_$gl_func=yes]) + AS_VAR_POPDEF([gl_Symbol])dnl + done +]) diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4 new file mode 100644 index 000000000..8cae82dd0 --- /dev/null +++ b/m4/wchar_h.m4 @@ -0,0 +1,152 @@ +dnl A placeholder for ISO C99 , for platforms that have issues. + +dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Eric Blake. + +# wchar_h.m4 serial 33 + +AC_DEFUN([gl_WCHAR_H], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) + dnl Prepare for creating substitute . + dnl Check for (missing in Linux uClibc when built without wide + dnl character support). + dnl is always overridden, because of GNULIB_POSIXCHECK. + AC_CHECK_HEADERS_ONCE([wchar.h]) + gl_CHECK_NEXT_HEADERS([wchar.h]) + if test $ac_cv_header_wchar_h = yes; then + HAVE_WCHAR_H=1 + else + HAVE_WCHAR_H=0 + fi + AC_SUBST([HAVE_WCHAR_H]) + + AC_REQUIRE([gt_TYPE_WINT_T]) + if test $gt_cv_c_wint_t = yes; then + HAVE_WINT_T=1 + else + HAVE_WINT_T=0 + fi + AC_SUBST([HAVE_WINT_T]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[ +/* Some systems require additional headers. */ +#ifndef __GLIBC__ +# include +# include +# include +#endif +#include + ]], [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb + wcsrtombs wcsnrtombs wcwidth]) +]) + +dnl Check whether is usable at all. +AC_DEFUN([gl_WCHAR_H_INLINE_OK], +[ + dnl Test whether suffers due to the transition from '__inline' to + dnl 'gnu_inline'. See + dnl and . In summary, + dnl glibc version 2.5 or older, together with gcc version 4.3 or newer and + dnl the option -std=c99 or -std=gnu99, leads to a broken . + AC_CACHE_CHECK([whether uses 'inline' correctly], + [gl_cv_header_wchar_h_correct_inline], + [gl_cv_header_wchar_h_correct_inline=yes + AC_LANG_CONFTEST([ + AC_LANG_SOURCE([[#define wcstod renamed_wcstod +#include +extern int zero (void); +int main () { return zero(); } +]])]) + if AC_TRY_EVAL([ac_compile]); then + mv conftest.$ac_objext conftest1.$ac_objext + AC_LANG_CONFTEST([ + AC_LANG_SOURCE([[#define wcstod renamed_wcstod +#include +int zero (void) { return 0; } +]])]) + if AC_TRY_EVAL([ac_compile]); then + mv conftest.$ac_objext conftest2.$ac_objext + if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then + : + else + gl_cv_header_wchar_h_correct_inline=no + fi + fi + fi + rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext + ]) + if test $gl_cv_header_wchar_h_correct_inline = no; then + AC_MSG_ERROR([ cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS). +This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in +C99 mode. You have four options: + - Add the flag -fgnu89-inline to CC and reconfigure, or + - Fix your include files, using parts of + , or + - Use a gcc version older than 4.3, or + - Don't use the flags -std=c99 or -std=gnu99. +Configuration aborted.]) + fi +]) + +dnl Unconditionally enables the replacement of . +AC_DEFUN([gl_REPLACE_WCHAR_H], +[ + dnl This is a no-op, because is always overridden. + : +]) + +AC_DEFUN([gl_WCHAR_MODULE_INDICATOR], +[ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + gl_MODULE_INDICATOR_SET_VARIABLE([$1]) + dnl Define it also as a C macro, for the benefit of the unit tests. + gl_MODULE_INDICATOR_FOR_TESTS([$1]) +]) + +AC_DEFUN([gl_WCHAR_H_DEFAULTS], +[ + GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC]) + GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB]) + GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT]) + GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC]) + GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN]) + GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS]) + GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS]) + GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB]) + GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS]) + GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) + GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) + HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) + HAVE_MBRTOWC=1; AC_SUBST([HAVE_MBRTOWC]) + HAVE_MBRLEN=1; AC_SUBST([HAVE_MBRLEN]) + HAVE_MBSRTOWCS=1; AC_SUBST([HAVE_MBSRTOWCS]) + HAVE_MBSNRTOWCS=1; AC_SUBST([HAVE_MBSNRTOWCS]) + HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB]) + HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS]) + HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS]) + HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) + HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) + REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) + REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC]) + REPLACE_WCTOB=0; AC_SUBST([REPLACE_WCTOB]) + REPLACE_MBSINIT=0; AC_SUBST([REPLACE_MBSINIT]) + REPLACE_MBRTOWC=0; AC_SUBST([REPLACE_MBRTOWC]) + REPLACE_MBRLEN=0; AC_SUBST([REPLACE_MBRLEN]) + REPLACE_MBSRTOWCS=0; AC_SUBST([REPLACE_MBSRTOWCS]) + REPLACE_MBSNRTOWCS=0; AC_SUBST([REPLACE_MBSNRTOWCS]) + REPLACE_WCRTOMB=0; AC_SUBST([REPLACE_WCRTOMB]) + REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS]) + REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS]) + REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) +]) diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4 new file mode 100644 index 000000000..a133e6ad5 --- /dev/null +++ b/m4/wchar_t.m4 @@ -0,0 +1,24 @@ +# wchar_t.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2002-2003, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether has the 'wchar_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WCHAR_T], +[ + AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + wchar_t foo = (wchar_t)'\0';]], + [[]])], + [gt_cv_c_wchar_t=yes], + [gt_cv_c_wchar_t=no])]) + if test $gt_cv_c_wchar_t = yes; then + AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.]) + fi +]) diff --git a/m4/wcrtomb.m4 b/m4/wcrtomb.m4 new file mode 100644 index 000000000..0de262e61 --- /dev/null +++ b/m4/wcrtomb.m4 @@ -0,0 +1,94 @@ +# wcrtomb.m4 serial 6 +dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_WCRTOMB], +[ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) + + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + gl_MBSTATE_T_BROKEN + + AC_CHECK_FUNCS_ONCE([wcrtomb]) + if test $ac_cv_func_wcrtomb = no; then + HAVE_WCRTOMB=0 + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_WCRTOMB=1 + else + dnl On AIX 4.3, OSF/1 5.1 and Solaris 10, wcrtomb (NULL, 0, NULL) sometimes + dnl returns 0 instead of 1. + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether wcrtomb return value is correct], + [gl_cv_func_wcrtomb_retval], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on AIX 4, OSF/1 and Solaris. + aix4* | osf* | solaris*) gl_cv_func_wcrtomb_retval="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_wcrtomb_retval="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#include +int main () +{ + if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) + return 1; + } + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) + return 1; + } + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) + return 1; + } + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) + return 1; + } + return 0; +}]])], + [gl_cv_func_wcrtomb_retval=yes], + [gl_cv_func_wcrtomb_retval=no], + [:]) + fi + ]) + case "$gl_cv_func_wcrtomb_retval" in + *yes) ;; + *) REPLACE_WCRTOMB=1 ;; + esac + fi + fi + if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then + gl_REPLACE_WCHAR_H + AC_LIBOBJ([wcrtomb]) + gl_PREREQ_WCRTOMB + fi +]) + +# Prerequisites of lib/wcrtomb.c. +AC_DEFUN([gl_PREREQ_WCRTOMB], [ + : +]) diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4 new file mode 100644 index 000000000..bc6b6e791 --- /dev/null +++ b/m4/wctype_h.m4 @@ -0,0 +1,85 @@ +# wctype_h.m4 serial 8 + +dnl A placeholder for ISO C99 , for platforms that lack it. + +dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Written by Paul Eggert. + +AC_DEFUN([gl_WCTYPE_H], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS_ONCE([iswcntrl]) + if test $ac_cv_func_iswcntrl = yes; then + HAVE_ISWCNTRL=1 + else + HAVE_ISWCNTRL=0 + fi + AC_SUBST([HAVE_ISWCNTRL]) + AC_CHECK_FUNCS_ONCE([iswblank]) + AC_CHECK_DECLS_ONCE([iswblank]) + if test $ac_cv_func_iswblank = yes; then + HAVE_ISWBLANK=1 + REPLACE_ISWBLANK=0 + else + HAVE_ISWBLANK=0 + if test $ac_cv_have_decl_iswblank = yes; then + REPLACE_ISWBLANK=1 + else + REPLACE_ISWBLANK=0 + fi + fi + AC_SUBST([HAVE_ISWBLANK]) + AC_SUBST([REPLACE_ISWBLANK]) + + AC_CHECK_HEADERS_ONCE([wctype.h]) + AC_REQUIRE([AC_C_INLINE]) + + AC_REQUIRE([gt_TYPE_WINT_T]) + if test $gt_cv_c_wint_t = yes; then + HAVE_WINT_T=1 + else + HAVE_WINT_T=0 + fi + AC_SUBST([HAVE_WINT_T]) + + if test $ac_cv_header_wctype_h = yes; then + if test $ac_cv_func_iswcntrl = yes; then + dnl Linux libc5 has an iswprint function that returns 0 for all arguments. + dnl The other functions are likely broken in the same way. + AC_CACHE_CHECK([whether iswcntrl works], [gl_cv_func_iswcntrl_works], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + #include + #include + int main () { return iswprint ('x') == 0; }]])], + [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #if __GNU_LIBRARY__ == 1 + Linux libc5 i18n is broken. + #endif]], [])], + [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no]) + ]) + ]) + fi + gl_CHECK_NEXT_HEADERS([wctype.h]) + HAVE_WCTYPE_H=1 + else + HAVE_WCTYPE_H=0 + fi + AC_SUBST([HAVE_WCTYPE_H]) + + if test "$gl_cv_func_iswcntrl_works" = no; then + REPLACE_ISWCNTRL=1 + else + REPLACE_ISWCNTRL=0 + fi + AC_SUBST([REPLACE_ISWCNTRL]) +]) diff --git a/m4/wint_t.m4 b/m4/wint_t.m4 new file mode 100644 index 000000000..58ef86556 --- /dev/null +++ b/m4/wint_t.m4 @@ -0,0 +1,32 @@ +# wint_t.m4 serial 5 (gettext-0.18.2) +dnl Copyright (C) 2003, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether has the 'wint_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WINT_T], +[ + AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be included + before . */ +#include +#include +#include +#include + wint_t foo = (wchar_t)'\0';]], + [[]])], + [gt_cv_c_wint_t=yes], + [gt_cv_c_wint_t=no])]) + if test $gt_cv_c_wint_t = yes; then + AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.]) + fi +]) diff --git a/m4/xsize.m4 b/m4/xsize.m4 new file mode 100644 index 000000000..b653693a3 --- /dev/null +++ b/m4/xsize.m4 @@ -0,0 +1,13 @@ +# xsize.m4 serial 4 +dnl Copyright (C) 2003-2004, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_XSIZE], +[ + dnl Prerequisites of lib/xsize.h. + AC_REQUIRE([gl_SIZE_MAX]) + AC_REQUIRE([AC_C_INLINE]) + AC_CHECK_HEADERS([stdint.h]) +]) From c5930ec832e823a9fa1f952d0f47f332084b78ad Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Mon, 20 Sep 2010 12:37:37 +0200 Subject: [PATCH 0210/1414] * util/grub-setup.c: Use argp instead of getopt. --- ChangeLog | 4 + util/grub-setup.c | 366 +++++++++++++++++++++++++--------------------- 2 files changed, 206 insertions(+), 164 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f235a016..a470425b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-20 Yves Blusseau + + * util/grub-setup.c: Use argp instead of getopt. + 2010-09-20 Yves Blusseau Use gnulib-tool to create gnulib source files. diff --git a/util/grub-setup.c b/util/grub-setup.c index 1bf0d958d..90a4b2ac2 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -50,7 +50,7 @@ #include "progname.h" #define _GNU_SOURCE 1 -#include +#include /* On SPARC this program fills in various fields inside of the 'boot' and 'core' * image files. @@ -643,55 +643,163 @@ unable_to_embed: grub_device_close (root_dev); } -static struct option options[] = - { - {"boot-image", required_argument, 0, 'b'}, - {"core-image", required_argument, 0, 'c'}, - {"directory", required_argument, 0, 'd'}, - {"device-map", required_argument, 0, 'm'}, - {"root-device", required_argument, 0, 'r'}, - {"force", no_argument, 0, 'f'}, - {"skip-fs-probe", no_argument, 0, 's'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; +static struct argp_option options[] = { + {"boot-image", 'b', N_("FILE"), 0, + N_("Use FILE as the boot image [default=%s]"), 0}, + {"core-image", 'c', N_("FILE"), 0, + N_("Use FILE as the core image [default=%s]"), 0}, + {"directory", 'd', N_("DIR"), 0, + N_("Use GRUB files in the directory DIR [default=%s]"), 0}, + {"device-map", 'm', N_("FILE"), 0, + N_("Use FILE as the device map [default=%s]"), 0}, + {"root-device", 'r', N_("DEV"), 0, + N_("Use DEV as the root device [default=guessed]"), 0}, + {"force", 'f', 0, 0, + N_("Install even if problems are detected"), 0}, + {"skip-fs-probe",'s',0, 0, + N_("Do not probe for filesystems in DEVICE"), 0}, + {"verbose", 'v', 0, 0, + N_("Print verbose messages."), 0}, + { 0, 0, 0, 0, 0, 0 } +}; -static void -usage (int status) +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) { - if (status) - fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); - else - printf (_("\ -Usage: %s [OPTION]... DEVICE\n\ -\n\ -Set up images to boot from DEVICE.\n\ -DEVICE must be a GRUB device (e.g. `(hd0,1)').\n\ -\n\ -You should not normally run %s directly. Use grub-install instead.\n\ -\n\ - -b, --boot-image=FILE use FILE as the boot image [default=%s]\n\ - -c, --core-image=FILE use FILE as the core image [default=%s]\n\ - -d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n\ - -m, --device-map=FILE use FILE as the device map [default=%s]\n\ - -r, --root-device=DEV use DEV as the root device [default=guessed]\n\ - -f, --force install even if problems are detected\n\ - -s, --skip-fs-probe do not probe for filesystems in DEVICE\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -"), - program_name, program_name, - DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY, - DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); + switch (key) + { + case 'b': + return xasprintf (text, DEFAULT_BOOT_FILE); - exit (status); + case 'c': + return xasprintf (text, DEFAULT_CORE_FILE); + + case 'd': + return xasprintf (text, DEFAULT_DIRECTORY); + + case 'm': + return xasprintf (text, DEFAULT_DEVICE_MAP); + + default: + return (char *) text; + } } +struct arguments +{ + char *boot_file; + char *core_file; + char *dir; + char *dev_map; + char *root_dev; + int force; + int fs_probe; + char *device; +}; + +/* Print the version information. */ +static void +print_version (FILE *stream, struct argp_state *state) +{ + fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); +} +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +/* Set the bug report address */ +const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">"; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + /* Get the input argument from argp_parse, which we + know is a pointer to our arguments structure. */ + struct arguments *arguments = state->input; + + char *p; + + switch (key) + { + case 'b': + if (arguments->boot_file) + free (arguments->boot_file); + + arguments->boot_file = xstrdup (arg); + break; + + case 'c': + if (arguments->core_file) + free (arguments->core_file); + + arguments->core_file = xstrdup (arg); + break; + + case 'd': + if (arguments->dir) + free (arguments->dir); + + arguments->dir = xstrdup (arg); + break; + + case 'm': + if (arguments->dev_map) + free (arguments->dev_map); + + arguments->dev_map = xstrdup (arg); + break; + + case 'r': + if (arguments->root_dev) + free (arguments->root_dev); + + arguments->root_dev = xstrdup (arg); + break; + + case 'f': + arguments->force = 1; + break; + + case 's': + arguments->fs_probe = 0; + break; + + case 'v': + verbosity++; + break; + + case ARGP_KEY_ARG: + if (state->arg_num == 0) + arguments->device = xstrdup(arg); + else + { + /* Too many arguments. */ + fprintf (stderr, _("Unknown extra argument `%s'.\n"), arg); + argp_usage (state); + } + break; + + case ARGP_KEY_NO_ARGS: + fprintf (stderr, _("No device is specified.\n")); + argp_usage (state); + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +static struct argp argp = { + options, argp_parser, N_("DEVICE"), + N_("\n\ +Set up images to boot from DEVICE.\n\ +\n\ +You should not normally run this program directly. Use grub-install instead.\n\ +\v\ +DEVICE must be an OS device (e.g. /dev/sda1)."), + NULL, help_filter, NULL +}; + static char * get_device_name (char *dev) { @@ -707,13 +815,10 @@ get_device_name (char *dev) int main (int argc, char *argv[]) { - char *boot_file = NULL; - char *core_file = NULL; - char *dir = NULL; - char *dev_map = NULL; char *root_dev = NULL; char *dest_dev = NULL; - int must_embed = 0, force = 0, fs_probe = 1; + int must_embed = 0; + struct arguments arguments; #ifdef GRUB_MACHINE_IEEE1275 force = 1; @@ -723,95 +828,22 @@ main (int argc, char *argv[]) grub_util_init_nls (); - /* Check for options. */ - while (1) + /* Default option values. */ + memset (&arguments, 0, sizeof (struct arguments)); + arguments.fs_probe = 1; + + /* Parse our arguments */ + if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) { - int c = getopt_long (argc, argv, "b:c:d:m:r:hVvf", options, 0); - - if (c == -1) - break; - else - switch (c) - { - case 'b': - if (boot_file) - free (boot_file); - - boot_file = xstrdup (optarg); - break; - - case 'c': - if (core_file) - free (core_file); - - core_file = xstrdup (optarg); - break; - - case 'd': - if (dir) - free (dir); - - dir = xstrdup (optarg); - break; - - case 'm': - if (dev_map) - free (dev_map); - - dev_map = xstrdup (optarg); - break; - - case 'r': - if (root_dev) - free (root_dev); - - root_dev = xstrdup (optarg); - break; - - case 'f': - force = 1; - break; - - case 's': - fs_probe = 0; - break; - - case 'h': - usage (0); - break; - - case 'V': - printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); - return 0; - - case 'v': - verbosity++; - break; - - default: - usage (1); - break; - } + fprintf (stderr, _("Error in parsing command line arguments\n")); + exit(1); } if (verbosity > 1) grub_env_set ("debug", "all"); - /* Obtain DEST_DEV. */ - if (optind >= argc) - { - fprintf (stderr, _("No device is specified.\n")); - usage (1); - } - - if (optind + 1 != argc) - { - fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); - usage (1); - } - /* Initialize the emulated biosdisk driver. */ - grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP); + grub_util_biosdisk_init (arguments.dev_map ? : DEFAULT_DEVICE_MAP); /* Initialize all modules. */ grub_init_all (); @@ -823,18 +855,21 @@ main (int argc, char *argv[]) grub_mdraid_init (); grub_lvm_init (); - dest_dev = get_device_name (argv[optind]); + dest_dev = get_device_name (arguments.device); if (! dest_dev) { /* Possibly, the user specified an OS device file. */ - dest_dev = grub_util_get_grub_dev (argv[optind]); + dest_dev = grub_util_get_grub_dev (arguments.device); if (! dest_dev) - { - fprintf (stderr, _("Invalid device `%s'.\n"), argv[optind]); - usage (1); - } + { + char *program = xstrdup(program_name); + fprintf (stderr, _("Invalid device `%s'.\n"), arguments.device); + argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program); + free(program); + exit(1); + } grub_util_info ("transformed OS device `%s' into GRUB device `%s'", - argv[optind], dest_dev); + arguments.device, dest_dev); } else { @@ -843,31 +878,31 @@ main (int argc, char *argv[]) grub_util_info ("Using `%s' as GRUB device", dest_dev); } - if (root_dev) + if (arguments.root_dev) { - char *tmp = get_device_name (root_dev); + root_dev = get_device_name (arguments.root_dev); - if (! tmp) - grub_util_error (_("invalid root device `%s'"), root_dev); + if (! root_dev) + grub_util_error (_("invalid root device `%s'"), arguments.root_dev); - tmp = xstrdup (tmp); - free (root_dev); - root_dev = tmp; + root_dev = xstrdup (root_dev); } else { - char *root_device = grub_guess_root_device (dir ? : DEFAULT_DIRECTORY); + char *root_device = + grub_guess_root_device (arguments.dir ? : DEFAULT_DIRECTORY); root_dev = grub_util_get_grub_dev (root_device); if (! root_dev) { grub_util_info ("guessing the root device failed, because of `%s'", grub_errmsg); - grub_util_error (_("cannot guess the root device. Specify the option `--root-device'")); + grub_util_error (_("cannot guess the root device. Specify the option " + "`--root-device'")); } grub_util_info ("guessed root device `%s' and root_dev `%s' from " - "dir `%s'", root_device, root_dev, - dir ? : DEFAULT_DIRECTORY); + "dir `%s'", root_device, root_dev, + arguments.dir ? : DEFAULT_DIRECTORY); } #ifdef __linux__ @@ -890,29 +925,32 @@ main (int argc, char *argv[]) devicelist = grub_util_raid_getmembers (dest_dev); for (i = 0; devicelist[i]; i++) - { - setup (dir ? : DEFAULT_DIRECTORY, - boot_file ? : DEFAULT_BOOT_FILE, - core_file ? : DEFAULT_CORE_FILE, - root_dev, grub_util_get_grub_dev (devicelist[i]), 1, force, fs_probe); - } + { + setup (arguments.dir ? : DEFAULT_DIRECTORY, + arguments.boot_file ? : DEFAULT_BOOT_FILE, + arguments.core_file ? : DEFAULT_CORE_FILE, + root_dev, grub_util_get_grub_dev (devicelist[i]), 1, + arguments.force, arguments.fs_probe); + } } else #endif /* Do the real work. */ - setup (dir ? : DEFAULT_DIRECTORY, - boot_file ? : DEFAULT_BOOT_FILE, - core_file ? : DEFAULT_CORE_FILE, - root_dev, dest_dev, must_embed, force, fs_probe); + setup (arguments.dir ? : DEFAULT_DIRECTORY, + arguments.boot_file ? : DEFAULT_BOOT_FILE, + arguments.core_file ? : DEFAULT_CORE_FILE, + root_dev, dest_dev, must_embed, arguments.force, arguments.fs_probe); /* Free resources. */ grub_fini_all (); grub_util_biosdisk_fini (); - free (boot_file); - free (core_file); - free (dir); - free (dev_map); + free (arguments.boot_file); + free (arguments.core_file); + free (arguments.dir); + free (arguments.root_dev); + free (arguments.dev_map); + free (arguments.device); free (root_dev); free (dest_dev); From 6439b8ee819d7c8fd2d3ed1afd501390638c79e8 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Mon, 20 Sep 2010 12:39:28 +0200 Subject: [PATCH 0211/1414] * util/grub-editenv.c: Use argp instead of getopt. --- ChangeLog | 4 ++ util/grub-editenv.c | 156 ++++++++++++++++++++++++-------------------- 2 files changed, 90 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index a470425b7..6e9fedfe5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-20 Yves Blusseau + + * util/grub-editenv.c: Use argp instead of getopt. + 2010-09-20 Yves Blusseau * util/grub-setup.c: Use argp instead of getopt. diff --git a/util/grub-editenv.c b/util/grub-editenv.c index 75cccd04e..3ea026cfe 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -28,46 +28,82 @@ #include #include #include -#include +#include #include "progname.h" #define DEFAULT_ENVBLK_SIZE 1024 +#define DEFAULT_ENVBLK_PATH DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG -static struct option options[] = { - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} +static struct argp_option options[] = { + {0, 0, 0, OPTION_DOC, N_("Commands:"), 1}, + {"create", 0, 0, OPTION_DOC|OPTION_NO_USAGE, + N_("Create a blank environment block file."), 0}, + {"list", 0, 0, OPTION_DOC|OPTION_NO_USAGE, + N_("List the current variables."), 0}, + {"set [name=value ...]", 0, 0, OPTION_DOC|OPTION_NO_USAGE, + N_("Set variables."), 0}, + {"unset [name ....]", 0, 0, OPTION_DOC|OPTION_NO_USAGE, + N_("Delete variables."), 0}, + + {0, 0, 0, OPTION_DOC, N_("Options:"), -1}, + {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0}, + + { 0, 0, 0, 0, 0, 0 } }; +/* Print the version information. */ static void -usage (int status) +print_version (FILE *stream, struct argp_state *state) { - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s [OPTIONS] [FILENAME] COMMAND\n\ -\n\ -Tool to edit environment block.\n\ -\nCommands:\n\ - create create a blank environment block file\n\ - list list the current variables\n\ - set [name=value ...] set variables\n\ - unset [name ....] delete variables\n\ -\nOptions:\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -If not given explicitly, FILENAME defaults to %s.\n\ -\n\ -Report bugs to <%s>.\n", -program_name, DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG, PACKAGE_BUGREPORT); - - exit (status); + fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); } +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +/* Set the bug report address */ +const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">"; + +error_t argp_parser (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'v': + verbosity++; + break; + + case ARGP_KEY_NO_ARGS: + fprintf (stderr, _("You need to specify at least one command.\n")); + argp_usage (state); + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case ARGP_KEY_HELP_POST_DOC: + return xasprintf(text, DEFAULT_ENVBLK_PATH); + + default: + return (char *) text; + } +} + +struct argp argp = { + options, argp_parser, N_("FILENAME COMMAND"), + N_("\n\ +Tool to edit environment block.\n\ +\v\ +If FILENAME is '-', the default value %s is used.\n"), + NULL, help_filter, NULL +}; static void create_envblk_file (const char *name) @@ -227,55 +263,32 @@ main (int argc, char *argv[]) { char *filename; char *command; + int index, arg_count; set_program_name (argv[0]); grub_util_init_nls (); - /* Check for options. */ - while (1) + /* Parse our arguments */ + if (argp_parse (&argp, argc, argv, 0, &index, 0) != 0) { - int c = getopt_long (argc, argv, "hVv", options, 0); - - if (c == -1) - break; - else - switch (c) - { - case 'h': - usage (0); - break; - - case 'V': - printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); - return 0; - - case 'v': - verbosity++; - break; - - default: - usage (1); - break; - } + fprintf (stderr, _("Error in parsing command line arguments\n")); + exit(1); } - /* Obtain the filename. */ - if (optind >= argc) - { - fprintf (stderr, "no filename specified\n"); - usage (1); - } + arg_count = argc - index; - if (optind + 1 >= argc) + if (arg_count == 1) { - filename = DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG; - command = argv[optind]; + filename = DEFAULT_ENVBLK_PATH; + command = argv[index++]; } else { - filename = argv[optind]; - command = argv[optind + 1]; + filename = argv[index++]; + if (strcmp (filename, "-") == 0) + filename = DEFAULT_ENVBLK_PATH; + command = argv[index++]; } if (strcmp (command, "create") == 0) @@ -283,13 +296,16 @@ main (int argc, char *argv[]) else if (strcmp (command, "list") == 0) list_variables (filename); else if (strcmp (command, "set") == 0) - set_variables (filename, argc - optind - 2, argv + optind + 2); + set_variables (filename, argc - index, argv + index); else if (strcmp (command, "unset") == 0) - unset_variables (filename, argc - optind - 2, argv + optind + 2); + unset_variables (filename, argc - index, argv + index); else { - fprintf (stderr, "unknown command %s\n", command); - usage (1); + char *program = xstrdup(program_name); + fprintf (stderr, _("Unknown command `%s'.\n"), command); + argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program); + free(program); + exit(1); } return 0; From a63c31b62d204588f5a7f7ccb4b93c09aeb29f78 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 12:12:33 +0100 Subject: [PATCH 0212/1414] * kern/emu/hostdisk.c: Include and on FreeBSD. Define HAVE_DIOCGDINFO on NetBSD and FreeBSD to reduce the verbosity of later #ifs. (find_partition_start): Define this function on FreeBSD too. (device_is_wholedisk) [__FreeBSD__ || __FreeBSD_kernel__]: New function. (grub_util_biosdisk_get_grub_dev): Use partition-start-sector logic on FreeBSD. --- ChangeLog | 11 ++++ grub-core/kern/emu/hostdisk.c | 115 ++++++++++++++++------------------ 2 files changed, 65 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e9fedfe5..0aaeb74d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-09-20 Colin Watson + + * kern/emu/hostdisk.c: Include and + on FreeBSD. Define HAVE_DIOCGDINFO on NetBSD and FreeBSD to reduce + the verbosity of later #ifs. + (find_partition_start): Define this function on FreeBSD too. + (device_is_wholedisk) [__FreeBSD__ || __FreeBSD_kernel__]: New + function. + (grub_util_biosdisk_get_grub_dev): Use partition-start-sector logic + on FreeBSD. + 2010-09-20 Yves Blusseau * util/grub-editenv.c: Use argp instead of getopt. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 7d9d1dac1..e53d9d440 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -102,9 +102,15 @@ struct hd_geometry # include #endif -#if defined(__NetBSD__) +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +# define HAVE_DIOCGDINFO # include # include /* struct disklabel */ +#else /* !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) */ +# undef HAVE_DIOCGDINFO +#endif /* defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */ + +#if defined(__NetBSD__) # ifdef HAVE_GETRAWPARTITION # include /* getrawpartition */ # endif /* HAVE_GETRAWPARTITION */ @@ -328,17 +334,17 @@ device_is_mapped (const char *dev) } #endif /* HAVE_DEVICE_MAPPER */ -#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) static grub_disk_addr_t find_partition_start (const char *dev) { int fd; -# if !defined(__NetBSD__) +# if !defined(HAVE_DIOCGDINFO) struct hd_geometry hdg; -# else /* defined(__NetBSD__) */ +# else /* defined(HAVE_DIOCGDINFO) */ struct disklabel label; int p_index; -# endif /* !defined(__NetBSD__) */ +# endif /* !defined(HAVE_DIOCGDINFO) */ # ifdef HAVE_DEVICE_MAPPER if (grub_device_mapper_supported () && device_is_mapped (dev)) { @@ -412,36 +418,38 @@ devmapper_fail: if (fd == -1) { grub_error (GRUB_ERR_BAD_DEVICE, -# if !defined(__NetBSD__) +# if !defined(HAVE_DIOCGDINFO) "cannot open `%s' while attempting to get disk geometry", dev); -# else /* defined(__NetBSD__) */ +# else /* defined(HAVE_DIOCGDINFO) */ "cannot open `%s' while attempting to get disk label", dev); -# endif /* !defined(__NetBSD__) */ +# endif /* !defined(HAVE_DIOCGDINFO) */ return 0; } -# if !defined(__NetBSD__) +# if !defined(HAVE_DIOCGDINFO) if (ioctl (fd, HDIO_GETGEO, &hdg)) -# else /* defined(__NetBSD__) */ +# else /* defined(HAVE_DIOCGDINFO) */ +# if defined(__NetBSD__) configure_device_driver (fd); +# endif /* defined(__NetBSD__) */ if (ioctl (fd, DIOCGDINFO, &label) == -1) -# endif /* !defined(__NetBSD__) */ +# endif /* !defined(HAVE_DIOCGDINFO) */ { grub_error (GRUB_ERR_BAD_DEVICE, -# if !defined(__NetBSD__) +# if !defined(HAVE_DIOCGDINFO) "cannot get disk geometry of `%s'", dev); -# else /* defined(__NetBSD__) */ +# else /* defined(HAVE_DIOCGDINFO) */ "cannot get disk label of `%s'", dev); -# endif /* !defined(__NetBSD__) */ +# endif /* !defined(HAVE_DIOCGDINFO) */ close (fd); return 0; } close (fd); -# if !defined(__NetBSD__) +# if !defined(HAVE_DIOCGDINFO) return hdg.start; -# else /* defined(__NetBSD__) */ +# else /* defined(HAVE_DIOCGDINFO) */ p_index = dev[strlen(dev) - 1] - 'a'; if (p_index >= label.d_npartitions) @@ -451,9 +459,9 @@ devmapper_fail: return 0; } return (grub_disk_addr_t) label.d_partitions[p_index].p_offset; -# endif /* !defined(__NetBSD__) */ +# endif /* !defined(HAVE_DIOCGDINFO) */ } -#endif /* __linux__ || __CYGWIN__ */ +#endif /* __linux__ || __CYGWIN__ || HAVE_DIOCGDINFO */ #ifdef __linux__ /* Cache of partition start sectors for each disk. */ @@ -996,8 +1004,7 @@ grub_util_biosdisk_fini (void) /* * Note: we do not use the new partition naming scheme as dos_part does not - * necessarily correspond to an msdos partition. See e.g. the FreeBSD code - * in function grub_util_biosdisk_get_grub_dev. + * necessarily correspond to an msdos partition. */ static char * make_device_name (int drive, int dos_part, int bsd_part) @@ -1349,6 +1356,27 @@ device_is_wholedisk (const char *os_dev) } #endif /* defined(__NetBSD__) */ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static int +device_is_wholedisk (const char *os_dev) +{ + const char *p; + + if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return 0; + + for (p = os_dev + sizeof ("/dev/") - 1; *p; ++p) + if (grub_isdigit (*p)) + { + if (strchr (p, 's')) + return 0; + break; + } + + return 1; +} +#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */ + static int find_system_device (const char *os_dev, struct stat *st, int add) { @@ -1422,7 +1450,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) #endif return make_device_name (drive, -1, -1); -#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) /* Linux counts partitions uniformly, whether a BSD partition or a DOS partition, so mapping them to GRUB devices is not trivial. Here, get the start sector of a partition by HDIO_GETGEO, and @@ -1432,8 +1460,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) does not count the extended partition and missing primary partitions. Use same method as on Linux here. - For NetBSD, proceed as for Linux, except that the start sector is - obtained from the disk label. */ + For NetBSD and FreeBSD, proceed as for Linux, except that the start + sector is obtained from the disk label. */ { char *name, *partname; grub_disk_t disk; @@ -1461,13 +1489,13 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) name = make_device_name (drive, -1, -1); -# if !defined(__NetBSD__) +# if !defined(HAVE_DIOCGDINFO) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) return name; -# else /* defined(__NetBSD__) */ +# else /* defined(HAVE_DIOCGDINFO) */ /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are * different, we know that os_dev cannot be a floppy device. */ -# endif /* !defined(__NetBSD__) */ +# endif /* !defined(HAVE_DIOCGDINFO) */ start = find_partition_start (os_dev); if (grub_errno != GRUB_ERR_NONE) @@ -1536,41 +1564,6 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return make_device_name (drive, dos_part, bsd_part); } -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) - /* FreeBSD uses "/dev/[a-z]+[0-9]+([sp][0-9]+[a-z]?)?". */ - { - int dos_part = -1; - int bsd_part = -1; - - if (strncmp ("/dev/", os_dev, 5) == 0) - { - const char *p; - char *q; - long int n; - - for (p = os_dev + 5; *p; ++p) - if (grub_isdigit(*p)) - { - p = strpbrk (p, "sp"); /* msdos or apple (or ... ?) partition map */ - if (p) - { - p++; - n = strtol (p, &q, 10); - if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX) - { - dos_part = (int) n - 1; - - if (*q >= 'a' && *q <= 'g') - bsd_part = *q - 'a'; - } - } - break; - } - } - - return make_device_name (drive, dos_part, bsd_part); - } - #else # warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly." return make_device_name (drive, -1, -1); From c982589f0c6a44bf7091dacacd726a683a438e9c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 13:14:44 +0100 Subject: [PATCH 0213/1414] * util/grub-mkrescue.in: Add explicit root argument to --set to prevent the UUID being interpreted as an argument to --set (matches previous change to prepare_grub_to_access_device). --- ChangeLog | 6 ++++++ util/grub-mkrescue.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0aaeb74d9..721410445 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-20 Colin Watson + + * util/grub-mkrescue.in: Add explicit root argument to --set to + prevent the UUID being interpreted as an argument to --set (matches + previous change to prepare_grub_to_access_device). + 2010-09-20 Colin Watson * kern/emu/hostdisk.c: Include and diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 142ee85cd..f2714c486 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -202,7 +202,7 @@ make_image () mkdir -p ${memdisk_dir}/boot/grub cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg -search --fs-uuid --set ${iso_uuid} +search --fs-uuid --set=root ${iso_uuid} set prefix=(\${root})/boot/grub/${platform} source \$prefix/grub.cfg EOF From 6d3d698d134a13938058f1205a82bc0b30794ba6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 13:18:41 +0100 Subject: [PATCH 0214/1414] * grub-core/commands/efi/lsefisystab.c: Correct header. * grub-core/commands/efi/lssal.c: Likewise. * grub-core/commands/testload.c: Likewise. --- ChangeLog | 6 ++++++ grub-core/commands/efi/lsefisystab.c | 2 +- grub-core/commands/efi/lssal.c | 2 +- grub-core/commands/testload.c | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 721410445..dd0d172ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-20 Colin Watson + + * grub-core/commands/efi/lsefisystab.c: Correct header. + * grub-core/commands/efi/lssal.c: Likewise. + * grub-core/commands/testload.c: Likewise. + 2010-09-20 Colin Watson * util/grub-mkrescue.in: Add explicit root argument to --set to diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c index ac84fc426..aa3e05aee 100644 --- a/grub-core/commands/efi/lsefisystab.c +++ b/grub-core/commands/efi/lsefisystab.c @@ -1,4 +1,4 @@ -/* systab.c - Display EFI systab. */ +/* lsefisystab.c - Display EFI systab. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008 Free Software Foundation, Inc. diff --git a/grub-core/commands/efi/lssal.c b/grub-core/commands/efi/lssal.c index 245883f90..2ee993033 100644 --- a/grub-core/commands/efi/lssal.c +++ b/grub-core/commands/efi/lssal.c @@ -1,4 +1,4 @@ -/* systab.c - Display EFI systab. */ +/* lssal.c - Display EFI SAL systab. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008 Free Software Foundation, Inc. diff --git a/grub-core/commands/testload.c b/grub-core/commands/testload.c index 3b6ddfae3..86b8a9253 100644 --- a/grub-core/commands/testload.c +++ b/grub-core/commands/testload.c @@ -1,4 +1,4 @@ -/* minicmd.c - commands for the rescue mode */ +/* testload.c - load the same file in multiple ways */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc. From 5ee21c970b4da2650bd13b3070d7c1aa5e1d316b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 14:48:17 +0200 Subject: [PATCH 0215/1414] Add terminal support in legacy_parser --- grub-core/lib/legacy_parse.c | 150 ++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 21 deletions(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 6ad15dc49..09905bd42 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -45,12 +45,14 @@ struct legacy_command TYPE_VBE_MODE } argt[4]; enum { - FLAG_IGNORE_REST = 1, - FLAG_FALLBACK_AVAILABLE = 4, - FLAG_FALLBACK = 8, - FLAG_COLOR_INVERT = 16, - FLAG_NO_MENUENTRY = 32, - FLAG_MENUENTRY_ONLY = 64, + FLAG_IGNORE_REST = 0x001, + FLAG_FALLBACK_AVAILABLE = 0x004, + FLAG_FALLBACK = 0x008, + FLAG_COLOR_INVERT = 0x010, + FLAG_NO_MENUENTRY = 0x020, + FLAG_MENUENTRY_ONLY = 0x040, + FLAG_TERMINAL = 0x080, + FLAG_TITLE = 0x100, } flags; const char *shortdesc; const char *longdesc; @@ -271,7 +273,22 @@ struct legacy_command legacy_commands[] = " default values are COM1, 9600, 8N1."}, /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ /* NOTE: setup unsupported. */ - /* FIXME: terminal unsupported. */ /* NUL_TERMINATE */ + /* FIXME: --no-echo, --no-edit, --lines, hercules unsupported. */ + /* NOTE: both terminals are activated so --silent and --timeout + are useless. */ + {"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST, + "[--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] " + "[--silent] [console] [serial] [hercules]", + "Select a terminal. When multiple terminals are specified, wait until" + " you push any key to continue. If both console and serial are specified," + " the terminal to which you input a key first will be selected. If no" + " argument is specified, print current setting. The option --dumb" + " specifies that your terminal is dumb, otherwise, vt100-compatibility" + " is assumed. If you specify --no-echo, input characters won't be echoed." + " If you specify --no-edit, the BASH-like editing feature will be disabled." + " If --timeout is present, this command will wait at most for SECS" + " seconds. The option --lines specifies the maximum number of lines." + " The option --silent is used to suppress messages."}, /* FIXME: terminfo unsupported. */ /* NUL_TERMINATE */ {"testload", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", "Read the entire contents of FILE in several different ways and" @@ -284,7 +301,9 @@ struct legacy_command legacy_commands[] = {"timeout", "set timeout=%s\n", NULL, 0, 1, {TYPE_INT}, 0, "SEC", "Set a timeout, in SEC seconds, before automatically booting the" " default entry (normally the first entry defined)."}, - /* title is handled separately. */ + {"title", NULL, NULL, 0, 0, {}, FLAG_TITLE, "NAME ...", + "Start a new boot entry, and set its name to the contents of the" + " rest of the line, starting with the first non-space character."}, {"unhide", "parttool '%s' hidden-\n", NULL, 0, 1, {TYPE_PARTITION}, 0, "PARTITION", "Unhide PARTITION by clearing the \"hidden\" bit in its" @@ -418,6 +437,7 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) const char *ptr; const char *cmdname; unsigned i, cmdnum; + char *args[ARRAY_SIZE (legacy_commands[0].argt)]; *suffix = NULL; @@ -441,18 +461,6 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) cmdname = ptr; for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); - if (entryname && grub_strncmp ("title", cmdname, ptr - cmdname) == 0 - && ptr - cmdname == sizeof ("title") - 1) - { - const char *ptr2; - for (; grub_isspace (*ptr) || *ptr == '='; ptr++); - ptr2 = ptr + grub_strlen (ptr); - while (ptr2 > ptr && grub_isspace (*(ptr2 - 1))) - ptr2--; - *entryname = grub_strndup (ptr, ptr2 - ptr); - return NULL; - } - for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 && legacy_commands[cmdnum].name[ptr - cmdname] == 0 @@ -466,7 +474,107 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) for (; grub_isspace (*ptr) || *ptr == '='; ptr++); - char *args[ARRAY_SIZE (legacy_commands[0].argt)]; + if (legacy_commands[cmdnum].flags & FLAG_TITLE) + { + const char *ptr2; + ptr2 = ptr + grub_strlen (ptr); + while (ptr2 > ptr && grub_isspace (*(ptr2 - 1))) + ptr2--; + *entryname = grub_strndup (ptr, ptr2 - ptr); + return NULL; + } + + if (legacy_commands[cmdnum].flags & FLAG_TERMINAL) + { + int dumb = 0, no_echo = 0, no_edit = 0, lines = 24; + int console = 0, serial = 0, hercules = 0; + /* Big enough for any possible resulting command. */ + char outbuf[256] = ""; + char *outptr; + while (*ptr) + { + /* "[--timeout=SECS] [--silent]" + " [console] [serial] [hercules]"*/ + if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0) + dumb = 1; + + if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0) + no_echo = 1; + + if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0) + no_edit = 1; + + if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0) + { + lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0); + if (grub_errno) + { + lines = 24; + grub_errno = GRUB_ERR_NONE; + } + } + + if (grub_memcmp (ptr, "console", sizeof ("console") - 1) == 0) + console = 1; + + if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0) + serial = 1; + + if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0) + hercules = 1; + + while (*ptr && !grub_isspace (*ptr)) + ptr++; + while (*ptr && grub_isspace (*ptr)) + ptr++; + } + + if (!console && !serial) + return grub_strdup ("terminal_input; terminal_output; terminfo\n"); + + grub_strcpy (outbuf, "terminal_input "); + outptr = outbuf + grub_strlen (outbuf); + if (serial) + { + grub_strcpy (outptr, "serial "); + outptr += grub_strlen (outptr); + } + if (console) + { + grub_strcpy (outptr, "console "); + outptr += grub_strlen (outptr); + } + grub_strcpy (outptr, "; terminal_output "); + outptr += grub_strlen (outptr); + if (serial) + { + grub_strcpy (outptr, "serial "); + outptr += grub_strlen (outptr); + } + if (console) + { + grub_strcpy (outptr, "console "); + outptr += grub_strlen (outptr); + } + grub_strcpy (outptr, "; "); + outptr += grub_strlen (outptr); + if (serial && dumb) + { + grub_strcpy (outptr, "terminfo serial dumb; "); + outptr += grub_strlen (outptr); + } + + if (serial && !dumb) + { + grub_strcpy (outptr, "terminfo serial vt100; "); + outptr += grub_strlen (outptr); + } + + grub_strcpy (outptr, "\n"); + + return grub_strdup (outbuf); + } + grub_memset (args, 0, sizeof (args)); { From 943682b44c6e656efb3fd6d76d11e0c2906f4035 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 13:55:49 +0100 Subject: [PATCH 0216/1414] * Makefile.am (SUBDIRS): Restore "."; it's important to force ordering, so that e.g. ascii.h is built before grub-core/font/font.c when needed. --- ChangeLog | 6 ++++++ Makefile.am | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dd0d172ed..c9e62f500 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-20 Colin Watson + + * Makefile.am (SUBDIRS): Restore "."; it's important to force + ordering, so that e.g. ascii.h is built before grub-core/font/font.c + when needed. + 2010-09-20 Colin Watson * grub-core/commands/efi/lsefisystab.c: Correct header. diff --git a/Makefile.am b/Makefile.am index 46275e175..931ea02e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects DEPDIR = .deps-util -SUBDIRS = grub-core/gnulib grub-core po docs util/bash-completion.d +SUBDIRS = grub-core/gnulib . grub-core po docs util/bash-completion.d include $(top_srcdir)/conf/Makefile.common include $(top_srcdir)/conf/Makefile.extra-dist From 61c874c51cc1b26fcb2973af29bc96e67b78ff4a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 14:03:47 +0100 Subject: [PATCH 0217/1414] * .bzrignore: Add grub-core/gnulib/sys, widthspec.bin, and widthspec.h. * docs/grub.texi (Shell-like scripting): Document `!'. (Network): Simplify using new i386-pc-pxe format. Mention grub-mknetdir. * NEWS: Update. --- .bzrignore | 3 +++ ChangeLog | 11 +++++++++++ NEWS | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- docs/grub.texi | 10 +++++++--- 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/.bzrignore b/.bzrignore index 3c1e294f5..06dd94341 100644 --- a/.bzrignore +++ b/.bzrignore @@ -125,7 +125,10 @@ grub-core/gnulib/stdio.h grub-core/gnulib/stdlib.h grub-core/gnulib/string.h grub-core/gnulib/strings.h +grub-core/gnulib/sys grub-core/gnulib/unistd.h grub-core/gnulib/warn-on-use.h grub-core/gnulib/wchar.h grub-core/gnulib/wctype.h +widthspec.bin +widthspec.h diff --git a/ChangeLog b/ChangeLog index c9e62f500..4688c5014 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-09-20 Colin Watson + + * .bzrignore: Add grub-core/gnulib/sys, widthspec.bin, and + widthspec.h. + + * docs/grub.texi (Shell-like scripting): Document `!'. + (Network): Simplify using new i386-pc-pxe format. Mention + grub-mknetdir. + + * NEWS: Update. + 2010-09-20 Colin Watson * Makefile.am (SUBDIRS): Restore "."; it's important to force diff --git a/NEWS b/NEWS index bb6b8df3f..b8cec570e 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,47 @@ New in 1.99: +* Keyboard layouts support. + +* New `lsapm' command (i386-pc only). + +* Parser for GRUB Legacy configuration files. + +* Support RAID on virtio devices. + +* Remove deprecated `root' command. + +* New `euro.pf2' font which supports most European languages. + +* Avoid opening the same device twice on Open Firmware platforms. + +* Extend `vbeinfo' and `vbetest' commands to non-VBE graphics, as + `videoinfo' and `videotest'. + +* New `lsefisystab' and `lssal' commands on EFI platforms. + +* Support explicit user claim that a device is BIOS-visible. Devices + listed in device.map will be assumed to be readable using only BIOS + facilities, rather than anything more complex such as LVM or RAID. + +* New bash-completion script for GRUB utilities. + +* Use ACPI to shut down if possible. + +* New `lsacpi' command. + +* Basic btrfs support (detection and UUID). + +* New `--boot-directory' option to `grub-install', `grub-reboot', and + `grub-set-default', with clearer semantics than the previous + `--root-directory' option. + +* Rename CD-ROM device to "cd" on BIOS platforms. + +* Transparent decompression filters. + +* Simpler PXE image generation. New `grub-mknetdir' utility to generate + netboot directory trees. + * New relocator. Allows for more kernel support and more straightforward loader writing. @@ -60,7 +102,8 @@ New in 1.99: * `grub-mkrescue' support for EFI, coreboot, and QEMU platforms. -* Unify `grub-mkimage' source code across platforms. +* Unify `grub-mkimage', `grub-setup', and `grub-install' source code + across platforms. * Fix VGA (as opposed to VBE) video driver, formerly a terminal driver. @@ -83,8 +126,9 @@ New in 1.99: * sunpc partition table support. * Add a number of new language features to GRUB script: `for', `while', - `until', `elif', function parameters, `break', `continue', and - `shift'. + `until', `elif', function parameters, `break', `continue', `shift', + multi-line quoted strings, positional parameters with `setparams', + `return', filename wildcard expansion, and `!'. * Support nested partition tables. GRUB now prefers to name partitions in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'. diff --git a/docs/grub.texi b/docs/grub.texi index 076adfd6c..3a72bbacb 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1264,7 +1264,9 @@ and terminated by a semicolon or a newline. The first word specifies the command to be executed. The remaining words are passed as arguments to the invoked command. -The return value of a simple command is its exit status. +The return value of a simple command is its exit status. If the reserved +word @code{!} precedes the command, then the return value is instead the +logical negation of the command's exit status. @heading Compound commands @@ -1796,8 +1798,7 @@ To generate a PXE boot image, run: @example @group -grub-mkimage --format=i386-pc --output=core.img --prefix='(pxe)/boot/grub' pxe pxecmd -cat /boot/grub/pxeboot.img core.img >grub.pxe +grub-mkimage --format=i386-pc-pxe --output=grub.pxe --prefix='(pxe)/boot/grub' pxe pxecmd @end group @end example @@ -1807,6 +1808,9 @@ accessible via the @file{/boot/grub/} path from the TFTP server root. Set the DHCP server configuration to offer @file{grub.pxe} as the boot file (the @samp{filename} option in ISC dhcpd). +You can also use the @command{grub-mknetdir} utility to generate an image +and a GRUB directory tree, rather than copying files around manually. + After GRUB has started, files on the TFTP server will be accessible via the @samp{(pxe)} device. From 41e9c57d89229ee5658f6883d914c57439ca6ad3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 16:12:15 +0200 Subject: [PATCH 0218/1414] * grub-core/lib/arg.c (grub_arg_show_help): Correctly handle parameters overflow. --- ChangeLog | 5 +++++ grub-core/lib/arg.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4688c5014..875edec38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-20 Vladimir Serbinenko + + * grub-core/lib/arg.c (grub_arg_show_help): Correctly handle + parameters overflow. + 2010-09-20 Colin Watson * .bzrignore: Add grub-core/gnulib/sys, widthspec.bin, and diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c index f487de7ad..dabf4e8ce 100644 --- a/grub-core/lib/arg.c +++ b/grub-core/lib/arg.c @@ -144,6 +144,9 @@ grub_arg_show_help (grub_extcmd_t cmd) } } + if (spacing < 0) + spacing = 3; + while (spacing--) grub_xputs (" "); From a9cc5438a5d31eb9de461353a031c56e6b31b7f2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 16:27:33 +0200 Subject: [PATCH 0219/1414] Suport manual terminal geometry specification. * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Save state in grub_ofconsole_terminfo_output. (grub_ofconsole_term): Use grub_terminfo_getwh. (grub_ofconsole_getwh): Removed. * grub-core/term/serial.c (grub_serial_getwh): Removed. (grub_serial_term): Use grub_terminfo_getwh. * grub-core/term/terminfo.c (grub_terminfo_getwh): New function. (options): New struct. (OPTION_*): New enum. (grub_cmd_terminfo): Transform into extcmd and handle new parameters. * include/grub/terminfo.h (grub_terminfo_output_state): New fields width and height. (grub_terminfo_getwh): New proto. * grub-core/lib/legacy_parse.c (grub_legacy_parse): Handle --lines. --- ChangeLog | 19 +++++ grub-core/lib/legacy_parse.c | 16 ++-- grub-core/term/ieee1275/ofconsole.c | 29 +++---- grub-core/term/serial.c | 14 +--- grub-core/term/terminfo.c | 126 ++++++++++++++++------------ include/grub/terminfo.h | 4 + 6 files changed, 119 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc95c5296..301f32d48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-09-20 Vladimir Serbinenko + + Suport manual terminal geometry specification. + + * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): + Save state in grub_ofconsole_terminfo_output. + (grub_ofconsole_term): Use grub_terminfo_getwh. + (grub_ofconsole_getwh): Removed. + * grub-core/term/serial.c (grub_serial_getwh): Removed. + (grub_serial_term): Use grub_terminfo_getwh. + * grub-core/term/terminfo.c (grub_terminfo_getwh): New function. + (options): New struct. + (OPTION_*): New enum. + (grub_cmd_terminfo): Transform into extcmd and handle new parameters. + * include/grub/terminfo.h (grub_terminfo_output_state): New fields + width and height. + (grub_terminfo_getwh): New proto. + * grub-core/lib/legacy_parse.c (grub_legacy_parse): Handle --lines. + 2010-09-20 Vladimir Serbinenko Handle legacy "terminal" command. diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 09905bd42..ae27048a2 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -273,7 +273,7 @@ struct legacy_command legacy_commands[] = " default values are COM1, 9600, 8N1."}, /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ /* NOTE: setup unsupported. */ - /* FIXME: --no-echo, --no-edit, --lines, hercules unsupported. */ + /* FIXME: --no-echo, --no-edit, hercules unsupported. */ /* NOTE: both terminals are activated so --silent and --timeout are useless. */ {"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST, @@ -558,20 +558,16 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) } grub_strcpy (outptr, "; "); outptr += grub_strlen (outptr); - if (serial && dumb) + if (serial) { - grub_strcpy (outptr, "terminfo serial dumb; "); - outptr += grub_strlen (outptr); - } - - if (serial && !dumb) - { - grub_strcpy (outptr, "terminfo serial vt100; "); + grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr, + "terminfo serial -g 80x%d %s; ", + lines, dumb ? "dumb" : "vt100"); outptr += grub_strlen (outptr); } grub_strcpy (outptr, "\n"); - + return grub_strdup (outbuf); } diff --git a/grub-core/term/ieee1275/ofconsole.c b/grub-core/term/ieee1275/ofconsole.c index 226b78b71..944056ba6 100644 --- a/grub-core/term/ieee1275/ofconsole.c +++ b/grub-core/term/ieee1275/ofconsole.c @@ -29,8 +29,7 @@ static grub_ieee1275_ihandle_t stdout_ihandle; static grub_ieee1275_ihandle_t stdin_ihandle; -static grub_uint8_t grub_ofconsole_width; -static grub_uint8_t grub_ofconsole_height; +extern struct grub_terminfo_output_state grub_ofconsole_terminfo_output; struct color { @@ -91,7 +90,8 @@ grub_ofconsole_dimensions (void) if (! grub_ieee1275_get_property (options, "screen-#columns", val, lval, 0)) - grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10); + grub_ofconsole_terminfo_output->width + = (grub_uint8_t) grub_strtoul (val, 0, 10); } if (! grub_ieee1275_get_property_length (options, "screen-#rows", &lval) && lval >= 0 && lval < 1024) @@ -99,21 +99,16 @@ grub_ofconsole_dimensions (void) char val[lval]; if (! grub_ieee1275_get_property (options, "screen-#rows", val, lval, 0)) - grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10); + grub_ofconsole_terminfo_output->height + = (grub_uint8_t) grub_strtoul (val, 0, 10); } } /* Use a small console by default. */ - if (! grub_ofconsole_width) - grub_ofconsole_width = 80; - if (! grub_ofconsole_height) - grub_ofconsole_height = 24; -} - -static grub_uint16_t -grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused))) -{ - return (grub_ofconsole_width << 8) | grub_ofconsole_height; + if (! grub_ofconsole_terminfo_output->width) + grub_ofconsole_terminfo_output->width = 80; + if (! grub_ofconsole_terminfo_output->height) + grub_ofconsole_terminfo_output->height = 24; } static void @@ -187,7 +182,9 @@ struct grub_terminfo_input_state grub_ofconsole_terminfo_input = struct grub_terminfo_output_state grub_ofconsole_terminfo_output = { - .put = put + .put = put, + .width = 80, + .height = 24 }; static struct grub_term_input grub_ofconsole_term_input = @@ -204,7 +201,7 @@ static struct grub_term_output grub_ofconsole_term_output = .init = grub_ofconsole_init_output, .putchar = grub_terminfo_putchar, .getxy = grub_terminfo_getxy, - .getwh = grub_ofconsole_getwh, + .getwh = grub_terminfo_getwh, .gotoxy = grub_terminfo_gotoxy, .cls = grub_terminfo_cls, .setcolorstate = grub_terminfo_setcolorstate, diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index e318e4b43..1ef17aa25 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -55,14 +55,6 @@ struct grub_serial_input_state struct grub_serial_port *port; }; -static grub_uint16_t -grub_serial_getwh (struct grub_term_output *term __attribute__ ((unused))) -{ - const grub_uint8_t TEXT_WIDTH = 80; - const grub_uint8_t TEXT_HEIGHT = 24; - return (TEXT_WIDTH << 8) | TEXT_HEIGHT; -} - static void serial_put (grub_term_output_t term, const int c) { @@ -89,7 +81,9 @@ struct grub_serial_output_state grub_serial_terminfo_output = { .tinfo = { - .put = serial_put + .put = serial_put, + .width = 80, + .height = 24 } }; @@ -107,7 +101,7 @@ static struct grub_term_output grub_serial_term_output = { .name = "serial", .putchar = grub_terminfo_putchar, - .getwh = grub_serial_getwh, + .getwh = grub_terminfo_getwh, .getxy = grub_terminfo_getxy, .gotoxy = grub_terminfo_gotoxy, .cls = grub_terminfo_cls, diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 8dea7aea1..d01811959 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -358,6 +358,15 @@ grub_terminfo_putchar (struct grub_term_output *term, data->put (term, c->base); } +grub_uint16_t +grub_terminfo_getwh (struct grub_term_output *term) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + return (data->width << 8) | data->height; +} + #define ANSI_C0 0x9b static void @@ -537,85 +546,96 @@ print_terminfo (void) return GRUB_ERR_NONE; } +static const struct grub_arg_option options[] = +{ + {"ascii", 'a', 0, N_("Terminal is ASCII-only [default]."), 0, ARG_TYPE_NONE}, + {"utf8", 'u', 0, N_("Terminal is logical-ordered UTF-8."), 0, ARG_TYPE_NONE}, + {"visual-utf8", 'v', 0, N_("Terminal is visually-ordered UTF-8."), 0, + ARG_TYPE_NONE}, + {"geometry", 'g', 0, N_("Terminal has given geometry."), + N_("WIDTHxHEIGHT."), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +enum + { + OPTION_ASCII, + OPTION_UTF8, + OPTION_VISUAL_UTF8, + OPTION_GEOMETRY + }; + static grub_err_t -grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) +grub_cmd_terminfo (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_term_output *cur; int encoding = GRUB_TERM_CODE_TYPE_ASCII; - int i; - char *name = NULL, *type = NULL; + struct grub_arg_list *state = ctxt->state; + int w = 0, h = 0; if (argc == 0) return print_terminfo (); - for (i = 0; i < argc; i++) + if (state[OPTION_ASCII].set) + encoding = GRUB_TERM_CODE_TYPE_ASCII; + + if (state[OPTION_UTF8].set) + encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; + + if (state[OPTION_VISUAL_UTF8].set) + encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL; + + if (state[OPTION_GEOMETRY].set) { - if (grub_strcmp (args[i], "-a") == 0 - || grub_strcmp (args[i], "--ascii") == 0) - { - encoding = GRUB_TERM_CODE_TYPE_ASCII; - continue; - } - if (grub_strcmp (args[i], "-u") == 0 - || grub_strcmp (args[i], "--utf8") == 0) - { - encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; - continue; - } - if (grub_strcmp (args[i], "-v") == 0 - || grub_strcmp (args[i], "--visual-utf8") == 0) - { - encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL; - continue; - } - if (!name) - { - name = args[i]; - continue; - } - if (!type) - { - type = args[i]; - continue; - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); + char *ptr = state[OPTION_GEOMETRY].arg; + w = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (*ptr != 'x') + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "incorrect geometry specification"); + ptr++; + h = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; } - if (name == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters"); - for (cur = terminfo_outputs; cur; cur = ((struct grub_terminfo_output_state *) cur->data)->next) - if (grub_strcmp (name, cur->name) == 0) + if (grub_strcmp (args[0], cur->name) == 0) { cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding; - if (!type) + + if (w && h) + { + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) cur->data; + data->width = w; + data->height = h; + } + + if (argc == 1) return GRUB_ERR_NONE; - return grub_terminfo_set_current (cur, type); + return grub_terminfo_set_current (cur, args[1]); } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no terminal %s found or it's not handled by terminfo", - name); + args[0]); } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(terminfo) { - cmd = grub_register_command ("terminfo", grub_cmd_terminfo, - N_("[[-a|-u|-v] TERM [TYPE]]"), - N_("Set terminfo type of TERM to TYPE.\n" - "-a, --ascii Terminal is ASCII-only [default].\n" - "-u, --utf8 Terminal is logical-ordered UTF-8.\n" - "-v, --visual-utf8 Terminal is visually-ordered UTF-8.") - - ); + cmd = grub_register_extcmd ("terminfo", grub_cmd_terminfo, 0, + N_("[[-a|-u|-v] [-g WxH] TERM [TYPE]]"), + N_("Set terminfo type of TERM to TYPE.\n"), + options); } GRUB_MOD_FINI(terminfo) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 1962c71b7..8317995d8 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -49,6 +49,8 @@ struct grub_terminfo_output_state char *cursor_off; char *setcolor; + unsigned int width, height; + unsigned int xpos, ypos; void (*put) (struct grub_term_output *term, const int c); @@ -68,6 +70,8 @@ grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term) int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term); void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term, const struct grub_unicode_glyph *c); +grub_uint16_t EXPORT_FUNC (grub_terminfo_getwh) (struct grub_term_output *term); + grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term, const char *type); From 38c259a76a6c40f5d2983c8e542edd79ea08e4d8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 17:46:35 +0200 Subject: [PATCH 0220/1414] Pause the execution (10s max) if any errors are displayed so the user has a chance to see them. * grub-core/kern/err.c (grub_err_printed_errors): New variable. (grub_print_error): Increment grub_err_printed_errors. * grub-core/normal/menu.c (grub_menu_execute_entry): Pause the execution if any errors were displayed. (show_menu): Remove old code for pause. * grub-core/normal/menu_entry.c (run): Likewise. * grub-core/normal/term.c (grub_normal_char_counter): Removed. All users updated. (grub_normal_get_char_counter): Likewise. * include/grub/err.h (grub_err_printed_errors): New external variable. * include/grub/normal.h (grub_normal_get_char_counter): Removed. --- ChangeLog | 17 +++++++++++++++++ grub-core/kern/err.c | 6 +++++- grub-core/normal/menu.c | 21 ++++++++------------- grub-core/normal/menu_entry.c | 13 ++++++------- grub-core/normal/term.c | 10 ---------- include/grub/err.h | 1 + include/grub/normal.h | 1 - 7 files changed, 37 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d503edf1..3b70597a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2010-09-20 Vladimir Serbinenko + + Pause the execution (10s max) if any errors are displayed so the user + has a chance to see them. + + * grub-core/kern/err.c (grub_err_printed_errors): New variable. + (grub_print_error): Increment grub_err_printed_errors. + * grub-core/normal/menu.c (grub_menu_execute_entry): Pause the + execution if any errors were displayed. + (show_menu): Remove old code for pause. + * grub-core/normal/menu_entry.c (run): Likewise. + * grub-core/normal/term.c (grub_normal_char_counter): Removed. All + users updated. + (grub_normal_get_char_counter): Likewise. + * include/grub/err.h (grub_err_printed_errors): New external variable. + * include/grub/normal.h (grub_normal_get_char_counter): Removed. + 2010-09-20 Vladimir Serbinenko Support multiboot VBE info. diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c index 8272467f5..74f3915aa 100644 --- a/grub-core/kern/err.c +++ b/grub-core/kern/err.c @@ -27,6 +27,7 @@ grub_err_t grub_errno; char grub_errmsg[GRUB_MAX_ERRMSG]; +int grub_err_printed_errors; static struct { @@ -122,7 +123,10 @@ grub_print_error (void) do { if (grub_errno != GRUB_ERR_NONE) - grub_err_printf (_("error: %s.\n"), grub_errmsg); + { + grub_err_printf (_("error: %s.\n"), grub_errmsg); + grub_err_printed_errors++; + } } while (grub_error_pop ()); diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 62b0d0a6a..9c0a2182f 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -158,6 +158,7 @@ void grub_menu_execute_entry(grub_menu_entry_t entry) { grub_err_t err = GRUB_ERR_NONE; + int errs_before; if (entry->restricted) err = grub_auth_check_authentication (entry->users); @@ -169,9 +170,14 @@ grub_menu_execute_entry(grub_menu_entry_t entry) return; } + errs_before = grub_err_printed_errors; + grub_env_set ("chosen", entry->title); grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args); + if (errs_before != grub_err_printed_errors) + grub_wait_after_message (); + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) /* Implicit execution of boot, only if something is loaded. */ grub_command_execute ("boot", 0, 0); @@ -583,20 +589,9 @@ show_menu (grub_menu_t menu, int nested) grub_cls (); if (auto_boot) - { - grub_menu_execute_with_fallback (menu, e, &execution_callback, 0); - } + grub_menu_execute_with_fallback (menu, e, &execution_callback, 0); else - { - int chars_before = grub_normal_get_char_counter (); - grub_errno = GRUB_ERR_NONE; - grub_menu_execute_entry (e); - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - - if (chars_before != grub_normal_get_char_counter ()) - grub_wait_after_message (); - } + grub_menu_execute_entry (e); } return GRUB_ERR_NONE; diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 87292d445..82506fa6f 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1161,6 +1161,7 @@ run (struct screen *screen) { int currline = 0; char *nextline; + int errs_before; auto grub_err_t editor_getline (char **line, int cont); grub_err_t editor_getline (char **line, int cont __attribute__ ((unused))) @@ -1194,6 +1195,7 @@ run (struct screen *screen) grub_printf_ (N_("Booting a command list")); grub_printf ("\n\n"); + errs_before = grub_err_printed_errors; /* Execute the script, line for line. */ while (currline < screen->num_lines) @@ -1203,6 +1205,9 @@ run (struct screen *screen) break; } + if (errs_before != grub_err_printed_errors) + grub_wait_after_message (); + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) /* Implicit execution of boot, only if something is loaded. */ grub_command_execute ("boot", 0, 0); @@ -1382,13 +1387,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) case GRUB_TERM_CTRL | 'x': case GRUB_TERM_KEY_F10: - { - int chars_before = grub_normal_get_char_counter (); - run (screen); - - if (chars_before != grub_normal_get_char_counter ()) - grub_wait_after_message (); - } + run (screen); goto refresh; case GRUB_TERM_CTRL | 'r': diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index 760900e86..fe6240eb0 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -42,17 +42,9 @@ static struct term_state *term_states = NULL; /* If the more pager is active. */ static int grub_more; -static int grub_normal_char_counter = 0; - static void putcode_real (grub_uint32_t code, struct grub_term_output *term); -int -grub_normal_get_char_counter (void) -{ - return grub_normal_char_counter; -} - void grub_normal_reset_more (void) { @@ -409,8 +401,6 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term) .estimated_width = 1 }; - grub_normal_char_counter++; - if (c->base == '\t' && term->getxy) { int n; diff --git a/include/grub/err.h b/include/grub/err.h index d35bba474..e532e19e2 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -66,6 +66,7 @@ void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_error_push) (void); int EXPORT_FUNC(grub_error_pop) (void); void EXPORT_FUNC(grub_print_error) (void); +extern int EXPORT_VAR(grub_err_printed_errors); int grub_err_printf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/include/grub/normal.h b/include/grub/normal.h index 72912e524..a3827f584 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -110,7 +110,6 @@ void read_terminal_list (const char *prefix); void grub_set_more (int onoff); -int grub_normal_get_char_counter (void); void grub_normal_reset_more (void); void grub_xputs_normal (const char *str); From 3286a4b4c27c24a3199ded058789ff289ef0ff9b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 18:38:38 +0200 Subject: [PATCH 0221/1414] Use argp in grub-fstest. * util/grub-fstest.c: Don't include getopt.h. Include argp.h. (root): New variable. (args_count): Likewise. (nparm): Likewise. (num_disks): Likewise. (images): Likewise. (cmd): Likewise. (debug_str): Likewise. (args): Likewise. (options): Transformed to argp. (usage): Removed. (main): Split argument parsing into ... (argp_parser): ... this. Changed to argp format. (argp): New variable. (main): Use argp_parse. --- ChangeLog | 21 +++ util/grub-fstest.c | 316 +++++++++++++++++++++------------------------ 2 files changed, 170 insertions(+), 167 deletions(-) diff --git a/ChangeLog b/ChangeLog index 041633925..6adf6142a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-09-20 Vladimir Serbinenko + + Use argp in grub-fstest. + + * util/grub-fstest.c: Don't include getopt.h. + Include argp.h. + (root): New variable. + (args_count): Likewise. + (nparm): Likewise. + (num_disks): Likewise. + (images): Likewise. + (cmd): Likewise. + (debug_str): Likewise. + (args): Likewise. + (options): Transformed to argp. + (usage): Removed. + (main): Split argument parsing into ... + (argp_parser): ... this. Changed to argp format. + (argp): New variable. + (main): Use argp_parse. + 2010-09-20 Tristan Gingold 2010-09-20 Robert Millan 2010-09-20 Vladimir Serbinenko diff --git a/util/grub-fstest.c b/util/grub-fstest.c index bcc9ea942..72485679f 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -38,9 +38,9 @@ #include #include #include -#include #include "progname.h" +#include "argp.h" static grub_err_t execute_command (char *name, int n, char **args) @@ -49,7 +49,7 @@ execute_command (char *name, int n, char **args) cmd = grub_command_find (name); if (! cmd) - grub_util_error ("can\'t find command %s", name); + grub_util_error (_("can\'t find command %s"), name); return (cmd->func) (cmd, n, args); } @@ -78,7 +78,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) dev = grub_device_open (0); if ((! dev) || (! dev->disk)) - grub_util_error ("can\'t open device"); + grub_util_error (_("can\'t open device")); grub_util_info ("total sectors : %lld", (unsigned long long) dev->disk->total_sectors); @@ -93,7 +93,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) len = (leng > BUF_SIZE) ? BUF_SIZE : leng; if (grub_disk_read (dev->disk, 0, skip, len, buf)) - grub_util_error ("disk read fails at offset %lld, length %d", + grub_util_error (_("disk read fails at offset %lld, length %d"), skip, len); if (hook (skip, buf, len)) @@ -111,7 +111,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) file = grub_file_open (pathname); if (!file) { - grub_util_error ("cannot open file %s", pathname); + grub_util_error (_("cannot open file %s"), pathname); return; } @@ -119,7 +119,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) if (skip > file->size) { - grub_util_error ("invalid skip value %lld", (unsigned long long) skip); + grub_util_error (_("invalid skip value %lld"), (unsigned long long) skip); return; } @@ -137,7 +137,8 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len); if (sz < 0) { - grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg); + grub_util_error (_("read error at offset %llu: %s"), ofs, + grub_errmsg); break; } @@ -163,7 +164,7 @@ cmd_cp (char *src, char *dest) if ((int) fwrite (buf, 1, len, ff) != len) { - grub_util_error ("write error"); + grub_util_error (_("write error")); return 1; } @@ -173,7 +174,7 @@ cmd_cp (char *src, char *dest) ff = fopen (dest, "wb"); if (ff == NULL) { - grub_util_error ("open error"); + grub_util_error (_("open error")); return; } read_file (src, cp_hook); @@ -191,7 +192,7 @@ cmd_cmp (char *src, char *dest) { if ((int) fread (buf_1, 1, len, ff) != len) { - grub_util_error ("read error at offset %llu: %s", ofs, grub_errmsg); + grub_util_error (_("read error at offset %llu: %s"), ofs, grub_errmsg); return 1; } @@ -202,7 +203,7 @@ cmd_cmp (char *src, char *dest) for (i = 0; i < len; i++, ofs++) if (buf_1[i] != buf[i]) { - grub_util_error ("compare fail at offset %llu", ofs); + grub_util_error (_("compare fail at offset %llu"), ofs); return 1; } } @@ -212,12 +213,12 @@ cmd_cmp (char *src, char *dest) ff = fopen (dest, "rb"); if (ff == NULL) { - grub_util_error ("open error"); + grub_util_error (_("open error")); return; } if ((skip) && (fseeko (ff, skip, SEEK_SET))) - grub_util_error ("seek error"); + grub_util_error (_("seek error")); read_file (src, cmp_hook); fclose (ff); @@ -257,8 +258,17 @@ cmd_crc (char *pathname) grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context))); } +static char *root = NULL; +static int args_count = 0; +static int nparm = 0; +static int num_disks = 1; +static char **images = NULL; +static int cmd = 0; +static char *debug_str = NULL; +static char **args = NULL; + static void -fstest (char **images, int num_disks, int cmd, int n, char **args) +fstest (int n, char **args) { char *host_file; char *loop_name; @@ -279,7 +289,7 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) argv[1] = host_file; if (execute_command ("loopback", 2, argv)) - grub_util_error ("loopback command fails"); + grub_util_error (_("loopback command fails")); grub_free (loop_name); grub_free (host_file); @@ -331,203 +341,175 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) } } -static struct option options[] = { - {"root", required_argument, 0, 'r'}, - {"skip", required_argument, 0, 's'}, - {"length", required_argument, 0, 'n'}, - {"diskcount", required_argument, 0, 'c'}, - {"debug", required_argument, 0, 'd'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} +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_("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}, + {N_("blocklist FILE"), 0, 0, OPTION_DOC, N_("Display blocklist of FILE."), 1}, + + {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, + {"skip", 's', "N", 0, N_("Skip N bytes from output file."), 2}, + {"length", 'n', "N", 0, N_("Handle N bytes in output file."), 2}, + {"diskcount", 'c', "N", 0, N_("N input files."), 2}, + {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, + {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, + {0, 0, 0, 0, 0, 0} }; +/* Print the version information. */ static void -usage (int status) +print_version (FILE *stream, struct argp_state *state) { - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s [OPTION]... IMAGE_PATH COMMANDS\n\ -\n\ -Debug tool for filesystem driver.\n\ -\nCommands:\n\ - ls PATH list files in PATH\n\ - cp FILE LOCAL copy FILE to local file LOCAL\n\ - cmp FILE LOCAL compare FILE with local file LOCAL\n\ - hex FILE Hex dump FILE\n\ - crc FILE Get crc32 checksum of FILE\n\ - blocklist FILE display blocklist of FILE\n\ -\nOptions:\n\ - -r, --root=DEVICE_NAME set root device\n\ - -s, --skip=N skip N bytes from output file\n\ - -n, --length=N handle N bytes in output file\n\ - -c, --diskcount=N N input files\n\ - -d, --debug=S Set debug environment variable\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); - - exit (status); + fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); } +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; -int -main (int argc, char *argv[]) +error_t +argp_parser (int key, char *arg, struct argp_state *state) { - char *debug_str = NULL, *root = NULL, *default_root, *alloc_root; - int i, cmd, num_opts, image_index, num_disks = 1; + char *p; - set_program_name (argv[0]); + switch (key) + { + case 'r': + root = arg; + return 0; - grub_util_init_nls (); + case 's': + skip = grub_strtoul (arg, &p, 0); + if (*p == 's') + skip <<= GRUB_DISK_SECTOR_BITS; + return 0; - /* Find the first non option entry. */ - for (num_opts = 1; num_opts < argc; num_opts++) - if (argv[num_opts][0] == '-') - { - if ((argv[num_opts][2] == 0) && (num_opts < argc - 1) && - ((argv[num_opts][1] == 'r') || - (argv[num_opts][1] == 's') || - (argv[num_opts][1] == 'n') || - (argv[num_opts][1] == 'c') || - (argv[num_opts][1] == 'd'))) - num_opts++; - } - else + case 'n': + leng = grub_strtoul (arg, &p, 0); + if (*p == 's') + leng <<= GRUB_DISK_SECTOR_BITS; + return 0; + + case 'c': + num_disks = grub_strtoul (arg, NULL, 0); + if (num_disks < 1) + { + fprintf (stderr, _("Invalid disk count.\n")); + argp_usage (state); + } + if (args_count != 0) + { + fprintf (stderr, _("Disk count must precede disks list.\n")); + argp_usage (state); + } + return 0; + + case 'd': + debug_str = arg; + return 0; + + case 'v': + verbosity++; + return 0; + + case ARGP_KEY_END: + if (args_count < num_disks) + { + fprintf (stderr, _("No command is specified.\n")); + argp_usage (state); + } + if (args_count - 1 - num_disks < nparm) + { + fprintf (stderr, _("Not enough parameters to command.\n")); + argp_usage (state); + } + return 0; + + case ARGP_KEY_ARG: break; - /* Check for options. */ - while (1) - { - int c = getopt_long (num_opts, argv, "r:s:n:c:d:hVv", options, 0); - char *p; - - if (c == -1) - break; - else - switch (c) - { - case 'r': - root = optarg; - break; - - case 's': - skip = grub_strtoul (optarg, &p, 0); - if (*p == 's') - skip <<= GRUB_DISK_SECTOR_BITS; - break; - - case 'n': - leng = grub_strtoul (optarg, &p, 0); - if (*p == 's') - leng <<= GRUB_DISK_SECTOR_BITS; - break; - - case 'c': - num_disks = grub_strtoul (optarg, NULL, 0); - if (num_disks < 1) - { - fprintf (stderr, "Invalid disk count.\n"); - usage (1); - } - break; - - case 'd': - debug_str = optarg; - break; - - case 'h': - usage (0); - break; - - case 'V': - printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); - return 0; - - case 'v': - verbosity++; - break; - - default: - usage (1); - break; - } + default: + return ARGP_ERR_UNKNOWN; } - /* Obtain PATH. */ - if (optind + num_disks - 1 >= argc) + if (args_count < num_disks) { - fprintf (stderr, "Not enough pathname.\n"); - usage (1); + if (arg[0] != '/') + { + fprintf (stderr, _("Must use absolute path.\n")); + argp_usage (state); + } + if (args_count == 0) + images = xmalloc (num_disks * sizeof (images[0])); + images[args_count] = xstrdup (arg); + args_count++; + return 0; } - image_index = optind; - for (i = 0; i < num_disks; i++, optind++) - if (argv[optind][0] != '/') - { - fprintf (stderr, "Must use absolute path.\n"); - usage (1); - } - - cmd = 0; - if (optind < argc) + if (args_count == num_disks) { - int nparm = 0; - - if (!grub_strcmp (argv[optind], "ls")) + if (!grub_strcmp (arg, "ls")) { cmd = CMD_LS; } - else if (!grub_strcmp (argv[optind], "cp")) + else if (!grub_strcmp (arg, "cp")) { cmd = CMD_CP; nparm = 2; } - else if (!grub_strcmp (argv[optind], "cmp")) + else if (!grub_strcmp (arg, "cmp")) { cmd = CMD_CMP; nparm = 2; } - else if (!grub_strcmp (argv[optind], "hex")) + else if (!grub_strcmp (arg, "hex")) { cmd = CMD_HEX; nparm = 1; } - else if (!grub_strcmp (argv[optind], "crc")) + else if (!grub_strcmp (arg, "crc")) { cmd = CMD_CRC; nparm = 1; } - else if (!grub_strcmp (argv[optind], "blocklist")) + else if (!grub_strcmp (arg, "blocklist")) { cmd = CMD_BLOCKLIST; nparm = 1; } else { - fprintf (stderr, "Invalid command %s.\n", argv[optind]); - usage (1); + fprintf (stderr, _("Invalid command %s.\n"), arg); + argp_usage (state); } - - if (optind + 1 + nparm > argc) - { - fprintf (stderr, "Invalid parameter for command %s.\n", - argv[optind]); - usage (1); - } - - optind++; - } - else - { - fprintf (stderr, "No command is specified.\n"); - usage (1); + args_count++; + return 0; } + args[args_count - 1 - num_disks] = xstrdup (arg); + args_count++; + return 0; +} + +struct argp argp = { + options, argp_parser, N_("IMAGE_PATH COMMANDS"), + N_("Debug tool for filesystem driver."), + NULL, NULL, NULL +}; + +int +main (int argc, char *argv[]) +{ + char *default_root, *alloc_root; + + set_program_name (argv[0]); + + grub_util_init_nls (); + + args = xmalloc (argc * sizeof (args[0])); + + argp_parse (&argp, argc, argv, 0, 0, 0); + /* Initialize all modules. */ grub_init_all (); @@ -555,7 +537,7 @@ main (int argc, char *argv[]) free (alloc_root); /* Do it. */ - fstest (argv + image_index, num_disks, cmd, argc - optind, argv + optind); + fstest (args_count - 1 - num_disks, args); /* Free resources. */ grub_fini_all (); From dfe3b247a2be2566b4a0c97caec59acc293fee8e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 17:56:14 +0100 Subject: [PATCH 0222/1414] * util/grub-editenv.c (argp_parser): Don't pass translated strings as printf format strings; the translations might contain '%' which could cause a crash. (main): Likewise. * util/grub-fstest.c (argp_parser): Likewise. * util/grub-setup.c (argp_parser): Likewise. (main): Likewise. --- ChangeLog | 10 ++++++++++ util/grub-editenv.c | 5 +++-- util/grub-fstest.c | 10 +++++----- util/grub-setup.c | 4 ++-- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6adf6142a..e20e2b654 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-09-20 Colin Watson + + * util/grub-editenv.c (argp_parser): Don't pass translated strings + as printf format strings; the translations might contain '%' which + could cause a crash. + (main): Likewise. + * util/grub-fstest.c (argp_parser): Likewise. + * util/grub-setup.c (argp_parser): Likewise. + (main): Likewise. + 2010-09-20 Vladimir Serbinenko Use argp in grub-fstest. diff --git a/util/grub-editenv.c b/util/grub-editenv.c index 3ea026cfe..bfda7c3d8 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -72,7 +72,8 @@ error_t argp_parser (int key, char *arg, struct argp_state *state) break; case ARGP_KEY_NO_ARGS: - fprintf (stderr, _("You need to specify at least one command.\n")); + fprintf (stderr, "%s", + _("You need to specify at least one command.\n")); argp_usage (state); break; @@ -272,7 +273,7 @@ main (int argc, char *argv[]) /* Parse our arguments */ if (argp_parse (&argp, argc, argv, 0, &index, 0) != 0) { - fprintf (stderr, _("Error in parsing command line arguments\n")); + fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); exit(1); } diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 72485679f..aedb2954a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -394,12 +394,12 @@ argp_parser (int key, char *arg, struct argp_state *state) num_disks = grub_strtoul (arg, NULL, 0); if (num_disks < 1) { - fprintf (stderr, _("Invalid disk count.\n")); + fprintf (stderr, "%s", _("Invalid disk count.\n")); argp_usage (state); } if (args_count != 0) { - fprintf (stderr, _("Disk count must precede disks list.\n")); + fprintf (stderr, "%s", _("Disk count must precede disks list.\n")); argp_usage (state); } return 0; @@ -415,12 +415,12 @@ argp_parser (int key, char *arg, struct argp_state *state) case ARGP_KEY_END: if (args_count < num_disks) { - fprintf (stderr, _("No command is specified.\n")); + fprintf (stderr, "%s", _("No command is specified.\n")); argp_usage (state); } if (args_count - 1 - num_disks < nparm) { - fprintf (stderr, _("Not enough parameters to command.\n")); + fprintf (stderr, "%s", _("Not enough parameters to command.\n")); argp_usage (state); } return 0; @@ -436,7 +436,7 @@ argp_parser (int key, char *arg, struct argp_state *state) { if (arg[0] != '/') { - fprintf (stderr, _("Must use absolute path.\n")); + fprintf (stderr, "%s", _("Must use absolute path.\n")); argp_usage (state); } if (args_count == 0) diff --git a/util/grub-setup.c b/util/grub-setup.c index 90a4b2ac2..05355bf43 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -778,7 +778,7 @@ argp_parser (int key, char *arg, struct argp_state *state) break; case ARGP_KEY_NO_ARGS: - fprintf (stderr, _("No device is specified.\n")); + fprintf (stderr, "%s", _("No device is specified.\n")); argp_usage (state); break; @@ -835,7 +835,7 @@ main (int argc, char *argv[]) /* Parse our arguments */ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) { - fprintf (stderr, _("Error in parsing command line arguments\n")); + fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); exit(1); } From 40901acd7649dbbc47824577a3b8df77c7b96a43 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 20 Sep 2010 17:59:09 +0100 Subject: [PATCH 0223/1414] * grub-core/commands/efi/lsefimmap.c: Correct header. * NEWS: Update. --- ChangeLog | 5 +++++ NEWS | 2 +- grub-core/commands/efi/lsefimmap.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e20e2b654..ae98382fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-20 Colin Watson + + * grub-core/commands/efi/lsefimmap.c: Correct header. + * NEWS: Update. + 2010-09-20 Colin Watson * util/grub-editenv.c (argp_parser): Don't pass translated strings diff --git a/NEWS b/NEWS index b8cec570e..7fce921d6 100644 --- a/NEWS +++ b/NEWS @@ -17,7 +17,7 @@ New in 1.99: * Extend `vbeinfo' and `vbetest' commands to non-VBE graphics, as `videoinfo' and `videotest'. -* New `lsefisystab' and `lssal' commands on EFI platforms. +* New `lsefisystab', `lssal', and `lsefimmap' commands on EFI platforms. * Support explicit user claim that a device is BIOS-visible. Devices listed in device.map will be assumed to be readable using only BIOS diff --git a/grub-core/commands/efi/lsefimmap.c b/grub-core/commands/efi/lsefimmap.c index 010fc0d77..30780447a 100644 --- a/grub-core/commands/efi/lsefimmap.c +++ b/grub-core/commands/efi/lsefimmap.c @@ -1,4 +1,4 @@ -/* memmap.c - Display memory map. */ +/* lsefimemmap.c - Display memory map. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008 Free Software Foundation, Inc. From 899d8af498bcfe987c59733b3d530011e4ea49e9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 19:14:29 +0200 Subject: [PATCH 0224/1414] * grub-core/kern/emu/misc.c (asprintf): Use vsnprintf instead of vsprintf. --- ChangeLog | 5 +++++ grub-core/kern/emu/misc.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ae98382fa..c2239c5ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-20 Vladimir Serbinenko + + * grub-core/kern/emu/misc.c (asprintf): Use vsnprintf instead of + vsprintf. + 2010-09-20 Colin Watson * grub-core/commands/efi/lsefimmap.c: Correct header. diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 4630d335d..d8db3be9d 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -161,7 +161,7 @@ vasprintf (char **buf, const char *fmt, va_list ap) /* Should be large enough. */ *buf = xmalloc (512); - return vsprintf (*buf, fmt, ap); + return vsnprintf (*buf, 512, fmt, ap); } #endif From 1e8d555b7d9cb0b459ee1f8f42bc99921a59a01c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 20:09:31 +0200 Subject: [PATCH 0225/1414] Split mdraid.mod into mdraid09.mod and mdraid1x.mod. * Makefile.util.def (libgrub.a): Add grub-core/disk/mdraid1x_linux.c. * grub-core/Makefile.core.def (mdraid): Renamed to ... (mdraid09): ... this. (mdraid1x): New module. * grub-core/disk/mdraid_linux.c: Move 1.x parts ... * grub-core/disk/mdraid1x_linux.c: ...here. All users updated. --- ChangeLog | 11 ++ Makefile.util.def | 1 + grub-core/Makefile.core.def | 7 +- grub-core/disk/mdraid1x_linux.c | 231 +++++++++++++++++++++++++++ grub-core/disk/mdraid_linux.c | 272 +++++--------------------------- include/grub/disk.h | 6 +- util/grub-fstest.c | 6 +- util/grub-probe.c | 6 +- util/grub-setup.c | 6 +- 9 files changed, 307 insertions(+), 239 deletions(-) create mode 100644 grub-core/disk/mdraid1x_linux.c diff --git a/ChangeLog b/ChangeLog index c2239c5ea..ff13ff5a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-09-20 Vladimir Serbinenko + + Split mdraid.mod into mdraid09.mod and mdraid1x.mod. + + * Makefile.util.def (libgrub.a): Add grub-core/disk/mdraid1x_linux.c. + * grub-core/Makefile.core.def (mdraid): Renamed to ... + (mdraid09): ... this. + (mdraid1x): New module. + * grub-core/disk/mdraid_linux.c: Move 1.x parts ... + * grub-core/disk/mdraid1x_linux.c: ...here. All users updated. + 2010-09-20 Vladimir Serbinenko * grub-core/kern/emu/misc.c (asprintf): Use vsnprintf instead of diff --git a/Makefile.util.def b/Makefile.util.def index 2ec82a4d2..ad99b0f31 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -25,6 +25,7 @@ library = { common = grub-core/disk/loopback.c; common = grub-core/disk/lvm.c; common = grub-core/disk/mdraid_linux.c; + common = grub-core/disk/mdraid1x_linux.c; common = grub-core/disk/raid5_recover.c; common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index d3d7010ea..bf79a277a 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -741,10 +741,15 @@ module = { }; module = { - name = mdraid; + name = mdraid09; common = disk/mdraid_linux.c; }; +module = { + name = mdraid1x; + common = disk/mdraid1x_linux.c; +}; + module = { name = raid; common = disk/raid.c; diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c new file mode 100644 index 000000000..4a0298347 --- /dev/null +++ b/grub-core/disk/mdraid1x_linux.c @@ -0,0 +1,231 @@ +/* mdraid_linux.c - module to handle Linux Software RAID. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 . + */ + +#include +#include +#include +#include +#include +#include + +/* Linux RAID on disk structures and constants, + copied from include/linux/raid/md_p.h. */ + +#define SB_MAGIC 0xa92b4efc + +/* + * The version-1 superblock : + * All numeric fields are little-endian. + * + * Total size: 256 bytes plus 2 per device. + * 1K allows 384 devices. + */ + +struct grub_raid_super_1x +{ + /* Constant array information - 128 bytes. */ + grub_uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian. */ + grub_uint32_t major_version; /* 1. */ + grub_uint32_t feature_map; /* Bit 0 set if 'bitmap_offset' is meaningful. */ + grub_uint32_t pad0; /* Always set to 0 when writing. */ + + grub_uint8_t set_uuid[16]; /* User-space generated. */ + char set_name[32]; /* Set and interpreted by user-space. */ + + grub_uint64_t ctime; /* Lo 40 bits are seconds, top 24 are microseconds or 0. */ + grub_uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5. */ + grub_uint32_t layout; /* only for raid5 and raid10 currently. */ + grub_uint64_t size; /* Used size of component devices, in 512byte sectors. */ + + grub_uint32_t chunksize; /* In 512byte sectors. */ + grub_uint32_t raid_disks; + grub_uint32_t bitmap_offset; /* Sectors after start of superblock that bitmap starts + * NOTE: signed, so bitmap can be before superblock + * only meaningful of feature_map[0] is set. + */ + + /* These are only valid with feature bit '4'. */ + grub_uint32_t new_level; /* New level we are reshaping to. */ + grub_uint64_t reshape_position; /* Next address in array-space for reshape. */ + grub_uint32_t delta_disks; /* Change in number of raid_disks. */ + grub_uint32_t new_layout; /* New layout. */ + grub_uint32_t new_chunk; /* New chunk size (512byte sectors). */ + grub_uint8_t pad1[128 - 124]; /* Set to 0 when written. */ + + /* Constant this-device information - 64 bytes. */ + grub_uint64_t data_offset; /* Sector start of data, often 0. */ + grub_uint64_t data_size; /* Sectors in this device that can be used for data. */ + grub_uint64_t super_offset; /* Sector start of this superblock. */ + grub_uint64_t recovery_offset; /* Sectors before this offset (from data_offset) have been recovered. */ + grub_uint32_t dev_number; /* Permanent identifier of this device - not role in raid. */ + grub_uint32_t cnt_corrected_read; /* Number of read errors that were corrected by re-writing. */ + grub_uint8_t device_uuid[16]; /* User-space setable, ignored by kernel. */ + grub_uint8_t devflags; /* Per-device flags. Only one defined... */ + grub_uint8_t pad2[64 - 57]; /* Set to 0 when writing. */ + + /* Array state information - 64 bytes. */ + grub_uint64_t utime; /* 40 bits second, 24 btes microseconds. */ + grub_uint64_t events; /* Incremented when superblock updated. */ + grub_uint64_t resync_offset; /* Data before this offset (from data_offset) known to be in sync. */ + grub_uint32_t sb_csum; /* Checksum upto devs[max_dev]. */ + grub_uint32_t max_dev; /* Size of devs[] array to consider. */ + grub_uint8_t pad3[64 - 32]; /* Set to 0 when writing. */ + + /* Device state information. Indexed by dev_number. + * 2 bytes per device. + * Note there are no per-device state flags. State information is rolled + * into the 'roles' value. If a device is spare or faulty, then it doesn't + * have a meaningful role. + */ + grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */ +}; +/* Could be __attribute__ ((packed)), but since all members in this struct + are already appropriately aligned, we can omit this and avoid suboptimal + assembly in some cases. */ + +#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ + +static grub_err_t +grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, + grub_disk_addr_t *start_sector) +{ + grub_disk_addr_t sector; + grub_uint64_t size; + struct grub_raid_super_1x sb; + grub_uint8_t minor_version; + + /* The sector where the mdraid 0.90 superblock is stored, if available. */ + size = grub_disk_get_size (disk); + + /* Check for an 1.x superblock. + * It's always aligned to a 4K boundary + * and depending on the minor version it can be: + * 0: At least 8K, but less than 12K, from end of device + * 1: At start of device + * 2: 4K from start of device. + */ + + for (minor_version = 0; minor_version < 3; ++minor_version) + { + switch (minor_version) + { + case 0: + sector = (size - 8 * 2) & ~(4 * 2 - 1); + break; + case 1: + sector = 0; + break; + case 2: + sector = 4 * 2; + break; + } + + if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x), + &sb)) + return grub_errno; + + if (sb.magic != SB_MAGIC) + continue; + + { + grub_uint64_t sb_size; + struct grub_raid_super_1x *real_sb; + + if (sb.major_version != 1) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID version: %d", + sb.major_version); + + /* Multipath. */ + if ((int) sb.level == -4) + sb.level = 1; + + if (sb.level != 0 && sb.level != 1 && sb.level != 4 && + sb.level != 5 && sb.level != 6 && sb.level != 10) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID level: %d", sb.level); + + /* 1.x superblocks don't have a fixed size on disk. So we have to + read it again now that we now the max device count. */ + sb_size = sizeof (struct grub_raid_super_1x) + + 2 * grub_le_to_cpu32 (sb.max_dev); + real_sb = grub_malloc (sb_size); + if (! real_sb) + return grub_errno; + + if (grub_disk_read (disk, sector, 0, sb_size, real_sb)) + { + grub_free (real_sb); + return grub_errno; + } + + array->name = grub_strdup (real_sb->set_name); + if (! array->name) + { + grub_free (real_sb); + return grub_errno; + } + + array->number = 0; + array->level = grub_le_to_cpu32 (real_sb->level); + array->layout = grub_le_to_cpu32 (real_sb->layout); + array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); + array->disk_size = grub_le_to_cpu64 (real_sb->size); + array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); + if (grub_le_to_cpu32 (real_sb->dev_number) < + grub_le_to_cpu32 (real_sb->max_dev)) + array->index = grub_le_to_cpu16 + (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); + else + array->index = 0xffff; /* disk will be later not used! */ + array->uuid_len = 16; + array->uuid = grub_malloc (16); + if (!array->uuid) + { + grub_free (real_sb); + return grub_errno; + } + + grub_memcpy (array->uuid, real_sb->set_uuid, 16); + + *start_sector = real_sb->data_offset; + + grub_free (real_sb); + return 0; + } + } + + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 1.x raid"); +} + +static struct grub_raid grub_mdraid_dev = { + .name = "mdraid1x", + .detect = grub_mdraid_detect, + .next = 0 +}; + +GRUB_MOD_INIT (mdraid1x) +{ + grub_raid_register (&grub_mdraid_dev); +} + +GRUB_MOD_FINI (mdraid1x) +{ + grub_raid_unregister (&grub_mdraid_dev); +} diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index d5a0aad47..549d48355 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -159,266 +159,78 @@ struct grub_raid_super_09 struct grub_raid_disk_09 this_disk; } __attribute__ ((packed)); -/* - * The version-1 superblock : - * All numeric fields are little-endian. - * - * Total size: 256 bytes plus 2 per device. - * 1K allows 384 devices. - */ - -struct grub_raid_super_1x -{ - /* Constant array information - 128 bytes. */ - grub_uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian. */ - grub_uint32_t major_version; /* 1. */ - grub_uint32_t feature_map; /* Bit 0 set if 'bitmap_offset' is meaningful. */ - grub_uint32_t pad0; /* Always set to 0 when writing. */ - - grub_uint8_t set_uuid[16]; /* User-space generated. */ - char set_name[32]; /* Set and interpreted by user-space. */ - - grub_uint64_t ctime; /* Lo 40 bits are seconds, top 24 are microseconds or 0. */ - grub_uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5. */ - grub_uint32_t layout; /* only for raid5 and raid10 currently. */ - grub_uint64_t size; /* Used size of component devices, in 512byte sectors. */ - - grub_uint32_t chunksize; /* In 512byte sectors. */ - grub_uint32_t raid_disks; - grub_uint32_t bitmap_offset; /* Sectors after start of superblock that bitmap starts - * NOTE: signed, so bitmap can be before superblock - * only meaningful of feature_map[0] is set. - */ - - /* These are only valid with feature bit '4'. */ - grub_uint32_t new_level; /* New level we are reshaping to. */ - grub_uint64_t reshape_position; /* Next address in array-space for reshape. */ - grub_uint32_t delta_disks; /* Change in number of raid_disks. */ - grub_uint32_t new_layout; /* New layout. */ - grub_uint32_t new_chunk; /* New chunk size (512byte sectors). */ - grub_uint8_t pad1[128 - 124]; /* Set to 0 when written. */ - - /* Constant this-device information - 64 bytes. */ - grub_uint64_t data_offset; /* Sector start of data, often 0. */ - grub_uint64_t data_size; /* Sectors in this device that can be used for data. */ - grub_uint64_t super_offset; /* Sector start of this superblock. */ - grub_uint64_t recovery_offset; /* Sectors before this offset (from data_offset) have been recovered. */ - grub_uint32_t dev_number; /* Permanent identifier of this device - not role in raid. */ - grub_uint32_t cnt_corrected_read; /* Number of read errors that were corrected by re-writing. */ - grub_uint8_t device_uuid[16]; /* User-space setable, ignored by kernel. */ - grub_uint8_t devflags; /* Per-device flags. Only one defined... */ - grub_uint8_t pad2[64 - 57]; /* Set to 0 when writing. */ - - /* Array state information - 64 bytes. */ - grub_uint64_t utime; /* 40 bits second, 24 btes microseconds. */ - grub_uint64_t events; /* Incremented when superblock updated. */ - grub_uint64_t resync_offset; /* Data before this offset (from data_offset) known to be in sync. */ - grub_uint32_t sb_csum; /* Checksum upto devs[max_dev]. */ - grub_uint32_t max_dev; /* Size of devs[] array to consider. */ - grub_uint8_t pad3[64 - 32]; /* Set to 0 when writing. */ - - /* Device state information. Indexed by dev_number. - * 2 bytes per device. - * Note there are no per-device state flags. State information is rolled - * into the 'roles' value. If a device is spare or faulty, then it doesn't - * have a meaningful role. - */ - grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */ -}; -/* Could be __attribute__ ((packed)), but since all members in this struct - are already appropriately aligned, we can omit this and avoid suboptimal - assembly in some cases. */ - -#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ - -static grub_err_t -grub_mdraid_detect_09 (grub_disk_addr_t sector, - struct grub_raid_super_09 *sb, - struct grub_raid_array *array, - grub_disk_addr_t *start_sector) -{ - grub_uint32_t *uuid; - - if (sb->major_version != 0 || sb->minor_version != 90) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID version: %d.%d", - sb->major_version, sb->minor_version); - - /* FIXME: Check the checksum. */ - - /* Multipath. */ - if ((int) sb->level == -4) - sb->level = 1; - - if (sb->level != 0 && sb->level != 1 && sb->level != 4 && - sb->level != 5 && sb->level != 6 && sb->level != 10) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID level: %d", sb->level); - - array->name = NULL; - array->number = sb->md_minor; - array->level = sb->level; - array->layout = sb->layout; - array->total_devs = sb->raid_disks; - array->disk_size = (sb->size) ? sb->size * 2 : sector; - array->chunk_size = sb->chunk_size >> 9; - array->index = sb->this_disk.number; - array->uuid_len = 16; - array->uuid = grub_malloc (16); - if (!array->uuid) - return grub_errno; - - uuid = (grub_uint32_t *) array->uuid; - uuid[0] = sb->set_uuid0; - uuid[1] = sb->set_uuid1; - uuid[2] = sb->set_uuid2; - uuid[3] = sb->set_uuid3; - - *start_sector = 0; - - return 0; -} - -static grub_err_t -grub_mdraid_detect_1x (grub_disk_t disk, grub_disk_addr_t sector, - struct grub_raid_super_1x *sb, - struct grub_raid_array *array, - grub_disk_addr_t *start_sector) -{ - grub_uint64_t sb_size; - struct grub_raid_super_1x *real_sb; - - if (sb->major_version != 1) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID version: %d", - sb->major_version); - - /* Multipath. */ - if ((int) sb->level == -4) - sb->level = 1; - - if (sb->level != 0 && sb->level != 1 && sb->level != 4 && - sb->level != 5 && sb->level != 6 && sb->level != 10) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID level: %d", sb->level); - - /* 1.x superblocks don't have a fixed size on disk. So we have to - read it again now that we now the max device count. */ - sb_size = sizeof (struct grub_raid_super_1x) + 2 * grub_le_to_cpu32 (sb->max_dev); - real_sb = grub_malloc (sb_size); - if (! real_sb) - return grub_errno; - - if (grub_disk_read (disk, sector, 0, sb_size, real_sb)) - { - grub_free (real_sb); - return grub_errno; - } - - array->name = grub_strdup (real_sb->set_name); - if (! array->name) - { - grub_free (real_sb); - return grub_errno; - } - - array->number = 0; - array->level = grub_le_to_cpu32 (real_sb->level); - array->layout = grub_le_to_cpu32 (real_sb->layout); - array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); - array->disk_size = grub_le_to_cpu64 (real_sb->size); - array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); - if (grub_le_to_cpu32 (real_sb->dev_number) < - grub_le_to_cpu32 (real_sb->max_dev)) - array->index = grub_le_to_cpu16 - (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); - else - array->index = 0xffff; /* disk will be later not used! */ - array->uuid_len = 16; - array->uuid = grub_malloc (16); - if (!array->uuid) - { - grub_free (real_sb); - return grub_errno; - } - - grub_memcpy (array->uuid, real_sb->set_uuid, 16); - - *start_sector = real_sb->data_offset; - - grub_free (real_sb); - return 0; -} - static grub_err_t grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, grub_disk_addr_t *start_sector) { grub_disk_addr_t sector; grub_uint64_t size; - struct grub_raid_super_09 sb_09; - struct grub_raid_super_1x sb_1x; - grub_uint8_t minor_version; + struct grub_raid_super_09 sb; + grub_uint32_t *uuid; /* The sector where the mdraid 0.90 superblock is stored, if available. */ size = grub_disk_get_size (disk); sector = NEW_SIZE_SECTORS (size); - if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb_09)) + if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb)) return grub_errno; /* Look whether there is a mdraid 0.90 superblock. */ - if (sb_09.md_magic == SB_MAGIC) - return grub_mdraid_detect_09 (sector, &sb_09, array, start_sector); + if (sb.md_magic != SB_MAGIC) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid"); - /* Check for an 1.x superblock. - * It's always aligned to a 4K boundary - * and depending on the minor version it can be: - * 0: At least 8K, but less than 12K, from end of device - * 1: At start of device - * 2: 4K from start of device. - */ + if (sb.major_version != 0 || sb.minor_version != 90) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported RAID version: %d.%d", + sb.major_version, sb.minor_version); - for (minor_version = 0; minor_version < 3; ++minor_version) - { - switch (minor_version) - { - case 0: - sector = (size - 8 * 2) & ~(4 * 2 - 1); - break; - case 1: - sector = 0; - break; - case 2: - sector = 4 * 2; - break; - } + /* FIXME: Check the checksum. */ - if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x), - &sb_1x)) - return grub_errno; + /* Multipath. */ + if ((int) sb.level == -4) + sb.level = 1; - if (sb_1x.magic == SB_MAGIC) - return grub_mdraid_detect_1x (disk, sector, &sb_1x, array, - start_sector); - } + if (sb.level != 0 && sb.level != 1 && sb.level != 4 && + sb.level != 5 && sb.level != 6 && sb.level != 10) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported RAID level: %d", sb.level); - /* Neither 0.90 nor 1.x. */ - return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); + array->name = NULL; + array->number = sb.md_minor; + array->level = sb.level; + array->layout = sb.layout; + array->total_devs = sb.raid_disks; + array->disk_size = (sb.size) ? sb.size * 2 : sector; + array->chunk_size = sb.chunk_size >> 9; + array->index = sb.this_disk.number; + array->uuid_len = 16; + array->uuid = grub_malloc (16); + if (!array->uuid) + return grub_errno; + + uuid = (grub_uint32_t *) array->uuid; + uuid[0] = sb.set_uuid0; + uuid[1] = sb.set_uuid1; + uuid[2] = sb.set_uuid2; + uuid[3] = sb.set_uuid3; + + *start_sector = 0; + + return 0; } static struct grub_raid grub_mdraid_dev = { - .name = "mdraid", + .name = "mdraid09", .detect = grub_mdraid_detect, .next = 0 }; -GRUB_MOD_INIT (mdraid) +GRUB_MOD_INIT (mdraid09) { grub_raid_register (&grub_mdraid_dev); } -GRUB_MOD_FINI (mdraid) +GRUB_MOD_FINI (mdraid09) { grub_raid_unregister (&grub_mdraid_dev); } diff --git a/include/grub/disk.h b/include/grub/disk.h index e3a0160c4..9c5653e00 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -176,10 +176,12 @@ extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t, #if defined (GRUB_UTIL) || defined (GRUB_MACHINE_EMU) void grub_lvm_init (void); -void grub_mdraid_init (void); +void grub_mdraid09_init (void); +void grub_mdraid1x_init (void); void grub_raid_init (void); void grub_lvm_fini (void); -void grub_mdraid_fini (void); +void grub_mdraid09_fini (void); +void grub_mdraid1x_fini (void); void grub_raid_fini (void); #endif diff --git a/util/grub-fstest.c b/util/grub-fstest.c index aedb2954a..2fcde4ab0 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -296,10 +296,12 @@ fstest (int n, char **args) } grub_lvm_fini (); - grub_mdraid_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); grub_raid_fini (); grub_raid_init (); - grub_mdraid_init (); + grub_mdraid09_init (); + grub_mdraid1x_init (); grub_lvm_init (); switch (cmd) diff --git a/util/grub-probe.c b/util/grub-probe.c index 9f8a443c8..b92d301f0 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -391,10 +391,12 @@ main (int argc, char *argv[]) grub_init_all (); grub_lvm_fini (); - grub_mdraid_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); grub_raid_fini (); grub_raid_init (); - grub_mdraid_init (); + grub_mdraid09_init (); + grub_mdraid1x_init (); grub_lvm_init (); /* Do it. */ diff --git a/util/grub-setup.c b/util/grub-setup.c index 05355bf43..62ba9747e 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -849,10 +849,12 @@ main (int argc, char *argv[]) grub_init_all (); grub_lvm_fini (); - grub_mdraid_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); grub_raid_fini (); grub_raid_init (); - grub_mdraid_init (); + grub_mdraid09_init (); + grub_mdraid1x_init (); grub_lvm_init (); dest_dev = get_device_name (arguments.device); From 4b98e0d7c70e5187cda278457432a6775e696b49 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 21:30:11 +0200 Subject: [PATCH 0226/1414] Support net-/openbsd labels inside logical partitions --- grub-core/partmap/bsdlabel.c | 49 +++++++++++++++++++++++----------- grub-core/partmap/msdos.c | 10 +++---- include/grub/msdos_partition.h | 7 +++++ 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index f25b9548e..da5c6e3ab 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -145,32 +145,49 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type, int (*hook) (grub_disk_t disk, const grub_partition_t partition)) { - grub_err_t err; + int count = 0; + + auto int check_msdos (grub_disk_t dsk, + const grub_partition_t partition); + + int check_msdos (grub_disk_t dsk, + const grub_partition_t partition) + { + grub_err_t err; + + if (partition->msdostype != type) + return 0; + + err = iterate_real (dsk, partition->start + + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook); + if (err == GRUB_ERR_NONE) + { + count++; + return 1; + } + if (err == GRUB_ERR_BAD_PART_TABLE) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + grub_print_error (); + return 0; + } if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") == 0) return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); { - struct grub_msdos_partition_mbr mbr; - unsigned i; + grub_err_t err; + err = grub_partition_msdos_iterate (disk, check_msdos); - err = grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr); if (err) return err; - - for (i = 0; i < ARRAY_SIZE (mbr.entries); i++) - if (mbr.entries[i].type == type) - { - err = iterate_real (disk, mbr.entries[i].start - + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, - hook); - if (err != GRUB_ERR_BAD_PART_TABLE) - return err; - } + if (!count) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found"); } - - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found"); + return GRUB_ERR_NONE; } static grub_err_t diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index a378bb1cd..c1805fe56 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -27,10 +27,10 @@ static struct grub_partition_map grub_msdos_partition_map; -static grub_err_t -pc_partition_map_iterate (grub_disk_t disk, - int (*hook) (grub_disk_t disk, - const grub_partition_t partition)) +grub_err_t +grub_partition_msdos_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) { struct grub_partition p; struct grub_msdos_partition_mbr mbr; @@ -148,7 +148,7 @@ pc_partition_map_iterate (grub_disk_t disk, static struct grub_partition_map grub_msdos_partition_map = { .name = "msdos", - .iterate = pc_partition_map_iterate, + .iterate = grub_partition_msdos_iterate, }; GRUB_MOD_INIT(part_msdos) diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h index 650d78493..a6e3fda49 100644 --- a/include/grub/msdos_partition.h +++ b/include/grub/msdos_partition.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include /* The signature. */ #define GRUB_PC_PARTITION_SIGNATURE 0xaa55 @@ -114,4 +116,9 @@ grub_msdos_partition_is_extended (int type) || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED); } +grub_err_t +grub_partition_msdos_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)); + #endif /* ! GRUB_PC_PARTITION_HEADER */ From 65d973de1c7dfdb401e84efbcf7fb5f50b95d4e1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 21:34:20 +0200 Subject: [PATCH 0227/1414] Add the comment about net-/openbsdlabel --- grub-core/partmap/bsdlabel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index da5c6e3ab..eff3bbe44 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -139,6 +139,9 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, &grub_bsdlabel_partition_map, hook); } +/* This is a total breakage. Even when net-/openbsd label is inside partition + it actually describes the whole disk. + */ static grub_err_t netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type, struct grub_partition_map *pmap, From 2ea57f884457d20091164b6c4635d277363cdb1c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 22:11:52 +0200 Subject: [PATCH 0228/1414] * grub-core/mmap/mmap.c (grub_cmd_cutmem): New function. (GRUB_MOD_INIT): Register new command. (GRUB_MOD_FINI): Unregister new command. --- ChangeLog | 8 ++++++ grub-core/mmap/mmap.c | 57 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2438ae32b..40f017bb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-09-20 Vladimir Serbinenko + + New command cutmem. + + * grub-core/mmap/mmap.c (grub_cmd_cutmem): New function. + (GRUB_MOD_INIT): Register new command. + (GRUB_MOD_FINI): Unregister new command. + 2010-09-20 Vladimir Serbinenko Support some annoying BSD and Minix subpartitions. diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index 7c3430e9f..4f5fad705 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -398,7 +398,57 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), } } -static grub_command_t cmd; +static grub_err_t +grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + grub_uint64_t cutmem; + char *ptr; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, + grub_memory_type_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, + grub_uint64_t size, + grub_memory_type_t type __attribute__ ((unused))) + { + grub_uint64_t end = addr + size; + + if (end >= cutmem) + return 0; + if (addr < cutmem) + addr = cutmem; + + grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE); + return 0; + } + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "number required"); + + cutmem = grub_strtoul (args[0], &ptr, 0); + if (grub_errno) + return grub_errno; + switch (*ptr) + { + case 'K': + cutmem <<= 10; + break; + case 'M': + cutmem <<= 20; + break; + case 'G': + cutmem <<= 30; + break; + case 'T': + cutmem <<= 40; + break; + } + grub_mmap_iterate (hook); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd, cmd_cut; GRUB_MOD_INIT(mmap) @@ -406,10 +456,15 @@ GRUB_MOD_INIT(mmap) cmd = grub_register_command ("badram", grub_cmd_badram, N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), N_("Declare memory regions as badram.")); + cmd_cut = grub_register_command ("cutmem", grub_cmd_cutmem, + N_("ADDR[K|M|G]"), + N_("Remove any memory regions above ADDR.")); + } GRUB_MOD_FINI(mmap) { grub_unregister_command (cmd); + grub_unregister_command (cmd_cut); } From 7bda3a87afc4f7b7a7781302da83a9e1a591eab9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 22:24:30 +0200 Subject: [PATCH 0229/1414] Make cutmem accept a region specification. Suggested by: Samuel Thibault * grub-core/mmap/mmap.c (parsemem): New function. (grub_cmd_cutmem): Handle new arguments. --- ChangeLog | 8 ++++++ grub-core/mmap/mmap.c | 64 ++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40f017bb9..9951f5979 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-09-20 Vladimir Serbinenko + + Make cutmem accept a region specification. + Suggested by: Samuel Thibault + + * grub-core/mmap/mmap.c (parsemem): New function. + (grub_cmd_cutmem): Handle new arguments. + 2010-09-20 Vladimir Serbinenko New command cutmem. diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index 4f5fad705..1c1825490 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -398,12 +398,33 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), } } +static grub_uint64_t +parsemem (const char *str) +{ + grub_uint64_t ret; + char *ptr; + + ret = grub_strtoul (str, &ptr, 0); + + switch (*ptr) + { + case 'K': + return ret << 10; + case 'M': + return ret << 20; + case 'G': + return ret << 30; + case 'T': + return ret << 40; + } + return ret; +} + static grub_err_t grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - grub_uint64_t cutmem; - char *ptr; + grub_uint64_t from, to; auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t); @@ -413,36 +434,29 @@ grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)), { grub_uint64_t end = addr + size; - if (end >= cutmem) + if (addr <= from) + addr = from; + if (end >= to) + end = to; + + if (end <= addr) return 0; - if (addr < cutmem) - addr = cutmem; grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE); return 0; } - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "number required"); + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "argements required"); - cutmem = grub_strtoul (args[0], &ptr, 0); + from = parsemem (args[0]); if (grub_errno) return grub_errno; - switch (*ptr) - { - case 'K': - cutmem <<= 10; - break; - case 'M': - cutmem <<= 20; - break; - case 'G': - cutmem <<= 30; - break; - case 'T': - cutmem <<= 40; - break; - } + + to = parsemem (args[1]); + if (grub_errno) + return grub_errno; + grub_mmap_iterate (hook); return GRUB_ERR_NONE; @@ -457,8 +471,8 @@ GRUB_MOD_INIT(mmap) N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), N_("Declare memory regions as badram.")); cmd_cut = grub_register_command ("cutmem", grub_cmd_cutmem, - N_("ADDR[K|M|G]"), - N_("Remove any memory regions above ADDR.")); + N_("FROM[K|M|G] TO[K|M|G]"), + N_("Remove any memory regions in specified range.")); } From a38b701cbf0a9d3b84bcfc2daef36a964273a5a0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 23:01:34 +0200 Subject: [PATCH 0230/1414] Rename jail to extractor --- grub-core/commands/configfile.c | 32 ++++++++++++++++---------------- grub-core/commands/legacycfg.c | 2 +- grub-core/commands/menuentry.c | 2 +- grub-core/commands/search_wrap.c | 2 +- grub-core/commands/test.c | 4 ++-- grub-core/kern/corecmd.c | 2 +- grub-core/normal/context.c | 10 +++++----- grub-core/script/execute.c | 6 ++++-- include/grub/command.h | 4 ++-- include/grub/env.h | 4 ++-- include/grub/err.h | 2 +- include/grub/normal.h | 2 +- 12 files changed, 37 insertions(+), 35 deletions(-) diff --git a/grub-core/commands/configfile.c b/grub-core/commands/configfile.c index 4d54ae682..2568b7ee6 100644 --- a/grub-core/commands/configfile.c +++ b/grub-core/commands/configfile.c @@ -27,34 +27,34 @@ static grub_err_t grub_cmd_source (grub_command_t cmd, int argc, char **args) { - int new_env, jail; + int new_env, extractor; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - jail = (cmd->name[0] == 'j'); - new_env = (cmd->name[jail ? 5 : 0] == 'c'); + extractor = (cmd->name[0] == 'e'); + new_env = (cmd->name[extractor ? sizeof ("extract_entries_") - 1 : 0] == 'c'); if (new_env) grub_cls (); - if (new_env && !jail) + if (new_env && !extractor) grub_env_context_open (); - if (jail) - grub_env_jail_open (!new_env); + if (extractor) + grub_env_extractor_open (!new_env); grub_normal_execute (args[0], 1, ! new_env); - if (new_env && !jail) + if (new_env && !extractor) grub_env_context_close (); - if (jail) - grub_env_jail_close (!new_env); + if (extractor) + grub_env_extractor_close (!new_env); return 0; } static grub_command_t cmd_configfile, cmd_source, cmd_dot; -static grub_command_t cmd_jail_source, cmd_jail_configfile; +static grub_command_t cmd_extractor_source, cmd_extractor_configfile; GRUB_MOD_INIT(configfile) { @@ -67,14 +67,14 @@ GRUB_MOD_INIT(configfile) N_("Load another config file without changing context.") ); - cmd_jail_source = - grub_register_command ("jail_source", grub_cmd_source, + cmd_extractor_source = + grub_register_command ("extract_entries_source", grub_cmd_source, N_("FILE"), N_("Load another config file without changing context but take only menuentries.") ); - cmd_jail_configfile = - grub_register_command ("jail_configfile", grub_cmd_source, + cmd_extractor_configfile = + grub_register_command ("extract_entries_configfile", grub_cmd_source, N_("FILE"), N_("Load another config file without changing context but take only menuentries.") ); @@ -90,7 +90,7 @@ GRUB_MOD_FINI(configfile) { grub_unregister_command (cmd_configfile); grub_unregister_command (cmd_source); - grub_unregister_command (cmd_jail_configfile); - grub_unregister_command (cmd_jail_source); + grub_unregister_command (cmd_extractor_configfile); + grub_unregister_command (cmd_extractor_source); grub_unregister_command (cmd_dot); } diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 463297810..c183c5a5c 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -201,7 +201,7 @@ grub_cmd_legacy_configfile (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); grub_cls (); - grub_env_context_open (1); + grub_env_context_open (); ret = legacy_file (args[0]); grub_env_context_close (); diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 01f6c010d..f10e05dc3 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -289,7 +289,7 @@ grub_menu_init (void) { cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry, GRUB_COMMAND_FLAG_BLOCKS - | GRUB_COMMAND_FLAG_UNJAILED, + | GRUB_COMMAND_FLAG_EXTRACTOR, N_("BLOCK"), N_("Define a menuentry."), options); } diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index a06399ac6..80741d7ab 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -90,7 +90,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(search) { cmd = - grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_UNJAILED, + grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_EXTRACTOR, N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]" " NAME"), N_("Search devices by file, filesystem label" diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c index 3affab9c5..e981c945a 100644 --- a/grub-core/commands/test.c +++ b/grub-core/commands/test.c @@ -423,10 +423,10 @@ GRUB_MOD_INIT(test) { cmd_1 = grub_register_command ("[", grub_cmd_test, N_("EXPRESSION ]"), N_("Evaluate an expression.")); - cmd_1->flags |= GRUB_COMMAND_FLAG_UNJAILED; + cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; cmd_2 = grub_register_command ("test", grub_cmd_test, N_("EXPRESSION"), N_("Evaluate an expression.")); - cmd_2->flags |= GRUB_COMMAND_FLAG_UNJAILED; + cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; } GRUB_MOD_FINI(test) diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c index f1d060cef..687692f3c 100644 --- a/grub-core/kern/corecmd.c +++ b/grub-core/kern/corecmd.c @@ -183,7 +183,7 @@ grub_register_core_commands (void) N_("[ENVVAR=VALUE]"), N_("Set an environment variable.")); if (cmd) - cmd->flags |= GRUB_COMMAND_FLAG_UNJAILED; + cmd->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; grub_register_command ("unset", grub_core_cmd_unset, N_("ENVVAR"), N_("Remove an environment variable.")); diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index 3b182dde7..75beeefda 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -99,12 +99,12 @@ grub_env_context_open (void) return grub_env_new_context (0); } -int grub_jail_level = 0; +int grub_extractor_level = 0; grub_err_t -grub_env_jail_open (int source) +grub_env_extractor_open (int source) { - grub_jail_level++; + grub_extractor_level++; return grub_env_new_context (source); } @@ -146,7 +146,7 @@ grub_env_context_close (void) } grub_err_t -grub_env_jail_close (int source) +grub_env_extractor_close (int source) { grub_menu_t menu, menu2; grub_menu_entry_t *last; @@ -171,7 +171,7 @@ grub_env_jail_close (int source) menu2->size += menu->size; } - grub_jail_level--; + grub_extractor_level--; return err; } diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 8d64962f8..2cadb0e1b 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -611,8 +611,10 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute the GRUB command or function. */ if (grubcmd) { - if (grub_jail_level && !(grubcmd->flags & GRUB_COMMAND_FLAG_UNJAILED)) - ret = grub_error (GRUB_ERR_JAIL, "%s isn't allowed to execute in jail", + if (grub_extractor_level && !(grubcmd->flags + & GRUB_COMMAND_FLAG_EXTRACTOR)) + ret = grub_error (GRUB_ERR_EXTRACTOR, + "%s isn't allowed to execute in an extractor", cmdname); else if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) && (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD)) diff --git a/include/grub/command.h b/include/grub/command.h index b17b1aa94..19622752e 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -35,8 +35,8 @@ typedef enum grub_command_flags GRUB_COMMAND_ACCEPT_DASH = 0x80, /* This command accepts only options preceding direct arguments. */ GRUB_COMMAND_OPTIONS_AT_START = 0x100, - /* Can be executed in a jail. */ - GRUB_COMMAND_FLAG_UNJAILED = 0x200 + /* Can be executed in an entries extractor. */ + GRUB_COMMAND_FLAG_EXTRACTOR = 0x200 } grub_command_flags_t; struct grub_command; diff --git a/include/grub/env.h b/include/grub/env.h index ee0e0546e..6d1f0de6e 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -60,10 +60,10 @@ grub_menu_t grub_env_get_menu (void); void grub_env_set_menu (grub_menu_t nmenu); grub_err_t -grub_env_jail_open (int source); +grub_env_extractor_open (int source); grub_err_t -grub_env_jail_close (int source); +grub_env_extractor_close (int source); #endif /* ! GRUB_ENV_HEADER */ diff --git a/include/grub/err.h b/include/grub/err.h index b2527cea0..22334038d 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -55,7 +55,7 @@ typedef enum GRUB_ERR_TIMEOUT, GRUB_ERR_IO, GRUB_ERR_ACCESS_DENIED, - GRUB_ERR_JAIL + GRUB_ERR_EXTRACTOR } grub_err_t; diff --git a/include/grub/normal.h b/include/grub/normal.h index 390dbb1da..2fc289373 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -114,7 +114,7 @@ void grub_normal_reset_more (void); void grub_xputs_normal (const char *str); -extern int grub_jail_level; +extern int grub_extractor_level; grub_err_t grub_normal_add_menu_entry (int argc, const char **args, char **classes, From 57f20e67a042893ceecc01fa9ec4eca44866749c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Sep 2010 23:10:29 +0200 Subject: [PATCH 0231/1414] Support extraction of legacy entries --- grub-core/commands/legacycfg.c | 69 +++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index c183c5a5c..d69dad75b 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -184,27 +184,33 @@ legacy_file (const char *filename) } static grub_err_t -grub_cmd_legacy_source (struct grub_command *cmd __attribute__ ((unused)), +grub_cmd_legacy_source (struct grub_command *cmd, int argc, char **args) { - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - return legacy_file (args[0]); -} - -static grub_err_t -grub_cmd_legacy_configfile (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ + int new_env, extractor; grub_err_t ret; + if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - grub_cls (); - grub_env_context_open (); + extractor = (cmd->name[0] == 'e'); + new_env = (cmd->name[extractor ? sizeof ("extract_legacy_entries_") - 1 + : sizeof ("legacy_") - 1] == 'c'); + + if (new_env) + grub_cls (); + + if (new_env && !extractor) + grub_env_context_open (); + if (extractor) + grub_env_extractor_open (!new_env); ret = legacy_file (args[0]); - grub_env_context_close (); + + if (new_env && !extractor) + grub_env_context_close (); + if (extractor) + grub_env_extractor_close (!new_env); return ret; } @@ -730,18 +736,33 @@ grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unuse return GRUB_ERR_NONE; } -static grub_command_t cmd_source, cmd_configfile, cmd_kernel, cmd_initrd; -static grub_command_t cmd_password, cmd_check_password, cmd_initrdnounzip; +static grub_command_t cmd_source, cmd_configfile; +static grub_command_t cmd_source_extract, cmd_configfile_extract; +static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip; +static grub_command_t cmd_password, cmd_check_password; GRUB_MOD_INIT(legacycfg) { - cmd_source = grub_register_command ("legacy_source", - grub_cmd_legacy_source, - N_("FILE"), N_("Parse legacy config")); - cmd_configfile = grub_register_command ("legacy_configfile", - grub_cmd_legacy_configfile, - N_("FILE"), - N_("Parse legacy config")); + cmd_source + = grub_register_command ("legacy_source", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in same context")); + cmd_configfile + = grub_register_command ("legacy_configfile", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in new context")); + cmd_source_extract + = grub_register_command ("extract_legacy_entries_source", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in same context taking onl entries")); + cmd_configfile_extract + = grub_register_command ("extract_legacy_entries_configfile", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in new context taking onl entries")); cmd_kernel = grub_register_command ("legacy_kernel", grub_cmd_legacy_kernel, @@ -773,9 +794,13 @@ GRUB_MOD_FINI(legacycfg) { grub_unregister_command (cmd_source); grub_unregister_command (cmd_configfile); + grub_unregister_command (cmd_source_extract); + grub_unregister_command (cmd_configfile_extract); + grub_unregister_command (cmd_kernel); grub_unregister_command (cmd_initrd); grub_unregister_command (cmd_initrdnounzip); + grub_unregister_command (cmd_password); grub_unregister_command (cmd_check_password); } From fc55cc4c27ef976a9c4d0a9a19c7f87bd3a2400a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 00:47:49 +0200 Subject: [PATCH 0232/1414] Support submenus. * grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New parameter submenu. All users updated. * grub-core/normal/main.c (free_menu): Rename to ... (grub_normal_free_menu): ... this. Made global. * grub-core/normal/menu.c (grub_menu_execute_entry): Open new context if requested. * grub-core/normal/menu_entry.c (screen): New field submenu. (make_screen): Set submenu. (run): Open new context if requested. * include/grub/menu.h (grub_menu_entry): New field submenu. * include/grub/normal.h (grub_normal_free_menu): New proto. --- ChangeLog | 16 ++++++++++ grub-core/commands/legacycfg.c | 4 +-- grub-core/commands/menuentry.c | 56 +++++++++++++++++++++++----------- grub-core/normal/main.c | 6 ++-- grub-core/normal/menu.c | 20 ++++++++++++ grub-core/normal/menu_entry.c | 24 +++++++++++++++ include/grub/menu.h | 2 ++ include/grub/normal.h | 5 ++- 8 files changed, 109 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index df1e4541d..934e3c73a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-09-20 Vladimir Serbinenko + + Support submenus. + + * grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New + parameter submenu. All users updated. + * grub-core/normal/main.c (free_menu): Rename to ... + (grub_normal_free_menu): ... this. Made global. + * grub-core/normal/menu.c (grub_menu_execute_entry): Open new context + if requested. + * grub-core/normal/menu_entry.c (screen): New field submenu. + (make_screen): Set submenu. + (run): Open new context if requested. + * include/grub/menu.h (grub_menu_entry): New field submenu. + * include/grub/normal.h (grub_normal_free_menu): New proto. + 2010-09-20 Vladimir Serbinenko Menu entries extractor. diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index d69dad75b..1b0e968c5 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -118,7 +118,7 @@ legacy_file (const char *filename) } args[0] = oldname; grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, - entrysrc); + entrysrc, 0); grub_free (args); entrysrc[0] = 0; grub_free (oldname); @@ -168,7 +168,7 @@ legacy_file (const char *filename) return grub_errno; } args[0] = entryname; - grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc); + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc, 0); grub_free (args); } diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index f10e05dc3..9718d1eab 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -68,9 +68,9 @@ static struct grub_err_t grub_normal_add_menu_entry (int argc, const char **args, char **classes, const char *users, const char *hotkey, - const char *prefix, const char *sourcecode) + const char *prefix, const char *sourcecode, + int submenu) { - unsigned i; int menu_hotkey = 0; char **menu_args = NULL; char *menu_users = NULL; @@ -93,6 +93,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, if (classes) { + int i; for (i = 0; classes[i]; i++); /* count # of menuentry classes */ menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) * i); if (! menu_classes) @@ -116,6 +117,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, if (hotkey) { + unsigned i; for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++) if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0) { @@ -141,13 +143,16 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, if (! menu_args) goto fail; - for (i = 0; i < argc; i++) - { - menu_args[i] = grub_strdup (args[i]); - if (! menu_args[i]) - goto fail; - } - menu_args[argc] = NULL; + { + int i; + for (i = 0; i < argc; i++) + { + menu_args[i] = grub_strdup (args[i]); + if (! menu_args[i]) + goto fail; + } + menu_args[argc] = NULL; + } /* Add the menu entry at the end of the list. */ while (*last) @@ -166,6 +171,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, (*last)->argc = argc; (*last)->args = menu_args; (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; menu->size++; return GRUB_ERR_NONE; @@ -173,13 +179,19 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, fail: grub_free (menu_sourcecode); - for (i = 0; menu_classes && menu_classes[i].name; i++) - grub_free (menu_classes[i].name); - grub_free (menu_classes); + { + int i; + for (i = 0; menu_classes && menu_classes[i].name; i++) + grub_free (menu_classes[i].name); + grub_free (menu_classes); + } - for (i = 0; menu_args && menu_args[i]; i++) - grub_free (menu_args[i]); - grub_free (menu_args); + { + int i; + for (i = 0; menu_args && menu_args[i]; i++) + grub_free (menu_args[i]); + grub_free (menu_args); + } grub_free (menu_users); grub_free (menu_title); @@ -259,7 +271,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) return grub_normal_add_menu_entry (argc, (const char **) args, ctxt->state[0].args, ctxt->state[1].arg, ctxt->state[2].arg, 0, - ctxt->state[3].arg); + ctxt->state[3].arg, + ctxt->extcmd->cmd->name[0] == 's'); src = args[argc - 1]; args[argc - 1] = NULL; @@ -274,7 +287,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) r = grub_normal_add_menu_entry (argc - 1, (const char **) args, ctxt->state[0].args, ctxt->state[1].arg, - ctxt->state[2].arg, prefix, src + 1); + ctxt->state[2].arg, prefix, src + 1, + ctxt->extcmd->cmd->name[0] == 's'); src[len - 1] = ch; args[argc - 1] = src; @@ -282,7 +296,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) return r; } -static grub_extcmd_t cmd; +static grub_extcmd_t cmd, cmd_sub; void grub_menu_init (void) @@ -291,10 +305,16 @@ grub_menu_init (void) GRUB_COMMAND_FLAG_BLOCKS | GRUB_COMMAND_FLAG_EXTRACTOR, N_("BLOCK"), N_("Define a menuentry."), options); + cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a submenu."), + options); } void grub_menu_fini (void) { grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_sub); } diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index f2e5eaf51..3bfbbeb72 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -123,8 +123,8 @@ grub_file_getline (grub_file_t file) return cmdline; } -static void -free_menu (grub_menu_t menu) +void +grub_normal_free_menu (grub_menu_t menu) { grub_menu_entry_t entry = menu->entry_list; @@ -289,7 +289,7 @@ grub_normal_execute (const char *config, int nested, int batch) { grub_show_menu (menu, nested); if (nested) - free_menu (menu); + grub_normal_free_menu (menu); } } } diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 9c0a2182f..807ad51e0 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -159,6 +159,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry) { grub_err_t err = GRUB_ERR_NONE; int errs_before; + grub_menu_t menu; if (entry->restricted) err = grub_auth_check_authentication (entry->users); @@ -172,6 +173,15 @@ grub_menu_execute_entry(grub_menu_entry_t entry) errs_before = grub_err_printed_errors; + if (entry->submenu) + { + grub_env_context_open (); + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + return; + grub_env_set_menu (menu); + } + grub_env_set ("chosen", entry->title); grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args); @@ -181,6 +191,16 @@ grub_menu_execute_entry(grub_menu_entry_t entry) if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) /* Implicit execution of boot, only if something is loaded. */ grub_command_execute ("boot", 0, 0); + + if (entry->submenu) + { + if (menu && menu->size) + { + grub_show_menu (menu, 1); + grub_normal_free_menu (menu); + } + grub_env_context_close (); + } } /* Execute ENTRY from the menu MENU, falling back to entries specified diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 82506fa6f..096600e09 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -71,6 +71,8 @@ struct screen /* The flag of a completion window. */ int completion_shown; + int submenu; + struct per_term_screen *terms; unsigned nterms; }; @@ -496,6 +498,8 @@ make_screen (grub_menu_entry_t entry) if (! screen) return 0; + screen->submenu = entry->submenu; + screen->num_lines = 1; screen->lines = grub_malloc (sizeof (struct line)); if (! screen->lines) @@ -1162,6 +1166,7 @@ run (struct screen *screen) int currline = 0; char *nextline; int errs_before; + grub_menu_t menu; auto grub_err_t editor_getline (char **line, int cont); grub_err_t editor_getline (char **line, int cont __attribute__ ((unused))) @@ -1197,6 +1202,15 @@ run (struct screen *screen) errs_before = grub_err_printed_errors; + if (screen->submenu) + { + grub_env_context_open (); + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + return; + grub_env_set_menu (menu); + } + /* Execute the script, line for line. */ while (currline < screen->num_lines) { @@ -1212,6 +1226,16 @@ run (struct screen *screen) /* Implicit execution of boot, only if something is loaded. */ grub_command_execute ("boot", 0, 0); + if (screen->submenu) + { + if (menu && menu->size) + { + grub_show_menu (menu, 1); + grub_normal_free_menu (menu); + } + grub_env_context_close (); + } + if (grub_errno != GRUB_ERR_NONE) { grub_print_error (); diff --git a/include/grub/menu.h b/include/grub/menu.h index 608253863..5ff356beb 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -53,6 +53,8 @@ struct grub_menu_entry int hotkey; + int submenu; + /* The next element. */ struct grub_menu_entry *next; }; diff --git a/include/grub/normal.h b/include/grub/normal.h index 2fc289373..187567797 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -119,11 +119,14 @@ extern int grub_extractor_level; grub_err_t grub_normal_add_menu_entry (int argc, const char **args, char **classes, const char *users, const char *hotkey, - const char *prefix, const char *sourcecode); + const char *prefix, const char *sourcecode, + int submenu); grub_err_t grub_normal_set_password (const char *user, const char *password); +void grub_normal_free_menu (grub_menu_t menu); + void grub_normal_auth_init (void); void grub_normal_auth_fini (void); From ade9bd6642ab2c33837b71d5b4ebda2b0cda9806 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 00:58:59 +0200 Subject: [PATCH 0233/1414] * util/grub.d/20_linux_xen.in: Use submenus. --- ChangeLog | 4 ++++ util/grub.d/20_linux_xen.in | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 934e3c73a..4fd29f131 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-20 Vladimir Serbinenko + + * util/grub.d/20_linux_xen.in: Use submenus. + 2010-09-20 Vladimir Serbinenko Support submenus. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index e631c0a4a..5333d44ec 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -104,6 +104,7 @@ while [ "x${xen_list}" != "x" ] ; do xen_dirname=`dirname ${current_xen}` rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname` xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"` + echo "submenu \"Xen ${xen_version}\" {" while [ "x$list" != "x" ] ; do linux=`version_find_latest $list` echo "Found linux image: $linux" >&2 @@ -139,5 +140,6 @@ while [ "x${xen_list}" != "x" ] ; do list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` done + echo "}" xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '` done From 3e0fa5d0e082fe230b7c2f8201defc3b26606dae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 01:02:24 +0200 Subject: [PATCH 0234/1414] * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Use UUID when possible. --- ChangeLog | 4 ++++ util/grub.d/10_kfreebsd.in | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4fd29f131..3c57b6f76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-20 Vladimir Serbinenko + + * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Use UUID when possible. + 2010-09-20 Vladimir Serbinenko * util/grub.d/20_linux_xen.in: Use submenus. diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index e39423999..591fbc4b1 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -144,7 +144,16 @@ while [ "x$list" != "x" ] ; do # filesystem name (empty string for the main filesystem) kfreebsd_device="${kfreebsd_device}$(grub-mkrelpath / | sed -e "s,/*@$,,")" ;; - *) kfreebsd_device=${GRUB_DEVICE} ;; + *) + kfreebsd_device=${kfreebsd_fs}id/${GRUB_DEVICE_UUID} + # Debian GNU/kFreeBSD can't remount root if it's supplied as UUID but + # as an UUID + if [ "x${GRUB_DISTRIBUTOR}" = "xDebian" ] \ + && ! (cat /etc/fstab | awk '!/^[[:space:]]*#/ && $2=="/" { print $1; }' \ + | grep "${kfreebsd_fs}id/${GRUB_DEVICE_UUID}" > /dev/null); then + kfreebsd_device=${GRUB_DEVICE} + fi + ;; esac version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"` From 269004c1580e68f8492b836af2fa62b6a9898418 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 00:09:23 +0100 Subject: [PATCH 0235/1414] Fix po directory handling. * configure.ac: Create po/Makefile.in rather than po/Makefile. * grub-core/gnulib/Makefile.am: Import gettext module. * m4/gnulib-cache.m4: Likewise. * m4/gnulib-comp.m4: Likewise. * m4/gettext.m4: New file, from gnulib. * m4/glibc2.m4: Likewise. * m4/iconv.m4: Likewise. * m4/intdiv0.m4: Likewise. * m4/intl.m4: Likewise. * m4/intldir.m4: Likewise. * m4/intlmacosx.m4: Likewise. * m4/intmax.m4: Likewise. * m4/inttypes-pri.m4: Likewise. * m4/lcmessage.m4: Likewise. * m4/lib-ld.m4: Likewise. * m4/lib-link.m4: Likewise. * m4/lib-prefix.m4: Likewise. * m4/lock.m4: Likewise. * m4/nls.m4: Likewise. * m4/po.m4: Likewise. * m4/printf-posix.m4: Likewise. * m4/progtest.m4: Likewise. * m4/threadlib.m4: Likewise. * m4/uintmax_t.m4: Likewise. * m4/visibility.m4: Likewise. * po/Makefile.am: Remove. * po/Makefile.in.in: New file, from gettext. ($(DOMAIN).pot-update): Support POTFILES-shell. * po/Makevars: New file. * po/POTFILES-shell: Rename to ... * po/POTFILES-shell.in: ... this. Update. * po/POTFILES: Rename to ... * po/POTFILES.in: ... this. Update. * po/Rules-quot: New file, from gettext. * po/boldquot.sed: Likewise. * po/en@boldquot.header: Likewise. * po/en@quot.header: Likewise. * po/insert-header.sin: Likewise. * po/quot.sed: Likewise. * po/remove-potcdate.sin: Likewise. --- ChangeLog | 45 ++ configure.ac | 2 +- grub-core/gnulib/Makefile.am | 25 +- m4/gettext.m4 | 401 ++++++++++++ m4/glibc2.m4 | 30 + m4/gnulib-cache.m4 | 3 +- m4/gnulib-comp.m4 | 28 + m4/iconv.m4 | 256 ++++++++ m4/intdiv0.m4 | 87 +++ m4/intl.m4 | 300 +++++++++ m4/intldir.m4 | 19 + m4/intlmacosx.m4 | 56 ++ m4/intmax.m4 | 36 ++ m4/inttypes-pri.m4 | 42 ++ m4/lcmessage.m4 | 35 + m4/lib-ld.m4 | 109 ++++ m4/lib-link.m4 | 775 +++++++++++++++++++++++ m4/lib-prefix.m4 | 224 +++++++ m4/lock.m4 | 41 ++ m4/nls.m4 | 32 + m4/po.m4 | 449 +++++++++++++ m4/printf-posix.m4 | 48 ++ m4/progtest.m4 | 91 +++ m4/threadlib.m4 | 362 +++++++++++ m4/uintmax_t.m4 | 30 + m4/visibility.m4 | 77 +++ po/Makefile.am | 0 po/Makefile.in.in | 464 ++++++++++++++ po/Makevars | 41 ++ po/POTFILES | 80 --- po/{POTFILES-shell => POTFILES-shell.in} | 2 + po/POTFILES.in | 117 ++++ po/Rules-quot | 47 ++ po/boldquot.sed | 10 + po/en@boldquot.header | 25 + po/en@quot.header | 22 + po/insert-header.sin | 23 + po/quot.sed | 6 + po/remove-potcdate.sin | 19 + 39 files changed, 4376 insertions(+), 83 deletions(-) create mode 100644 m4/gettext.m4 create mode 100644 m4/glibc2.m4 create mode 100644 m4/iconv.m4 create mode 100644 m4/intdiv0.m4 create mode 100644 m4/intl.m4 create mode 100644 m4/intldir.m4 create mode 100644 m4/intlmacosx.m4 create mode 100644 m4/intmax.m4 create mode 100644 m4/inttypes-pri.m4 create mode 100644 m4/lcmessage.m4 create mode 100644 m4/lib-ld.m4 create mode 100644 m4/lib-link.m4 create mode 100644 m4/lib-prefix.m4 create mode 100644 m4/lock.m4 create mode 100644 m4/nls.m4 create mode 100644 m4/po.m4 create mode 100644 m4/printf-posix.m4 create mode 100644 m4/progtest.m4 create mode 100644 m4/threadlib.m4 create mode 100644 m4/uintmax_t.m4 create mode 100644 m4/visibility.m4 delete mode 100644 po/Makefile.am create mode 100644 po/Makefile.in.in create mode 100644 po/Makevars delete mode 100644 po/POTFILES rename po/{POTFILES-shell => POTFILES-shell.in} (78%) create mode 100644 po/POTFILES.in create mode 100644 po/Rules-quot create mode 100644 po/boldquot.sed create mode 100644 po/en@boldquot.header create mode 100644 po/en@quot.header create mode 100644 po/insert-header.sin create mode 100644 po/quot.sed create mode 100644 po/remove-potcdate.sin diff --git a/ChangeLog b/ChangeLog index 3c57b6f76..53f1e1d49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2010-09-21 Colin Watson + + Fix po directory handling. + + * configure.ac: Create po/Makefile.in rather than po/Makefile. + * grub-core/gnulib/Makefile.am: Import gettext module. + * m4/gnulib-cache.m4: Likewise. + * m4/gnulib-comp.m4: Likewise. + * m4/gettext.m4: New file, from gnulib. + * m4/glibc2.m4: Likewise. + * m4/iconv.m4: Likewise. + * m4/intdiv0.m4: Likewise. + * m4/intl.m4: Likewise. + * m4/intldir.m4: Likewise. + * m4/intlmacosx.m4: Likewise. + * m4/intmax.m4: Likewise. + * m4/inttypes-pri.m4: Likewise. + * m4/lcmessage.m4: Likewise. + * m4/lib-ld.m4: Likewise. + * m4/lib-link.m4: Likewise. + * m4/lib-prefix.m4: Likewise. + * m4/lock.m4: Likewise. + * m4/nls.m4: Likewise. + * m4/po.m4: Likewise. + * m4/printf-posix.m4: Likewise. + * m4/progtest.m4: Likewise. + * m4/threadlib.m4: Likewise. + * m4/uintmax_t.m4: Likewise. + * m4/visibility.m4: Likewise. + * po/Makefile.am: Remove. + * po/Makefile.in.in: New file, from gettext. + ($(DOMAIN).pot-update): Support POTFILES-shell. + * po/Makevars: New file. + * po/POTFILES-shell: Rename to ... + * po/POTFILES-shell.in: ... this. Update. + * po/POTFILES: Rename to ... + * po/POTFILES.in: ... this. Update. + * po/Rules-quot: New file, from gettext. + * po/boldquot.sed: Likewise. + * po/en@boldquot.header: Likewise. + * po/en@quot.header: Likewise. + * po/insert-header.sin: Likewise. + * po/quot.sed: Likewise. + * po/remove-potcdate.sin: Likewise. + 2010-09-20 Vladimir Serbinenko * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Use UUID when possible. diff --git a/configure.ac b/configure.ac index ad48c6298..dc433317b 100644 --- a/configure.ac +++ b/configure.ac @@ -934,7 +934,7 @@ fi AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([grub-core/Makefile]) AC_CONFIG_FILES([grub-core/gnulib/Makefile]) -AC_CONFIG_FILES([po/Makefile]) +AC_CONFIG_FILES([po/Makefile.in]) AC_CONFIG_FILES([docs/Makefile]) AC_CONFIG_FILES([util/bash-completion.d/Makefile]) AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) diff --git a/grub-core/gnulib/Makefile.am b/grub-core/gnulib/Makefile.am index e990aefb1..fb1525f00 100644 --- a/grub-core/gnulib/Makefile.am +++ b/grub-core/gnulib/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline progname regex +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex AUTOMAKE_OPTIONS = 1.5 gnits @@ -322,12 +322,35 @@ EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c ## end gnulib module getopt-posix +## begin gnulib module gettext + +# This is for those projects which use "gettextize --intl" to put a source-code +# copy of libintl into their package. In such projects, every Makefile.am needs +# -I$(top_builddir)/intl, so that can be found in this directory. +# For the Makefile.ams in other directories it is the maintainer's +# responsibility; for the one from gnulib we do it here. +# This option has no effect when the user disables NLS (because then the intl +# directory contains no libintl.h file) or when the project does not use +# "gettextize --intl". +AM_CPPFLAGS += -I$(top_builddir)/intl + +EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath + +## end gnulib module gettext + ## begin gnulib module gettext-h libgnu_a_SOURCES += gettext.h ## end gnulib module gettext-h +## begin gnulib module havelib + + +EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath + +## end gnulib module havelib + ## begin gnulib module intprops diff --git a/m4/gettext.m4 b/m4/gettext.m4 new file mode 100644 index 000000000..979c52c19 --- /dev/null +++ b/m4/gettext.m4 @@ -0,0 +1,401 @@ +# gettext.m4 serial 64 (gettext-0.18.2) +dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2006, 2008-2010. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], + [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define([gt_included_intl], + ifelse([$1], [external], + ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), + [yes])) + define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) + gt_NEEDS_INIT + AM_GNU_GETTEXT_NEED([$2]) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. + AC_REQUIRE([AM_NLS]) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl Add a version number to the cache macros. + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH([included-gettext], + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings + ]])], + [eval "$gt_func_gnugettext_libc=yes"], + [eval "$gt_func_gnugettext_libc=no"])]) + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + [$gt_func_gnugettext_libintl], + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") + ]])], + [eval "$gt_func_gnugettext_libintl=yes"], + [eval "$gt_func_gnugettext_libintl=no"]) + dnl Now see whether libintl exists and depends on libiconv. + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); + ]], + [[ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") + ]])], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + CATOBJEXT= + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Some extra flags are needed during linking. + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE([ENABLE_NLS], [1], + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE([HAVE_GETTEXT], [1], + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE([HAVE_DCGETTEXT], [1], + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST([BUILD_INCLUDED_LIBINTL]) + AC_SUBST([USE_INCLUDED_LIBINTL]) + AC_SUBST([CATOBJEXT]) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST([DATADIRNAME]) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST([INSTOBJEXT]) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST([GENCAT]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLOBJS= + if test "$USE_INCLUDED_LIBINTL" = yes; then + INTLOBJS="\$(GETTOBJS)" + fi + AC_SUBST([INTLOBJS]) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX]) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST([INTLLIBS]) + + dnl Make all documented variables known to autoconf. + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_SUBST([POSUB]) +]) + + +dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. +m4_define([gt_NEEDS_INIT], +[ + m4_divert_text([DEFAULTS], [gt_needs=]) + m4_define([gt_NEEDS_INIT], []) +]) + + +dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) +AC_DEFUN([AM_GNU_GETTEXT_NEED], +[ + m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/m4/glibc2.m4 b/m4/glibc2.m4 new file mode 100644 index 000000000..f148c12c4 --- /dev/null +++ b/m4/glibc2.m4 @@ -0,0 +1,30 @@ +# glibc2.m4 serial 2 +dnl Copyright (C) 2000-2002, 2004, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Test for the GNU C Library, version 2.0 or newer. +# From Bruno Haible. + +AC_DEFUN([gt_GLIBC2], + [ + AC_CACHE_CHECK([whether we are using the GNU C Library 2 or newer], + [ac_cv_gnu_library_2], + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) + Lucky GNU user + #endif +#endif + ], + [ac_cv_gnu_library_2=yes], + [ac_cv_gnu_library_2=no]) + ] + ) + AC_SUBST([GLIBC2]) + GLIBC2="$ac_cv_gnu_library_2" + ] +) diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index 799c4f954..3c094bc19 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -15,7 +15,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline progname regex +# gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) @@ -25,6 +25,7 @@ gl_MODULES([ fnmatch getdelim getline + gettext progname regex ]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index d77510f20..d3490c932 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -45,7 +45,9 @@ AC_DEFUN([gl_EARLY], # Code from module getline: # Code from module getopt-gnu: # Code from module getopt-posix: + # Code from module gettext: # Code from module gettext-h: + # Code from module havelib: # Code from module include_next: # Code from module intprops: # Code from module langinfo: @@ -150,9 +152,13 @@ AC_DEFUN([gl_INIT], gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) # Code from module getopt-posix: gl_FUNC_GETOPT_POSIX + # Code from module gettext: + dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac. + AM_GNU_GETTEXT_VERSION([0.18.1]) # Code from module gettext-h: AC_SUBST([LIBINTL]) AC_SUBST([LTLIBINTL]) + # Code from module havelib: # Code from module include_next: # Code from module intprops: # Code from module langinfo: @@ -400,6 +406,7 @@ AC_DEFUN([gltests_LIBSOURCES], [ AC_DEFUN([gl_FILE_LIST], [ build-aux/arg-nonnull.h build-aux/c++defs.h + build-aux/config.rpath build-aux/warn-on-use.h lib/alloca.c lib/alloca.in.h @@ -517,16 +524,30 @@ AC_DEFUN([gl_FILE_LIST], [ m4/getdelim.m4 m4/getline.m4 m4/getopt.m4 + m4/gettext.m4 + m4/glibc2.m4 m4/glibc21.m4 m4/gnulib-common.m4 + m4/iconv.m4 m4/include_next.m4 + m4/intdiv0.m4 + m4/intl.m4 + m4/intldir.m4 + m4/intlmacosx.m4 + m4/intmax.m4 m4/intmax_t.m4 + m4/inttypes-pri.m4 m4/inttypes_h.m4 m4/langinfo_h.m4 + m4/lcmessage.m4 + m4/lib-ld.m4 + m4/lib-link.m4 + m4/lib-prefix.m4 m4/localcharset.m4 m4/locale-fr.m4 m4/locale-ja.m4 m4/locale-zh.m4 + m4/lock.m4 m4/longlong.m4 m4/malloc.m4 m4/mbrtowc.m4 @@ -538,7 +559,11 @@ AC_DEFUN([gl_FILE_LIST], [ m4/mmap-anon.m4 m4/multiarch.m4 m4/nl_langinfo.m4 + m4/nls.m4 + m4/po.m4 + m4/printf-posix.m4 m4/printf.m4 + m4/progtest.m4 m4/rawmemchr.m4 m4/realloc.m4 m4/regex.m4 @@ -560,8 +585,11 @@ AC_DEFUN([gl_FILE_LIST], [ m4/strnlen.m4 m4/sys_wait_h.m4 m4/sysexits.m4 + m4/threadlib.m4 + m4/uintmax_t.m4 m4/unistd_h.m4 m4/vasnprintf.m4 + m4/visibility.m4 m4/vsnprintf.m4 m4/warn-on-use.m4 m4/wchar_h.m4 diff --git a/m4/iconv.m4 b/m4/iconv.m4 new file mode 100644 index 000000000..425145c0a --- /dev/null +++ b/m4/iconv.m4 @@ -0,0 +1,256 @@ +# iconv.m4 serial 15 (gettext-0.18.2) +dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);]])], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, + dnl Solaris 10. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\263"; + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + const char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +}]])], + [am_cv_func_iconv_works=yes], + [am_cv_func_iconv_works=no], + [ +changequote(,)dnl + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +changequote([,])dnl + ]) + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to +dnl avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +dnl This is tricky because of the way 'aclocal' is implemented: +dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. +dnl Otherwise aclocal's initial scan pass would miss the macro definition. +dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. +dnl Otherwise aclocal would emit many "Use of uninitialized value $1" +dnl warnings. +m4_define([gl_iconv_AC_DEFUN], + m4_version_prereq([2.64], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [m4_ifdef([gl_00GNULIB], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [[AC_DEFUN( + [$1], [$2])]])])) +gl_iconv_AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + ]], + [[]])], + [am_cv_proto_iconv_arg1=""], + [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4 new file mode 100644 index 000000000..9b27ff1b7 --- /dev/null +++ b/m4/intdiv0.m4 @@ -0,0 +1,87 @@ +# intdiv0.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2002, 2007-2008, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gt_INTDIV0], +[ + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + + AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], + gt_cv_int_divbyzero_sigfpe, + [ + gt_cv_int_divbyzero_sigfpe= +changequote(,)dnl + case "$host_os" in + macos* | darwin[6-9]* | darwin[1-9][0-9]*) + # On MacOS X 10.2 or newer, just assume the same as when cross- + # compiling. If we were to perform the real test, 1 Crash Report + # dialog window would pop up. + case "$host_cpu" in + i[34567]86 | x86_64) + gt_cv_int_divbyzero_sigfpe="guessing yes" ;; + esac + ;; + esac +changequote([,])dnl + if test -z "$gt_cv_int_divbyzero_sigfpe"; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include + +static void +sigfpe_handler (int sig) +{ + /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ + exit (sig != SIGFPE); +} + +int x = 1; +int y = 0; +int z; +int nan; + +int main () +{ + signal (SIGFPE, sigfpe_handler); +/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ +#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) + signal (SIGTRAP, sigfpe_handler); +#endif +/* Linux/SPARC yields signal SIGILL. */ +#if defined (__sparc__) && defined (__linux__) + signal (SIGILL, sigfpe_handler); +#endif + + z = x / y; + nan = y / y; + exit (1); +} +]])], + [gt_cv_int_divbyzero_sigfpe=yes], + [gt_cv_int_divbyzero_sigfpe=no], + [ + # Guess based on the CPU. +changequote(,)dnl + case "$host_cpu" in + alpha* | i[34567]86 | x86_64 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; + esac +changequote([,])dnl + ]) + fi + ]) + case "$gt_cv_int_divbyzero_sigfpe" in + *yes) value=1;; + *) value=0;; + esac + AC_DEFINE_UNQUOTED([INTDIV0_RAISES_SIGFPE], [$value], + [Define if integer division by zero raises signal SIGFPE.]) +]) diff --git a/m4/intl.m4 b/m4/intl.m4 new file mode 100644 index 000000000..d84bc4a9b --- /dev/null +++ b/m4/intl.m4 @@ -0,0 +1,300 @@ +# intl.m4 serial 17b +dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2009. + +AC_PREREQ([2.53]) + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([gt_GLIBC2])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([gl_VISIBILITY])dnl + AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl + AC_REQUIRE([AC_TYPE_LONG_LONG_INT])dnl + AC_REQUIRE([gt_TYPE_WCHAR_T])dnl + AC_REQUIRE([gt_TYPE_WINT_T])dnl + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gt_TYPE_INTMAX_T]) + AC_REQUIRE([gt_PRINTF_POSIX]) + AC_REQUIRE([gl_GLIBC21])dnl + AC_REQUIRE([gl_XSIZE])dnl + AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl + AC_REQUIRE([gt_INTL_MACOSX])dnl + + dnl Support for automake's --enable-silent-rules. + case "$enable_silent_rules" in + yes) INTL_DEFAULT_VERBOSITY=0;; + no) INTL_DEFAULT_VERBOSITY=1;; + *) INTL_DEFAULT_VERBOSITY=1;; + esac + AC_SUBST([INTL_DEFAULT_VERBOSITY]) + + AC_CHECK_TYPE([ptrdiff_t], , + [AC_DEFINE([ptrdiff_t], [long], + [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) + ]) + AC_CHECK_HEADERS([stddef.h stdlib.h string.h]) + AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \ + snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) + + dnl Use the _snprintf function only if it is declared (because on NetBSD it + dnl is defined as a weak alias of snprintf; we prefer to use the latter). + gt_CHECK_DECL(_snprintf, [#include ]) + gt_CHECK_DECL(_snwprintf, [#include ]) + + dnl Use the *_unlocked functions only if they are declared. + dnl (because some of them were defined without being declared in Solaris + dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built + dnl on Solaris 2.5.1 to run on Solaris 2.6). + dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. + gt_CHECK_DECL(getc_unlocked, [#include ]) + + case $gt_cv_func_printf_posix in + *yes) HAVE_POSIX_PRINTF=1 ;; + *) HAVE_POSIX_PRINTF=0 ;; + esac + AC_SUBST([HAVE_POSIX_PRINTF]) + if test "$ac_cv_func_asprintf" = yes; then + HAVE_ASPRINTF=1 + else + HAVE_ASPRINTF=0 + fi + AC_SUBST([HAVE_ASPRINTF]) + if test "$ac_cv_func_snprintf" = yes; then + HAVE_SNPRINTF=1 + else + HAVE_SNPRINTF=0 + fi + AC_SUBST([HAVE_SNPRINTF]) + if test "$ac_cv_func_newlocale" = yes; then + HAVE_NEWLOCALE=1 + else + HAVE_NEWLOCALE=0 + fi + AC_SUBST([HAVE_NEWLOCALE]) + if test "$ac_cv_func_wprintf" = yes; then + HAVE_WPRINTF=1 + else + HAVE_WPRINTF=0 + fi + AC_SUBST([HAVE_WPRINTF]) + + AM_LANGINFO_CODESET + gt_LC_MESSAGES + + dnl Compilation on mingw and Cygwin needs special Makefile rules, because + dnl 1. when we install a shared library, we must arrange to export + dnl auxiliary pointer variables for every exported variable, + dnl 2. when we install a shared library and a static library simultaneously, + dnl the include file specifies __declspec(dllimport) and therefore we + dnl must arrange to define the auxiliary pointer variables for the + dnl exported variables _also_ in the static library. + if test "$enable_shared" = yes; then + case "$host_os" in + mingw* | cygwin*) is_woe32dll=yes ;; + *) is_woe32dll=no ;; + esac + else + is_woe32dll=no + fi + WOE32DLL=$is_woe32dll + AC_SUBST([WOE32DLL]) + + dnl On mingw and Cygwin, we can activate special Makefile rules which add + dnl version information to the shared libraries and executables. + case "$host_os" in + mingw* | cygwin*) is_woe32=yes ;; + *) is_woe32=no ;; + esac + WOE32=$is_woe32 + AC_SUBST([WOE32]) + if test $WOE32 = yes; then + dnl Check for a program that compiles Windows resource files. + AC_CHECK_TOOL([WINDRES], [windres]) + fi + + dnl Determine whether when creating a library, "-lc" should be passed to + dnl libtool or not. On many platforms, it is required for the libtool option + dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool + dnl in the *.la files - makes it impossible to create multithreaded programs, + dnl because libtool also reorders the -lc to come before the -pthread, and + dnl this disables pthread_create() . + case "$host_os" in + hpux*) LTLIBC="" ;; + *) LTLIBC="-lc" ;; + esac + AC_SUBST([LTLIBC]) + + dnl Rename some macros and functions used for locking. + AH_BOTTOM([ +#define __libc_lock_t gl_lock_t +#define __libc_lock_define gl_lock_define +#define __libc_lock_define_initialized gl_lock_define_initialized +#define __libc_lock_init gl_lock_init +#define __libc_lock_lock gl_lock_lock +#define __libc_lock_unlock gl_lock_unlock +#define __libc_lock_recursive_t gl_recursive_lock_t +#define __libc_lock_define_recursive gl_recursive_lock_define +#define __libc_lock_define_initialized_recursive gl_recursive_lock_define_initialized +#define __libc_lock_init_recursive gl_recursive_lock_init +#define __libc_lock_lock_recursive gl_recursive_lock_lock +#define __libc_lock_unlock_recursive gl_recursive_lock_unlock +#define glthread_in_use libintl_thread_in_use +#define glthread_lock_init_func libintl_lock_init_func +#define glthread_lock_lock_func libintl_lock_lock_func +#define glthread_lock_unlock_func libintl_lock_unlock_func +#define glthread_lock_destroy_func libintl_lock_destroy_func +#define glthread_rwlock_init_multithreaded libintl_rwlock_init_multithreaded +#define glthread_rwlock_init_func libintl_rwlock_init_func +#define glthread_rwlock_rdlock_multithreaded libintl_rwlock_rdlock_multithreaded +#define glthread_rwlock_rdlock_func libintl_rwlock_rdlock_func +#define glthread_rwlock_wrlock_multithreaded libintl_rwlock_wrlock_multithreaded +#define glthread_rwlock_wrlock_func libintl_rwlock_wrlock_func +#define glthread_rwlock_unlock_multithreaded libintl_rwlock_unlock_multithreaded +#define glthread_rwlock_unlock_func libintl_rwlock_unlock_func +#define glthread_rwlock_destroy_multithreaded libintl_rwlock_destroy_multithreaded +#define glthread_rwlock_destroy_func libintl_rwlock_destroy_func +#define glthread_recursive_lock_init_multithreaded libintl_recursive_lock_init_multithreaded +#define glthread_recursive_lock_init_func libintl_recursive_lock_init_func +#define glthread_recursive_lock_lock_multithreaded libintl_recursive_lock_lock_multithreaded +#define glthread_recursive_lock_lock_func libintl_recursive_lock_lock_func +#define glthread_recursive_lock_unlock_multithreaded libintl_recursive_lock_unlock_multithreaded +#define glthread_recursive_lock_unlock_func libintl_recursive_lock_unlock_func +#define glthread_recursive_lock_destroy_multithreaded libintl_recursive_lock_destroy_multithreaded +#define glthread_recursive_lock_destroy_func libintl_recursive_lock_destroy_func +#define glthread_once_func libintl_once_func +#define glthread_once_singlethreaded libintl_once_singlethreaded +#define glthread_once_multithreaded libintl_once_multithreaded +]) +]) + + +dnl Checks for the core files of the intl subdirectory: +dnl dcigettext.c +dnl eval-plural.h +dnl explodename.c +dnl finddomain.c +dnl gettextP.h +dnl gmo.h +dnl hash-string.h hash-string.c +dnl l10nflist.c +dnl libgnuintl.h.in (except the *printf stuff) +dnl loadinfo.h +dnl loadmsgcat.c +dnl localealias.c +dnl log.c +dnl plural-exp.h plural-exp.c +dnl plural.y +dnl Used by libglocale. +AC_DEFUN([gt_INTL_SUBDIR_CORE], +[ + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + AC_REQUIRE([gl_LOCK])dnl + + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }]], + [[]])], + [AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], + [Define to 1 if the compiler understands __builtin_expect.])]) + + AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \ + stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \ + argz_stringify argz_next __fsetlocking]) + + dnl Use the *_unlocked functions only if they are declared. + dnl (because some of them were defined without being declared in Solaris + dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built + dnl on Solaris 2.5.1 to run on Solaris 2.6). + dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. + gt_CHECK_DECL([feof_unlocked], [#include ]) + gt_CHECK_DECL([fgets_unlocked], [#include ]) + + AM_ICONV + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +dnl gt_CHECK_DECL(FUNC, INCLUDES) +dnl Check whether a function is declared. +AC_DEFUN([gt_CHECK_DECL], +[ + AC_CACHE_CHECK([whether $1 is declared], [ac_cv_have_decl_$1], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[$2]], + [[ +#ifndef $1 + char *p = (char *) $1; +#endif + ]])], + [ac_cv_have_decl_$1=yes], + [ac_cv_have_decl_$1=no])]) + if test $ac_cv_have_decl_$1 = yes; then + gt_value=1 + else + gt_value=0 + fi + AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value], + [Define to 1 if you have the declaration of `$1', and to 0 if you don't.]) +]) diff --git a/m4/intldir.m4 b/m4/intldir.m4 new file mode 100644 index 000000000..ebae76d36 --- /dev/null +++ b/m4/intldir.m4 @@ -0,0 +1,19 @@ +# intldir.m4 serial 2 (gettext-0.18) +dnl Copyright (C) 2006, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +AC_PREREQ([2.52]) + +dnl Tells the AM_GNU_GETTEXT macro to consider an intl/ directory. +AC_DEFUN([AM_GNU_GETTEXT_INTL_SUBDIR], []) diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4 new file mode 100644 index 000000000..f0f7c9872 --- /dev/null +++ b/m4/intlmacosx.m4 @@ -0,0 +1,56 @@ +# intlmacosx.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2004-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Checks for special options needed on MacOS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in MacOS X 10.2. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFPreferencesCopyAppValue(NULL, NULL)]])], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], + [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Check for API introduced in MacOS X 10.3. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[CFLocaleCopyCurrent();]])], + [gt_cv_func_CFLocaleCopyCurrent=yes], + [gt_cv_func_CFLocaleCopyCurrent=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], + [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) diff --git a/m4/intmax.m4 b/m4/intmax.m4 new file mode 100644 index 000000000..2c0f2afe5 --- /dev/null +++ b/m4/intmax.m4 @@ -0,0 +1,36 @@ +# intmax.m4 serial 6 (gettext-0.18.2) +dnl Copyright (C) 2002-2005, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. +dnl Test whether the system has the 'intmax_t' type, but don't attempt to +dnl find a replacement if it is lacking. + +AC_DEFUN([gt_TYPE_INTMAX_T], +[ + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +#include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +#include +#endif + ]], + [[intmax_t x = -1; + return !x;]])], + [gt_cv_c_intmax_t=yes], + [gt_cv_c_intmax_t=no])]) + if test $gt_cv_c_intmax_t = yes; then + AC_DEFINE([HAVE_INTMAX_T], [1], + [Define if you have the 'intmax_t' type in or .]) + fi +]) diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4 new file mode 100644 index 000000000..ee96bcd97 --- /dev/null +++ b/m4/inttypes-pri.m4 @@ -0,0 +1,42 @@ +# inttypes-pri.m4 serial 7 (gettext-0.18.2) +dnl Copyright (C) 1997-2002, 2006, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.53]) + +# Define PRI_MACROS_BROKEN if exists and defines the PRI* +# macros to non-string values. This is the case on AIX 4.3.3. + +AC_DEFUN([gt_INTTYPES_PRI], +[ + AC_CHECK_HEADERS([inttypes.h]) + if test $ac_cv_header_inttypes_h = yes; then + AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], + [gt_cv_inttypes_pri_broken], + [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#ifdef PRId32 +char *p = PRId32; +#endif + ]], + [[]])], + [gt_cv_inttypes_pri_broken=no], + [gt_cv_inttypes_pri_broken=yes]) + ]) + fi + if test "$gt_cv_inttypes_pri_broken" = yes; then + AC_DEFINE_UNQUOTED([PRI_MACROS_BROKEN], [1], + [Define if exists and defines unusable PRI* macros.]) + PRI_MACROS_BROKEN=1 + else + PRI_MACROS_BROKEN=0 + fi + AC_SUBST([PRI_MACROS_BROKEN]) +]) diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 new file mode 100644 index 000000000..232da73b6 --- /dev/null +++ b/m4/lcmessage.m4 @@ -0,0 +1,35 @@ +# lcmessage.m4 serial 7 (gettext-0.18.2) +dnl Copyright (C) 1995-2002, 2004-2005, 2008-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995. + +# Check whether LC_MESSAGES is available in . + +AC_DEFUN([gt_LC_MESSAGES], +[ + AC_CACHE_CHECK([for LC_MESSAGES], [gt_cv_val_LC_MESSAGES], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[return LC_MESSAGES]])], + [gt_cv_val_LC_MESSAGES=yes], + [gt_cv_val_LC_MESSAGES=no])]) + if test $gt_cv_val_LC_MESSAGES = yes; then + AC_DEFINE([HAVE_LC_MESSAGES], [1], + [Define if your file defines LC_MESSAGES.]) + fi +]) diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 new file mode 100644 index 000000000..294db72e1 --- /dev/null +++ b/m4/lib-ld.m4 @@ -0,0 +1,109 @@ +# lib-ld.m4 serial 5 (gettext-0.18.2) +dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 /dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL([acl_cv_path_LD], +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/m4/lib-link.m4 b/m4/lib-link.m4 new file mode 100644 index 000000000..2ea9d6d07 --- /dev/null +++ b/m4/lib-link.m4 @@ -0,0 +1,775 @@ +# lib-link.m4 serial 25 (gettext-0.18.2) +dnl Copyright (C) 2001-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.54]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. The missing-message +dnl defaults to 'no' and may contain additional hints for the user. +dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} +dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, + dnl because these -l options might require -L options that are present in + dnl LIBS. -l options benefit only from the -L options listed before it. + dnl Otherwise, add it to the front of LIBS, because it may be a static + dnl library that depends on another static library that is present in LIBS. + dnl Static libraries benefit only from the static libraries listed after + dnl it. + case " $LIB[]NAME" in + *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; + *) LIBS="$LIB[]NAME $LIBS" ;; + esac + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[$3]], [[$4]])], + [ac_cv_lib[]Name=yes], + [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 new file mode 100644 index 000000000..1601ceaef --- /dev/null +++ b/m4/lib-prefix.m4 @@ -0,0 +1,224 @@ +# lib-prefix.m4 serial 7 (gettext-0.18) +dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl . + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_EGREP_CPP([sixtyfour bits], [ +#ifdef _LP64 +sixtyfour bits +#endif + ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +]) diff --git a/m4/lock.m4 b/m4/lock.m4 new file mode 100644 index 000000000..f71c66459 --- /dev/null +++ b/m4/lock.m4 @@ -0,0 +1,41 @@ +# lock.m4 serial 11 (gettext-0.18.2) +dnl Copyright (C) 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gl_LOCK], +[ + AC_REQUIRE([gl_THREADLIB]) + if test "$gl_threads_api" = posix; then + # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the + # pthread_rwlock_* functions. + AC_CHECK_TYPE([pthread_rwlock_t], + [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1], + [Define if the POSIX multithreading library has read/write locks.])], + [], + [#include ]) + # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro. + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[#include ]], + [[ +#if __FreeBSD__ == 4 +error "No, in FreeBSD 4.0 recursive mutexes actually don't work." +#else +int x = (int)PTHREAD_MUTEX_RECURSIVE; +return !x; +#endif + ]])], + [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1], + [Define if the defines PTHREAD_MUTEX_RECURSIVE.])]) + fi + gl_PREREQ_LOCK +]) + +# Prerequisites of lib/lock.c. +AC_DEFUN([gl_PREREQ_LOCK], [ + AC_REQUIRE([AC_C_INLINE]) +]) diff --git a/m4/nls.m4 b/m4/nls.m4 new file mode 100644 index 000000000..003704c4b --- /dev/null +++ b/m4/nls.m4 @@ -0,0 +1,32 @@ +# nls.m4 serial 5 (gettext-0.18) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) diff --git a/m4/po.m4 b/m4/po.m4 new file mode 100644 index 000000000..47f36a41a --- /dev/null +++ b/m4/po.m4 @@ -0,0 +1,449 @@ +# po.m4 serial 17 (gettext-0.18) +dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.50]) + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + AC_REQUIRE([AM_NLS])dnl + + dnl Release version of the gettext macros. This is used to ensure that + dnl the gettext macros and po/Makefile.in.in are in sync. + AC_SUBST([GETTEXT_MACRO_VERSION], [0.18]) + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) + + dnl Test whether it is GNU msgfmt >= 0.15. +changequote(,)dnl + case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; + *) MSGFMT_015=$MSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([MSGFMT_015]) +changequote(,)dnl + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([GMSGFMT_015]) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Test whether it is GNU xgettext >= 0.15. +changequote(,)dnl + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac +changequote([,])dnl + AC_SUBST([XGETTEXT_015]) + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) + + dnl Installation directories. + dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we + dnl have to define it here, so that it can be used in po/Makefile. + test -n "$localedir" || localedir='${datadir}/locale' + AC_SUBST([localedir]) + + dnl Support for AM_XGETTEXT_OPTION. + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) + + AC_CONFIG_COMMANDS([po-directories], [[ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done]], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake < 1.5. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat < "$ac_file.tmp" + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" < /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + cat >> "$ac_file.tmp" <> "$ac_file.tmp" < +#include +/* The string "%2$d %1$d", with dollar characters protected from the shell's + dollar expansion (possibly an autoconf bug). */ +static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; +static char buf[100]; +int main () +{ + sprintf (buf, format, 33, 55); + return (strcmp (buf, "55 33") != 0); +}]])], + [gt_cv_func_printf_posix=yes], + [gt_cv_func_printf_posix=no], + [ + AC_EGREP_CPP([notposix], [ +#if defined __NetBSD__ || defined __BEOS__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ + notposix +#endif + ], + [gt_cv_func_printf_posix="guessing no"], + [gt_cv_func_printf_posix="guessing yes"]) + ]) + ]) + case $gt_cv_func_printf_posix in + *yes) + AC_DEFINE([HAVE_POSIX_PRINTF], [1], + [Define if your printf() function supports format strings with positions.]) + ;; + esac +]) diff --git a/m4/progtest.m4 b/m4/progtest.m4 new file mode 100644 index 000000000..9ffa5c020 --- /dev/null +++ b/m4/progtest.m4 @@ -0,0 +1,91 @@ +# progtest.m4 serial 7 (gettext-0.18.2) +dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1996. + +AC_PREREQ([2.50]) + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL([ac_cv_path_$1], +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$][$1]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST([$1])dnl +]) diff --git a/m4/threadlib.m4 b/m4/threadlib.m4 new file mode 100644 index 000000000..bff01bc5e --- /dev/null +++ b/m4/threadlib.m4 @@ -0,0 +1,362 @@ +# threadlib.m4 serial 6 (gettext-0.18.2) +dnl Copyright (C) 2005-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl gl_THREADLIB +dnl ------------ +dnl Tests for a multithreading library to be used. +dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS, +dnl USE_PTH_THREADS, USE_WIN32_THREADS +dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use +dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with +dnl libtool). +dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for +dnl programs that really need multithread functionality. The difference +dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak +dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread". +dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for +dnl multithread-safe programs. + +AC_DEFUN([gl_THREADLIB_EARLY], +[ + AC_REQUIRE([gl_THREADLIB_EARLY_BODY]) +]) + +dnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once. + +AC_DEFUN([gl_THREADLIB_EARLY_BODY], +[ + dnl Ordering constraints: This macro modifies CPPFLAGS in a way that + dnl influences the result of the autoconf tests that test for *_unlocked + dnl declarations, on AIX 5 at least. Therefore it must come early. + AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl + AC_BEFORE([$0], [gl_ARGP])dnl + + AC_REQUIRE([AC_CANONICAL_HOST]) + dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems. + dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes + dnl AC_GNU_SOURCE. + m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], + [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], + [AC_REQUIRE([AC_GNU_SOURCE])]) + dnl Check for multithreading. + m4_divert_text([DEFAULTS], [gl_use_threads_default=]) + AC_ARG_ENABLE([threads], +AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API]) +AC_HELP_STRING([--disable-threads], [build without multithread safety]), + [gl_use_threads=$enableval], + [if test -n "$gl_use_threads_default"; then + gl_use_threads="$gl_use_threads_default" + else +changequote(,)dnl + case "$host_os" in + dnl Disable multithreading by default on OSF/1, because it interferes + dnl with fork()/exec(): When msgexec is linked with -lpthread, its + dnl child process gets an endless segmentation fault inside execvp(). + dnl Disable multithreading by default on Cygwin 1.5.x, because it has + dnl bugs that lead to endless loops or crashes. See + dnl . + osf*) gl_use_threads=no ;; + cygwin*) + case `uname -r` in + 1.[0-5].*) gl_use_threads=no ;; + *) gl_use_threads=yes ;; + esac + ;; + *) gl_use_threads=yes ;; + esac +changequote([,])dnl + fi + ]) + if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then + # For using : + case "$host_os" in + osf*) + # On OSF/1, the compiler needs the flag -D_REENTRANT so that it + # groks . cc also understands the flag -pthread, but + # we don't use it because 1. gcc-2.95 doesn't understand -pthread, + # 2. putting a flag into CPPFLAGS that has an effect on the linker + # causes the AC_LINK_IFELSE test below to succeed unexpectedly, + # leading to wrong values of LIBTHREAD and LTLIBTHREAD. + CPPFLAGS="$CPPFLAGS -D_REENTRANT" + ;; + esac + # Some systems optimize for single-threaded programs by default, and + # need special flags to disable these optimizations. For example, the + # definition of 'errno' in . + case "$host_os" in + aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; + solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; + esac + fi +]) + +dnl The guts of gl_THREADLIB. Needs to be expanded only once. + +AC_DEFUN([gl_THREADLIB_BODY], +[ + AC_REQUIRE([gl_THREADLIB_EARLY_BODY]) + gl_threads_api=none + LIBTHREAD= + LTLIBTHREAD= + LIBMULTITHREAD= + LTLIBMULTITHREAD= + if test "$gl_use_threads" != no; then + dnl Check whether the compiler and linker support weak declarations. + AC_CACHE_CHECK([whether imported symbols can be declared weak], + [gl_cv_have_weak], + [gl_cv_have_weak=no + dnl First, test whether the compiler accepts it syntactically. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern void xyzzy (); +#pragma weak xyzzy]], + [[xyzzy();]])], + [gl_cv_have_weak=maybe]) + if test $gl_cv_have_weak = maybe; then + dnl Second, test whether it actually works. On Cygwin 1.7.2, with + dnl gcc 4.3, symbols declared weak always evaluate to the address 0. + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#pragma weak fputs +int main () +{ + return (fputs == NULL); +}]])], + [gl_cv_have_weak=yes], + [gl_cv_have_weak=no], + [dnl When cross-compiling, assume that only ELF platforms support + dnl weak symbols. + AC_EGREP_CPP([Extensible Linking Format], + [#ifdef __ELF__ + Extensible Linking Format + #endif + ], + [gl_cv_have_weak="guessing yes"], + [gl_cv_have_weak="guessing no"]) + ]) + fi + ]) + if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then + # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that + # it groks . It's added above, in gl_THREADLIB_EARLY_BODY. + AC_CHECK_HEADER([pthread.h], + [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) + if test "$gl_have_pthread_h" = yes; then + # Other possible tests: + # -lpthreads (FSU threads, PCthreads) + # -lgthreads + gl_have_pthread= + # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist + # in libc. IRIX 6.5 has the first one in both libc and libpthread, but + # the second one only in libpthread, and lock.c needs it. + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[pthread_mutex_lock((pthread_mutex_t*)0); + pthread_mutexattr_init((pthread_mutexattr_t*)0);]])], + [gl_have_pthread=yes]) + # Test for libpthread by looking for pthread_kill. (Not pthread_self, + # since it is defined as a macro on OSF/1.) + if test -n "$gl_have_pthread"; then + # The program links fine without libpthread. But it may actually + # need to link with libpthread in order to create multiple threads. + AC_CHECK_LIB([pthread], [pthread_kill], + [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread + # On Solaris and HP-UX, most pthread functions exist also in libc. + # Therefore pthread_in_use() needs to actually try to create a + # thread: pthread_create from libc will fail, whereas + # pthread_create will actually create a thread. + case "$host_os" in + solaris* | hpux*) + AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], + [Define if the pthread_in_use() detection is hard.]) + esac + ]) + else + # Some library is needed. Try libpthread and libc_r. + AC_CHECK_LIB([pthread], [pthread_kill], + [gl_have_pthread=yes + LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread + LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread]) + if test -z "$gl_have_pthread"; then + # For FreeBSD 4. + AC_CHECK_LIB([c_r], [pthread_kill], + [gl_have_pthread=yes + LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r + LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r]) + fi + fi + if test -n "$gl_have_pthread"; then + gl_threads_api=posix + AC_DEFINE([USE_POSIX_THREADS], [1], + [Define if the POSIX multithreading library can be used.]) + if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then + if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then + AC_DEFINE([USE_POSIX_THREADS_WEAK], [1], + [Define if references to the POSIX multithreading library should be made weak.]) + LIBTHREAD= + LTLIBTHREAD= + fi + fi + fi + fi + fi + if test -z "$gl_have_pthread"; then + if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then + gl_have_solaristhread= + gl_save_LIBS="$LIBS" + LIBS="$LIBS -lthread" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[thr_self();]])], + [gl_have_solaristhread=yes]) + LIBS="$gl_save_LIBS" + if test -n "$gl_have_solaristhread"; then + gl_threads_api=solaris + LIBTHREAD=-lthread + LTLIBTHREAD=-lthread + LIBMULTITHREAD="$LIBTHREAD" + LTLIBMULTITHREAD="$LTLIBTHREAD" + AC_DEFINE([USE_SOLARIS_THREADS], [1], + [Define if the old Solaris multithreading library can be used.]) + if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then + AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1], + [Define if references to the old Solaris multithreading library should be made weak.]) + LIBTHREAD= + LTLIBTHREAD= + fi + fi + fi + fi + if test "$gl_use_threads" = pth; then + gl_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_LINKFLAGS([pth]) + gl_have_pth= + gl_save_LIBS="$LIBS" + LIBS="$LIBS -lpth" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], [[pth_self();]])], + [gl_have_pth=yes]) + LIBS="$gl_save_LIBS" + if test -n "$gl_have_pth"; then + gl_threads_api=pth + LIBTHREAD="$LIBPTH" + LTLIBTHREAD="$LTLIBPTH" + LIBMULTITHREAD="$LIBTHREAD" + LTLIBMULTITHREAD="$LTLIBTHREAD" + AC_DEFINE([USE_PTH_THREADS], [1], + [Define if the GNU Pth multithreading library can be used.]) + if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then + if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then + AC_DEFINE([USE_PTH_THREADS_WEAK], [1], + [Define if references to the GNU Pth multithreading library should be made weak.]) + LIBTHREAD= + LTLIBTHREAD= + fi + fi + else + CPPFLAGS="$gl_save_CPPFLAGS" + fi + fi + if test -z "$gl_have_pthread"; then + if test "$gl_use_threads" = yes || test "$gl_use_threads" = win32; then + if { case "$host_os" in + mingw*) true;; + *) false;; + esac + }; then + gl_threads_api=win32 + AC_DEFINE([USE_WIN32_THREADS], [1], + [Define if the Win32 multithreading API can be used.]) + fi + fi + fi + fi + AC_MSG_CHECKING([for multithread API to use]) + AC_MSG_RESULT([$gl_threads_api]) + AC_SUBST([LIBTHREAD]) + AC_SUBST([LTLIBTHREAD]) + AC_SUBST([LIBMULTITHREAD]) + AC_SUBST([LTLIBMULTITHREAD]) +]) + +AC_DEFUN([gl_THREADLIB], +[ + AC_REQUIRE([gl_THREADLIB_EARLY]) + AC_REQUIRE([gl_THREADLIB_BODY]) +]) + + +dnl gl_DISABLE_THREADS +dnl ------------------ +dnl Sets the gl_THREADLIB default so that threads are not used by default. +dnl The user can still override it at installation time, by using the +dnl configure option '--enable-threads'. + +AC_DEFUN([gl_DISABLE_THREADS], [ + m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no]) +]) + + +dnl Survey of platforms: +dnl +dnl Platform Available Compiler Supports test-lock +dnl flavours option weak result +dnl --------------- --------- --------- -------- --------- +dnl Linux 2.4/glibc posix -lpthread Y OK +dnl +dnl GNU Hurd/glibc posix +dnl +dnl FreeBSD 5.3 posix -lc_r Y +dnl posix -lkse ? Y +dnl posix -lpthread ? Y +dnl posix -lthr Y +dnl +dnl FreeBSD 5.2 posix -lc_r Y +dnl posix -lkse Y +dnl posix -lthr Y +dnl +dnl FreeBSD 4.0,4.10 posix -lc_r Y OK +dnl +dnl NetBSD 1.6 -- +dnl +dnl OpenBSD 3.4 posix -lpthread Y OK +dnl +dnl MacOS X 10.[123] posix -lpthread Y OK +dnl +dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK +dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK +dnl +dnl HP-UX 11 posix -lpthread N (cc) OK +dnl Y (gcc) +dnl +dnl IRIX 6.5 posix -lpthread Y 0.5 +dnl +dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK +dnl +dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK +dnl -lpthread (gcc) Y +dnl +dnl Cygwin posix -lpthread Y OK +dnl +dnl Any of the above pth -lpth 0.0 +dnl +dnl Mingw win32 N OK +dnl +dnl BeOS 5 -- +dnl +dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is +dnl turned off: +dnl OK if all three tests terminate OK, +dnl 0.5 if the first test terminates OK but the second one loops endlessly, +dnl 0.0 if the first test already loops endlessly. diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4 new file mode 100644 index 000000000..03b51bcfe --- /dev/null +++ b/m4/uintmax_t.m4 @@ -0,0 +1,30 @@ +# uintmax_t.m4 serial 12 +dnl Copyright (C) 1997-2004, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Paul Eggert. + +AC_PREREQ([2.13]) + +# Define uintmax_t to 'unsigned long' or 'unsigned long long' +# if it is not already defined in or . + +AC_DEFUN([gl_AC_TYPE_UINTMAX_T], +[ + AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([gl_AC_HEADER_STDINT_H]) + if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then + AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + test $ac_cv_type_unsigned_long_long_int = yes \ + && ac_type='unsigned long long' \ + || ac_type='unsigned long' + AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type], + [Define to unsigned long or unsigned long long + if and don't define.]) + else + AC_DEFINE([HAVE_UINTMAX_T], [1], + [Define if you have the 'uintmax_t' type in or .]) + fi +]) diff --git a/m4/visibility.m4 b/m4/visibility.m4 new file mode 100644 index 000000000..19cd8f3d3 --- /dev/null +++ b/m4/visibility.m4 @@ -0,0 +1,77 @@ +# visibility.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2005, 2008, 2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + dnl First, check whether -Werror can be added to the command line, or + dnl whether it leads to an error because of some other option that the + dnl user has put into $CC $CFLAGS $CPPFLAGS. + AC_MSG_CHECKING([whether the -Werror option is usable]) + AC_CACHE_VAL([gl_cv_cc_vis_werror], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [gl_cv_cc_vis_werror=yes], + [gl_cv_cc_vis_werror=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_vis_werror]) + dnl Now check whether visibility declarations are supported. + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL([gl_cv_cc_visibility], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $gl_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + ]], + [[]])], + [gl_cv_cc_visibility=yes], + [gl_cv_cc_visibility=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/po/Makefile.am b/po/Makefile.am deleted file mode 100644 index e69de29bb..000000000 diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 000000000..d0af6c962 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,464 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU General Public +# License but which still want to provide support for the GNU gettext +# functionality. +# Please note that the actual code of GNU gettext is covered by the GNU +# General Public License and is *not* in the public domain. +# +# Origin: gettext-0.18 +GETTEXT_MACRO_VERSION = 0.18 + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = @localedir@ +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# @install_sh@ does not start with $(SHELL), so we add it. +# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) @install_sh@ -d +install_sh = $(SHELL) @install_sh@ +MKDIR_P = @MKDIR_P@ +mkdir_p = @mkdir_p@ + +GMSGFMT_ = @GMSGFMT@ +GMSGFMT_no = @GMSGFMT@ +GMSGFMT_yes = @GMSGFMT_015@ +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +MSGFMT_ = @MSGFMT@ +MSGFMT_no = @MSGFMT@ +MSGFMT_yes = @MSGFMT_015@ +MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = @XGETTEXT@ +XGETTEXT_no = @XGETTEXT@ +XGETTEXT_yes = @XGETTEXT_015@ +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = msgmerge +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +# Makevars gets inserted here. (Don't remove this line!) + +.SUFFIXES: +.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update + +.po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ + $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ + +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ + cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all: check-macro-version all-@USE_NLS@ + +all-yes: stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +check-macro-version: + @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, stamp-po is a nop (i.e. a phony target). + +# stamp-po is a timestamp denoting the last time at which the CATALOGS have +# been loosely updated. Its purpose is that when a developer or translator +# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, +# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent +# invocations of "make" will do nothing. This timestamp would not be necessary +# if updating the $(CATALOGS) would always touch them; however, the rule for +# $(POFILES) has been designed to not touch files that don't need to be +# changed. +stamp-po: $(srcdir)/$(DOMAIN).pot + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch stamp-po" && \ + echo timestamp > stamp-poT && \ + mv stamp-poT stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell.in remove-potcdate.sed + if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \ + package_gnu='GNU '; \ + else \ + package_gnu=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_gnu}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + esac + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES-shell.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + --join-existing --language=Shell --keyword=gettext_quoted \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES-shell.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_gnu}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + --join-existing --language=Shell --keyword=gettext_quoted \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + $(MAKE) update-po + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: stamp-po $(DISTFILES) + dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use @SHELL@, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && @SHELL@ ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 000000000..44857b1b8 --- /dev/null +++ b/po/Makevars @@ -0,0 +1,41 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Free Software Foundation, Inc. + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = bug-grub@gnu.org + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES b/po/POTFILES deleted file mode 100644 index cfa1e33cb..000000000 --- a/po/POTFILES +++ /dev/null @@ -1,80 +0,0 @@ -# List of files which contain translatable strings. -commands/acpi.c -commands/blocklist.c -commands/boot.c -commands/cat.c -commands/cmp.c -commands/configfile.c -commands/crc.c -commands/date.c -commands/echo.c -commands/efi/fixvideo.c -commands/efi/loadbios.c -commands/gptsync.c -commands/halt.c -commands/hdparm.c -commands/help.c -commands/hexdump.c -commands/i386/cpuid.c -commands/i386/pc/drivemap.c -commands/i386/pc/halt.c -commands/i386/pc/play.c -commands/i386/pc/pxecmd.c -commands/i386/pc/vbeinfo.c -commands/i386/pc/vbetest.c -commands/ieee1275/suspend.c -commands/keystatus.c -commands/loadenv.c -commands/ls.c -commands/lsmmap.c -commands/lspci.c -commands/memrw.c -commands/minicmd.c -commands/parttool.c -commands/password.c -commands/probe.c -commands/read.c -commands/reboot.c -commands/search.c -commands/search_file.c -commands/search_label.c -commands/search_uuid.c -commands/sleep.c -commands/test.c -commands/true.c -commands/usbtest.c -commands/videotest.c -commands/xnu_uuid.c - -disk/loopback.c - -hello/hello.c - -lib/arg.c - -loader/efi/appleloader.c -loader/efi/chainloader.c -loader/i386/bsd.c -loader/i386/efi/linux.c -loader/i386/ieee1275/linux.c -loader/i386/linux.c -loader/i386/pc/chainloader.c -loader/i386/pc/linux.c -loader/i386/xnu.c -loader/multiboot.c -loader/powerpc/ieee1275/linux.c -loader/sparc64/ieee1275/linux.c -loader/xnu.c - -normal/auth.c -normal/color.c -normal/dyncmd.c -normal/main.c -normal/menu_entry.c -normal/menu_text.c -normal/misc.c - -term/serial.c - -util/grub-mkimage.c -util/i386/pc/grub-setup.c diff --git a/po/POTFILES-shell b/po/POTFILES-shell.in similarity index 78% rename from po/POTFILES-shell rename to po/POTFILES-shell.in index 90d2b978c..70c2a3fd4 100644 --- a/po/POTFILES-shell +++ b/po/POTFILES-shell.in @@ -1,5 +1,7 @@ # List of files which contain translatable strings. Only files written in # Shell language are included here. +util/grub.d/10_hurd.in util/grub.d/10_kfreebsd.in util/grub.d/10_linux.in util/grub.d/10_netbsd.in +util/grub.d/20_linux_xen.in diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 000000000..8329fdf0a --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,117 @@ +# List of files which contain translatable strings. +grub-core/commands/acpi.c +grub-core/commands/blocklist.c +grub-core/commands/boot.c +grub-core/commands/cat.c +grub-core/commands/cmp.c +grub-core/commands/configfile.c +grub-core/commands/date.c +grub-core/commands/echo.c +grub-core/commands/efi/fixvideo.c +grub-core/commands/efi/loadbios.c +grub-core/commands/gptsync.c +grub-core/commands/halt.c +grub-core/commands/hashsum.c +grub-core/commands/hdparm.c +grub-core/commands/help.c +grub-core/commands/hexdump.c +grub-core/commands/i386/cpuid.c +grub-core/commands/i386/pc/drivemap.c +grub-core/commands/i386/pc/halt.c +grub-core/commands/i386/pc/lsapm.c +grub-core/commands/i386/pc/play.c +grub-core/commands/i386/pc/pxecmd.c +grub-core/commands/ieee1275/suspend.c +grub-core/commands/iorw.c +grub-core/commands/keylayouts.c +grub-core/commands/keystatus.c +grub-core/commands/legacycfg.c +grub-core/commands/loadenv.c +grub-core/commands/ls.c +grub-core/commands/lsacpi.c +grub-core/commands/lsmmap.c +grub-core/commands/lspci.c +grub-core/commands/memrw.c +grub-core/commands/menuentry.c +grub-core/commands/minicmd.c +grub-core/commands/parttool.c +grub-core/commands/password.c +grub-core/commands/password_pbkdf2.c +grub-core/commands/probe.c +grub-core/commands/read.c +grub-core/commands/reboot.c +grub-core/commands/regexp.c +grub-core/commands/search.c +grub-core/commands/search_file.c +grub-core/commands/search_label.c +grub-core/commands/search_uuid.c +grub-core/commands/search_wrap.c +grub-core/commands/setpci.c +grub-core/commands/sleep.c +grub-core/commands/terminal.c +grub-core/commands/test.c +grub-core/commands/testload.c +grub-core/commands/true.c +grub-core/commands/usbtest.c +grub-core/commands/videoinfo.c +grub-core/commands/videotest.c +grub-core/commands/xnu_uuid.c + +grub-core/disk/loopback.c + +grub-core/efiemu/main.c + +grub-core/font/font_cmd.c + +grub-core/gettext/gettext.c + +grub-core/gfxmenu/gui_progress_bar.c + +grub-core/hello/hello.c + +grub-core/kern/corecmd.c +grub-core/kern/emu/hostdisk.c +grub-core/kern/emu/misc.c +grub-core/kern/err.c + +grub-core/lib/arg.c + +grub-core/loader/efi/appleloader.c +grub-core/loader/efi/chainloader.c +grub-core/loader/i386/bsd.c +grub-core/loader/i386/linux.c +grub-core/loader/i386/pc/chainloader.c +grub-core/loader/i386/pc/linux.c +grub-core/loader/i386/pc/ntldr.c +grub-core/loader/i386/xnu.c +grub-core/loader/mips/linux.c +grub-core/loader/multiboot.c +grub-core/loader/powerpc/ieee1275/linux.c +grub-core/loader/sparc64/ieee1275/linux.c +grub-core/loader/xnu.c + +grub-core/mmap/mmap.c + +grub-core/normal/auth.c +grub-core/normal/cmdline.c +grub-core/normal/color.c +grub-core/normal/context.c +grub-core/normal/dyncmd.c +grub-core/normal/main.c +grub-core/normal/menu.c +grub-core/normal/menu_entry.c +grub-core/normal/menu_text.c +grub-core/normal/misc.c + +grub-core/script/main.c + +grub-core/term/gfxterm.c +grub-core/term/serial.c +grub-core/term/terminfo.c + +grub-core/tests/test_blockarg.c + +util/grub-editenv.c +util/grub-fstest.c +util/grub-mkimage.c +util/grub-setup.c diff --git a/po/Rules-quot b/po/Rules-quot new file mode 100644 index 000000000..af5248792 --- /dev/null +++ b/po/Rules-quot @@ -0,0 +1,47 @@ +# Special Makefile rules for English message catalogs with quotation marks. + +DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot + +.SUFFIXES: .insert-header .po-update-en + +en@quot.po-create: + $(MAKE) en@quot.po-update +en@boldquot.po-create: + $(MAKE) en@boldquot.po-update + +en@quot.po-update: en@quot.po-update-en +en@boldquot.po-update: en@boldquot.po-update-en + +.insert-header.po-update-en: + @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ + if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + ll=`echo $$lang | sed -e 's/@.*//'`; \ + LC_ALL=C; export LC_ALL; \ + cd $(srcdir); \ + if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "creation of $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +en@quot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header + +en@boldquot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header + +mostlyclean: mostlyclean-quot +mostlyclean-quot: + rm -f *.insert-header diff --git a/po/boldquot.sed b/po/boldquot.sed new file mode 100644 index 000000000..4b937aa51 --- /dev/null +++ b/po/boldquot.sed @@ -0,0 +1,10 @@ +s/"\([^"]*\)"/“\1”/g +s/`\([^`']*\)'/â€\1’/g +s/ '\([^`']*\)' / â€\1’ /g +s/ '\([^`']*\)'$/ â€\1’/g +s/^'\([^`']*\)' /â€\1’ /g +s/“”/""/g +s/“/“/g +s/”/”/g +s/â€/â€/g +s/’/’/g diff --git a/po/en@boldquot.header b/po/en@boldquot.header new file mode 100644 index 000000000..fedb6a06d --- /dev/null +++ b/po/en@boldquot.header @@ -0,0 +1,25 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# diff --git a/po/en@quot.header b/po/en@quot.header new file mode 100644 index 000000000..a9647fc35 --- /dev/null +++ b/po/en@quot.header @@ -0,0 +1,22 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# diff --git a/po/insert-header.sin b/po/insert-header.sin new file mode 100644 index 000000000..b26de01f6 --- /dev/null +++ b/po/insert-header.sin @@ -0,0 +1,23 @@ +# Sed script that inserts the file called HEADER before the header entry. +# +# At each occurrence of a line starting with "msgid ", we execute the following +# commands. At the first occurrence, insert the file. At the following +# occurrences, do nothing. The distinction between the first and the following +# occurrences is achieved by looking at the hold space. +/^msgid /{ +x +# Test if the hold space is empty. +s/m/m/ +ta +# Yes it was empty. First occurrence. Read the file. +r HEADER +# Output the file's contents by reading the next line. But don't lose the +# current line while doing this. +g +N +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/po/quot.sed b/po/quot.sed new file mode 100644 index 000000000..0122c4631 --- /dev/null +++ b/po/quot.sed @@ -0,0 +1,6 @@ +s/"\([^"]*\)"/“\1”/g +s/`\([^`']*\)'/â€\1’/g +s/ '\([^`']*\)' / â€\1’ /g +s/ '\([^`']*\)'$/ â€\1’/g +s/^'\([^`']*\)' /â€\1’ /g +s/“”/""/g diff --git a/po/remove-potcdate.sin b/po/remove-potcdate.sin new file mode 100644 index 000000000..2436c49e7 --- /dev/null +++ b/po/remove-potcdate.sin @@ -0,0 +1,19 @@ +# Sed script that remove the POT-Creation-Date line in the header entry +# from a POT file. +# +# The distinction between the first and the following occurrences of the +# pattern is achieved by looking at the hold space. +/^"POT-Creation-Date: .*"$/{ +x +# Test if the hold space is empty. +s/P/P/ +ta +# Yes it was empty. First occurrence. Remove the line. +g +d +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} From 77a94e98108171ba2c7d67ec7a6ebb0743fe1d66 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 02:06:14 +0200 Subject: [PATCH 0236/1414] * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): Add BADRAM. * grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap): Likewise. * include/multiboot.h: Resynced with specification. * include/multiboot2.h: Likewise. --- ChangeLog | 9 +++++ grub-core/loader/i386/multiboot_mbi.c | 4 +++ grub-core/loader/multiboot_mbi2.c | 6 +++- include/multiboot.h | 3 +- include/multiboot2.h | 52 +++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53f1e1d49..c79bdcf8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-21 Vladimir Serbinenko + + * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): + Add BADRAM. + * grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap): + Likewise. + * include/multiboot.h: Resynced with specification. + * include/multiboot2.h: Likewise. + 2010-09-21 Colin Watson Fix po directory handling. diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index eb86958cb..283b84c5a 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -229,6 +229,10 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) case GRUB_MEMORY_NVS: mmap_entry->type = MULTIBOOT_MEMORY_NVS; break; + + case GRUB_MEMORY_BADRAM: + mmap_entry->type = MULTIBOOT_MEMORY_BADRAM; + break; default: mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index b4cd8ac0e..799985a1c 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -313,7 +313,11 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) case GRUB_MEMORY_NVS: mmap_entry->type = MULTIBOOT_MEMORY_NVS; break; - + + case GRUB_MEMORY_BADRAM: + mmap_entry->type = MULTIBOOT_MEMORY_BADRAM; + break; + default: mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; break; diff --git a/include/multiboot.h b/include/multiboot.h index ed71e6b96..bd133ba1f 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -1,5 +1,5 @@ /* multiboot.h - Multiboot header file. */ -/* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc. +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -236,6 +236,7 @@ struct multiboot_mmap_entry #define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 multiboot_uint32_t type; } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; diff --git a/include/multiboot2.h b/include/multiboot2.h index 275debe75..0e26a8ec2 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -52,6 +52,12 @@ #define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 #define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 #define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 #define MULTIBOOT_HEADER_TAG_END 0 #define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 @@ -167,6 +173,7 @@ struct multiboot_mmap_entry #define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 multiboot_uint32_t type; multiboot_uint32_t zero; } __attribute__((packed)); @@ -309,6 +316,51 @@ struct multiboot_tag_apm multiboot_uint16_t dseg_len; }; +struct multiboot_tag_efi32 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + #endif /* ! ASM_FILE */ #endif /* ! MULTIBOOT_HEADER */ From 9dbbe5e85809ec80cf2d4c15b342e3a4d79bd6a9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 02:19:29 +0200 Subject: [PATCH 0237/1414] Impletment EST multiboot passing --- grub-core/loader/multiboot_mbi2.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 799985a1c..db3553789 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -142,6 +142,8 @@ grub_multiboot_load (grub_file_t file) case MULTIBOOT_TAG_TYPE_VBE: case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: case MULTIBOOT_TAG_TYPE_APM: + case MULTIBOOT_TAG_TYPE_EFI32: + case MULTIBOOT_TAG_TYPE_EFI64: break; default: @@ -283,6 +285,8 @@ grub_multiboot_get_mbi_size (void) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN) + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1 + sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1; } @@ -674,7 +678,27 @@ grub_multiboot_make_mbi (grub_uint32_t *target) grub_errno = GRUB_ERR_NONE; } } - + +#if defined (GRUB_MACHINE_EFI) && __x86_64__ + { + struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi64 *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_EFI64; + tag->size = sizeof (*tag); + tag->pointer = (grub_addr_t) grub_efi_system_table; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + } +#endif + +#if defined (GRUB_MACHINE_EFI) && __i386_ + { + struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi32 *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_EFI32; + tag->size = sizeof (*tag); + tag->pointer = (grub_addr_t) grub_efi_system_table; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + } +#endif + { struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_END; From df3367cc4ae9fd44818ed2c89f2da0c2b17f743b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 02:33:48 +0200 Subject: [PATCH 0238/1414] * configure.ac: Change version to 1.99~beta0. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c79bdcf8f..d3f29692a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-21 Vladimir Serbinenko + + * configure.ac: Change version to 1.99~beta0. + 2010-09-21 Vladimir Serbinenko * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): diff --git a/configure.ac b/configure.ac index dc433317b..f9abafcf0 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.98],[bug-grub@gnu.org]) +AC_INIT([GRUB],[1.99~beta0],[bug-grub@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) From 4519e259a146e4f5fad65c23bb96b13ad28749c7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 08:37:50 +0200 Subject: [PATCH 0239/1414] Implementation of ACPI parts --- grub-core/loader/multiboot.c | 2 ++ grub-core/loader/multiboot_mbi2.c | 44 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 9062ba01c..4bfc2c191 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -22,6 +22,8 @@ * need to be implemented: * - drives table * - ROM configuration table + * - SMBIOS tables + * - Networking information */ #include diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index db3553789..d499de2bb 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -32,6 +32,7 @@ #include #include #include +#include #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) #include @@ -144,6 +145,8 @@ grub_multiboot_load (grub_file_t file) case MULTIBOOT_TAG_TYPE_APM: case MULTIBOOT_TAG_TYPE_EFI32: case MULTIBOOT_TAG_TYPE_EFI64: + case MULTIBOOT_TAG_TYPE_ACPI_OLD: + case MULTIBOOT_TAG_TYPE_ACPI_NEW: break; default: @@ -267,6 +270,18 @@ grub_multiboot_load (grub_file_t file) return err; } +static grub_size_t +acpiv2_size (void) +{ + struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 (); + + if (!p) + return 0; + + return ALIGN_UP (sizeof (struct multiboot_tag_old_acpi) + + p->length, MULTIBOOT_TAG_ALIGN); +} + static grub_size_t grub_multiboot_get_mbi_size (void) { @@ -287,6 +302,9 @@ grub_multiboot_get_mbi_size (void) + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (sizeof (struct multiboot_tag_old_acpi) + + sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN) + + acpiv2_size () + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1 + sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1; } @@ -699,6 +717,32 @@ grub_multiboot_make_mbi (grub_uint32_t *target) } #endif + { + struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *) + ptrorig; + struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 (); + if (a) + { + tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD; + tag->size = sizeof (*tag) + sizeof (*a); + grub_memcpy (tag->rsdp, a, sizeof (*a)); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + } + } + + { + struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *) + ptrorig; + struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 (); + if (a) + { + tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW; + tag->size = sizeof (*tag) + a->length; + grub_memcpy (tag->rsdp, a, a->length); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); + } + } + { struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_END; From 3197c86ba826bd114f44cc09bb380b4be398ed73 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 10:07:12 +0200 Subject: [PATCH 0240/1414] Remove dead code in decompressor --- grub-core/kern/i386/pc/lzma_decode.S | 63 ---------------------------- 1 file changed, 63 deletions(-) diff --git a/grub-core/kern/i386/pc/lzma_decode.S b/grub-core/kern/i386/pc/lzma_decode.S index a5a86848a..88c668d5e 100644 --- a/grub-core/kern/i386/pc/lzma_decode.S +++ b/grub-core/kern/i386/pc/lzma_decode.S @@ -77,69 +77,6 @@ #define RepLenCoder (LenCoder + kNumLenProbs) #define Literal (RepLenCoder + kNumLenProbs) - -#if 0 - -DbgOut: - pushf - pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - pushl %eax - - call _DebugPrint - - popl %eax - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popf - - ret - - -/* - * int LzmaDecodeProperties(CLzmaProperties *propsRes, - * const unsigned char *propsData, - * int size); - */ - -_LzmaDecodePropertiesA: - movb (%edx), %dl - - xorl %ecx, %ecx -1: - cmpb $45, %dl - jb 2f - incl %ecx - subb $45, %dl - jmp 1b -2: - movl %ecx, 8(%eax) /* pb */ - xorl %ecx, %ecx -1: - cmpb $9, %dl - jb 2f - incl %ecx - subb $9, %dl -2: - movl %ecx, 4(%eax) /* lp */ - movb %dl, %cl - movl %ecx, (%eax) /* lc */ - -#endif - -#ifndef ASM_FILE - xorl %eax, %eax -#endif - ret - #define out_size 8(%ebp) #define now_pos -4(%ebp) From c5b4cd370ee3342d226cd0f4193f2c560f855b2d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 10:14:08 +0200 Subject: [PATCH 0241/1414] asm part for mips decompressor --- grub-core/Makefile.core.def | 13 ++ grub-core/boot/mips/startup_raw.S | 186 +++++++++++++++++++++++++++++ grub-core/kern/mips/cache.S | 3 + grub-core/kern/mips/cache_flush.S | 4 +- grub-core/kern/mips/startup.S | 148 ++++------------------- grub-core/lib/mips/relocator_asm.S | 7 +- include/grub/offsets.h | 12 +- util/grub-mkimage.c | 51 ++++++-- 8 files changed, 278 insertions(+), 146 deletions(-) create mode 100644 grub-core/boot/mips/startup_raw.S diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2fca91430..3341cb678 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -275,6 +275,19 @@ image = { enable = i386_pc; }; +image = { + name = decompress; + mips = boot/mips/startup_raw.S; + common = lib/LzmaDec.c; + + mips_cppflags = '-DGRUB_MACHINE_LINK_ADDR=0x80200000'; + + objcopyflags = '-O binary'; + ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; + cflags = '-static-libgcc'; + enable = mips; +}; + image = { name = fwstart; mips_yeeloong = boot/mips/yeeloong/fwstart.S; diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S new file mode 100644 index 000000000..67dc2ec03 --- /dev/null +++ b/grub-core/boot/mips/startup_raw.S @@ -0,0 +1,186 @@ +/* startup.S - Startup code for the MIPS. */ +/* + * 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 . + */ + +#include +#include +#include +#include + +#define BASE_ADDR 8 + +.extern __bss_start +.extern _end + + .globl __start, _start, start + .set noreorder + .set nomacro +__start: +_start: +start: + + bal codestart + nop +base: + . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE +compressed_size: + .long 0 + . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE +uncompressed_size: + .long 0 +codestart: + /* Save our base. */ + move $s0, $ra + + /* Parse arguments. Has to be done before relocation. + So need to do it in asm. */ +#if 0 // def GRUB_MACHINE_MIPS_YEELOONG + move $s2, $zero + move $s3, $zero + move $s4, $zero + move $s5, $zero + + /* $a2 has the environment. */ + addiu $t0, $a2, 1 + beq $t0, $zero, argdone + nop + move $t0, $a2 +argcont: + lw $t1, 0($t0) + beq $t1, $zero, argdone + nop +#define DO_PARSE(str, reg) \ + addiu $t2, $s0, (str-base);\ + bal parsestr;\ + beq $v0, $zero, 1f;\ + nop ;\ + b 2f;\ + move reg, $v0; +1: + DO_PARSE (busclockstr, $s2) + DO_PARSE (cpuclockstr, $s3) + DO_PARSE (memsizestr, $s4) + DO_PARSE (highmemsizestr, $s5) +2: + b argcont + addiu $t0, $t0, 4 +parsestr: + move $v0, $zero + move $t3, $t1 +3: + lb $t4, 0($t2) + lb $t5, 0($t3) + addiu $t2, $t2, 1 + addiu $t3, $t3, 1 + beq $t5, $zero, 1f + nop + beq $t5, $t4, 3b + nop + bne $t4, $zero, 1f + nop + + addiu $t3, $t3, 0xffff +digcont: + lb $t5, 0($t3) + /* Substract '0' from digit. */ + addiu $t5, $t5, 0xffd0 + bltz $t5, 1f + nop + addiu $t4, $t5, 0xfff7 + bgtz $t4, 1f + nop + /* Multiply $v0 by 10 with bitshifts. */ + sll $v0, $v0, 1 + sll $t4, $v0, 2 + addu $v0, $v0, $t4 + addu $v0, $v0, $t5 + addiu $t3, $t3, 1 + b digcont + nop +1: + jr $ra + nop +busclockstr: .asciiz "busclock=" +cpuclockstr: .asciiz "cpuclock=" +memsizestr: .asciiz "memsize=" +highmemsizestr: .asciiz "highmemsize=" + .p2align 2 +argdone: +#endif + /* Copy the decompressor. */ + lui $t1, %hi(base) + addiu $t1, $t1, %lo(base) + lui $t3, %hi(__bss_start) + addiu $t3, $t3, %lo(__bss_start) + move $t2, $s0 + +1: + beq $t1, $t3, 2f + lb $t4, 0($t2) + sb $t4, 0($t1) + addiu $t1, $t1, 1 + b 1b + addiu $t2, $t2, 1 +2: + /* Clean out its BSS. */ + lui $t1, %hi(__bss_start) + addiu $t1, $t1, %lo(__bss_start) + lui $t2, %hi(_end) + addiu $t2, $t2, %lo(_end) +1: + beq $t1, $t2, 2f + nop + sb $zero, 0($t1) + b 1b + addiu $t1, $t1, 1 +2: + + /* Decompress the payload. */ + lui $a0, %hi(__bss_start) + addiu $a0, $a0, %lo(__bss_start) + lui $t0, %hi(base) + addiu $t0, $t0, %lo(base) + subu $a0, $a0, $t0 + addu $a0, $a0, $s0 + + lui $a1, %hi(GRUB_MACHINE_LINK_ADDR) + addiu $a1, %lo(GRUB_MACHINE_LINK_ADDR) + lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0) + move $s1, $a1 + + /* $a0 contains source compressed address, $a1 is destination, + $a2 is compressed size, $a3 is uncompressed size. + */ + move $s6, $a3 + + lui $sp, %hi(_start) + + bal EXT_C(grub_decompress_core) + addiu $sp, $sp, %lo(_start) + + move $a0, $s1 + move $a1, $s6 + +#include "../../kern/mips/cache_flush.S" + + lui $t1, %hi(GRUB_MACHINE_LINK_ADDR) + addiu $t1, %lo(GRUB_MACHINE_LINK_ADDR) + + jr $t1 + nop diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S index 2c35b6da2..02dc3355f 100644 --- a/grub-core/kern/mips/cache.S +++ b/grub-core/kern/mips/cache.S @@ -1,6 +1,9 @@ #include + .set nomacro + .set noreorder + FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) #include "cache_flush.S" diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S index 5667ee7b4..11096c035 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 $t0, $t0, 0x1 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 $t0, $t0, 0x1 addiu $t1, $t1, 0xffff bne $t1, $zero, 2b + addiu $t0, $t0, 0x1 sync diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 6811353ea..1b27a5b1f 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -22,128 +22,19 @@ #include #include -#define BASE_ADDR 8 - -.extern __bss_start -.extern _end - +#define BASE_ADDR 8 + .globl __start, _start, start + .set noreorder + .set nomacro __start: _start: -start: - bal codestart -base: - . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE -compressed_size: - .long 0 - . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE -total_module_size: - .long 0 - . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE -kernel_image_size: - .long 0 -codestart: - /* Save our base. */ - move $s0, $ra +start: +.extern __bss_start +.extern _end + bal cont + nop - /* Parse arguments. Has to be done before relocation. - So need to do it in asm. */ -#ifdef GRUB_MACHINE_MIPS_YEELOONG - move $s2, $zero - move $s3, $zero - move $s4, $zero - move $s5, $zero - - /* $a2 has the environment. */ - addiu $t0, $a2, 1 - beq $t0, $zero, argdone - move $t0, $a2 -argcont: - lw $t1, 0($t0) - beq $t1, $zero, argdone -#define DO_PARSE(str, reg) \ - addiu $t2, $s0, (str-base);\ - bal parsestr;\ - beq $v0, $zero, 1f;\ - move reg, $v0;\ - b 2f;\ -1: - DO_PARSE (busclockstr, $s2) - DO_PARSE (cpuclockstr, $s3) - DO_PARSE (memsizestr, $s4) - DO_PARSE (highmemsizestr, $s5) -2: - addiu $t0, $t0, 4 - b argcont -parsestr: - move $v0, $zero - move $t3, $t1 -3: - lb $t4, 0($t2) - lb $t5, 0($t3) - addiu $t2, $t2, 1 - addiu $t3, $t3, 1 - beq $t5, $zero, 1f - beq $t5, $t4, 3b - bne $t4, $zero, 1f - - addiu $t3, $t3, 0xffff -digcont: - lb $t5, 0($t3) - /* Substract '0' from digit. */ - addiu $t5, $t5, 0xffd0 - bltz $t5, 1f - addiu $t4, $t5, 0xfff7 - bgtz $t4, 1f - /* Multiply $v0 by 10 with bitshifts. */ - sll $v0, $v0, 1 - sll $t4, $v0, 2 - addu $v0, $v0, $t4 - addu $v0, $v0, $t5 - addiu $t3, $t3, 1 - b digcont -1: - jr $ra -busclockstr: .asciiz "busclock=" -cpuclockstr: .asciiz "cpuclock=" -memsizestr: .asciiz "memsize=" -highmemsizestr: .asciiz "highmemsize=" - .p2align 2 -argdone: -#endif - - /* Decompress the payload. */ - addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR - lui $a1, %hi(compressed) - addiu $a1, %lo(compressed) - lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) - move $s1, $a1 - - /* $a0 contains source compressed address, $a1 is destination, - $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0, - $s1, $s2, $s3, $s4 and $s5. - On return $v0 contains uncompressed size. - */ - move $v0, $a2 -reloccont: - lb $t4, 0($a0) - sb $t4, 0($a1) - addiu $a1,$a1,1 - addiu $a0,$a0,1 - addiu $a2, 0xffff - bne $a2, $0, reloccont - - move $a0, $s1 - move $a1, $v0 - -#include "cache_flush.S" - - lui $t1, %hi(cont) - addiu $t1, %lo(cont) - - jr $t1 - . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE -compressed: . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) @@ -166,6 +57,8 @@ VARIABLE (grub_arch_highmemsize) .long 0 #endif cont: + /* Save our base. */ + move $s0, $ra #ifdef GRUB_MACHINE_MIPS_YEELOONG lui $t1, %hi(grub_arch_busclock) @@ -177,10 +70,8 @@ cont: #endif /* Move the modules out of BSS. */ - lui $t1, %hi(_start) - addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) - addu $t2, $t1, $t2 + lui $t2, %hi(_end) + addiu $t2, %lo(_end) lui $t1, %hi(_end) addiu $t1, %lo(_end) @@ -201,11 +92,11 @@ cont: modulesmovcont: lb $t4, 0($t2) sb $t4, 0($t1) - addiu $t1,$t1,0xffff - addiu $t2,$t2,0xffff - addiu $t3, 0xffff + addiu $t1, $t1, -1 + addiu $t3, $t3, -1 bne $t3, $0, modulesmovcont - + addiu $t2, $t2, -1 + /* Clean BSS. */ lui $t1, %hi(__bss_start) @@ -214,13 +105,14 @@ modulesmovcont: addiu $t2, %lo(_end) bsscont: sb $0,0($t1) - addiu $t1,$t1,1 - sltu $t3,$t1,$t2 + sltu $t3, $t1, $t2 bne $t3, $0, bsscont + addiu $t1, $t1, 1 li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH lui $t1, %hi(grub_main) addiu $t1, %lo(grub_main) jr $t1 + nop diff --git a/grub-core/lib/mips/relocator_asm.S b/grub-core/lib/mips/relocator_asm.S index 3408b59e1..1d142a4f3 100644 --- a/grub-core/lib/mips/relocator_asm.S +++ b/grub-core/lib/mips/relocator_asm.S @@ -20,6 +20,9 @@ .p2align 4 /* force 16-byte alignment */ + .set noreorder + .set nomacro + VARIABLE (grub_relocator_forward_start) move $a0, $9 move $a1, $10 @@ -28,9 +31,9 @@ copycont1: lb $11,0($8) sb $11,0($9) addiu $8, $8, 1 - addiu $9, $9, 1 addiu $10, $10, -1 bne $10, $0, copycont1 + addiu $9, $9, 1 #include "../../kern/mips/cache_flush.S" @@ -49,9 +52,9 @@ copycont2: lb $11,0($8) sb $11,0($9) addiu $8, $8, -1 - addiu $9, $9, -1 addiu $10, $10, -1 bne $10, $0, copycont2 + addiu $9, $9, -1 #include "../../kern/mips/cache_flush.S" diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 47eb6c9bd..8caa27c2f 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -102,13 +102,12 @@ #define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 -#define GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE 0x200 -#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0xc -#define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 +#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE 0xc -#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE -#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 +#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0x08 +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX 0x0c +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END 0x54 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_EFI_PREFIX 0x8 @@ -158,6 +157,7 @@ #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) +#define GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _UNCOMPRESSED_SIZE) #define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) #define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX_END) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index d798ad052..ee007a54b 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -248,13 +248,13 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, - .flags = PLATFORM_FLAGS_NONE, + .flags = PLATFORM_FLAGS_LZMA, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, - .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, - .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, - .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -268,13 +268,13 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_ELF, - .flags = PLATFORM_FLAGS_NONE, + .flags = PLATFORM_FLAGS_LZMA, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, - .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, - .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, - .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -680,6 +680,41 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], = grub_host_to_target32 (-2); } + if (image_target->id == IMAGE_YEELOONG_FLASH + || image_target->id == IMAGE_YEELOONG_ELF) + { + char *full_img; + size_t full_size; + char *decompress_path, *decompress_img; + size_t decompress_size; + + decompress_path = grub_util_get_path (dir, "decompress.img"); + 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_host_to_target32 (core_size); + + *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE)) + = grub_host_to_target32 (kernel_size + total_module_size); + + full_size = core_size + decompress_size; + + full_img = xmalloc (full_size); + memset (full_img, 0, full_size); + + memcpy (full_img, decompress_img, decompress_size); + + memcpy (full_img + decompress_size, core_img, core_size); + + memset (full_img + decompress_size + core_size, 0, + full_size - (decompress_size + core_size)); + + free (core_img); + core_img = full_img; + core_size = full_size; + } + switch (image_target->id) { case IMAGE_I386_PC: From 934d7e44b259b42efa2721a39a95eb1961b60ea0 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Tue, 21 Sep 2010 11:17:54 +0200 Subject: [PATCH 0242/1414] * util/grub-editenv.c: Update strings to avoid warnings when generating grub.pot file. * util/grub-setup.c: Likewise. --- ChangeLog | 7 +++++++ util/grub-editenv.c | 8 ++++---- util/grub-setup.c | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3f29692a..6f4835ca7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-09-21 Yves Blusseau + + * util/grub-editenv.c: Update strings to avoid warnings when generating + grub.pot file. + * util/grub-setup.c: Likewise. + + 2010-09-21 Vladimir Serbinenko * configure.ac: Change version to 1.99~beta0. diff --git a/util/grub-editenv.c b/util/grub-editenv.c index bfda7c3d8..519945411 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -99,10 +99,10 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused))) struct argp argp = { options, argp_parser, N_("FILENAME COMMAND"), - N_("\n\ -Tool to edit environment block.\n\ -\v\ -If FILENAME is '-', the default value %s is used.\n"), + "\n"N_("\ +Tool to edit environment block.") +"\v"N_("\ +If FILENAME is '-', the default value %s is used."), NULL, help_filter, NULL }; diff --git a/util/grub-setup.c b/util/grub-setup.c index 62ba9747e..0c5470830 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -791,11 +791,11 @@ argp_parser (int key, char *arg, struct argp_state *state) static struct argp argp = { options, argp_parser, N_("DEVICE"), - N_("\n\ + "\n"N_("\ Set up images to boot from DEVICE.\n\ \n\ -You should not normally run this program directly. Use grub-install instead.\n\ -\v\ +You should not normally run this program directly. Use grub-install instead.") +"\v"N_("\ DEVICE must be an OS device (e.g. /dev/sda1)."), NULL, help_filter, NULL }; From f8926c32b4d132a9c2c641a4f331f27b99866f41 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 11:22:52 +0200 Subject: [PATCH 0243/1414] C part of decompressor --- grub-core/Makefile.core.def | 9 +- grub-core/boot/decompressor.c | 115 ++++++++++++++++++++++++++ grub-core/kern/mips/cache.S | 2 +- grub-core/lib/LzmaDec.c | 40 +++++++-- grub-core/lib/xzembed/xz_dec_bcj.c | 11 ++- grub-core/lib/xzembed/xz_dec_lzma2.c | 28 ++++++- grub-core/lib/xzembed/xz_dec_stream.c | 57 +++++++++++-- include/grub/decompressor.h | 28 +++++++ include/grub/lib/LzmaDec.h | 2 +- 9 files changed, 272 insertions(+), 20 deletions(-) create mode 100644 grub-core/boot/decompressor.c create mode 100644 include/grub/decompressor.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 3341cb678..58fd7cf5d 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -278,9 +278,14 @@ image = { image = { name = decompress; mips = boot/mips/startup_raw.S; - common = lib/LzmaDec.c; + common = boot/decompressor.c; + common = lib/xzembed/xz_dec_bcj.c; + common = lib/xzembed/xz_dec_lzma2.c; + common = lib/xzembed/xz_dec_stream.c; - mips_cppflags = '-DGRUB_MACHINE_LINK_ADDR=0x80200000'; + 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'; objcopyflags = '-O binary'; ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; diff --git a/grub-core/boot/decompressor.c b/grub-core/boot/decompressor.c new file mode 100644 index 000000000..5c16fb932 --- /dev/null +++ b/grub-core/boot/decompressor.c @@ -0,0 +1,115 @@ +/* + * 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 "xz.h" +#include "xz_stream.h" + +void * +memset (void *s, int c, grub_size_t len) +{ + grub_uint8_t *ptr; + for (ptr = s; len; ptr++, len--) + *ptr = c; + return s; +} + +void * +grub_memmove (void *dest, const void *src, grub_size_t n) +{ + char *d = (char *) dest; + const char *s = (const char *) src; + + if (d < s) + while (n--) + *d++ = *s++; + else + { + d += n; + s += n; + + while (n--) + *--d = *--s; + } + + return dest; +} + +int +grub_memcmp (const void *s1, const void *s2, grub_size_t n) +{ + const char *t1 = s1; + const char *t2 = s2; + + while (n--) + { + if (*t1 != *t2) + return (int) *t1 - (int) *t2; + + t1++; + t2++; + } + + return 0; +} + +int memcmp (const void *s1, const void *s2, grub_size_t n) + __attribute__ ((alias ("grub_memcmp"))); + +void *memmove (void *dest, const void *src, grub_size_t n) + __attribute__ ((alias ("grub_memmove"))); + +void *memcpy (void *dest, const void *src, grub_size_t n) + __attribute__ ((alias ("grub_memmove"))); + +void +grub_decompress_core (void *src, void *dst, unsigned long srcsize, + unsigned long dstsize) +{ + struct xz_dec *dec; + struct xz_buf buf; + + dec = xz_dec_init (GRUB_DECOMPRESSOR_DICT_SIZE); + + buf.in = src; + buf.in_pos = 0; + buf.in_size = srcsize; + buf.out = dst; + buf.out_pos = 0; + buf.out_size = dstsize; + + while (buf.in_pos != buf.in_size) + { + enum xz_ret xzret; + xzret = xz_dec_run (dec, &buf); + switch (xzret) + { + case XZ_MEMLIMIT_ERROR: + case XZ_FORMAT_ERROR: + case XZ_OPTIONS_ERROR: + case XZ_DATA_ERROR: + case XZ_BUF_ERROR: + return; + default: + break; + } + } +} diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S index 02dc3355f..999872f6b 100644 --- a/grub-core/kern/mips/cache.S +++ b/grub-core/kern/mips/cache.S @@ -1,8 +1,8 @@ #include - .set nomacro .set noreorder + .set nomacro FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) diff --git a/grub-core/lib/LzmaDec.c b/grub-core/lib/LzmaDec.c index 62ebee686..4d6890b60 100644 --- a/grub-core/lib/LzmaDec.c +++ b/grub-core/lib/LzmaDec.c @@ -26,7 +26,14 @@ #include -#include +static void +memcpy (void *a_, const void *b_, unsigned s) +{ + char *a = a_; + const char *b = b_; + while (s--) + *a++ = *b++; +} #define kNumTopBits 24 #define kTopValue ((UInt32)1 << kNumTopBits) @@ -294,14 +301,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte prob = probs + RepLenCoder; } { - unsigned limit, offset; + unsigned limit2, offset; CLzmaProb *probLen = prob + LenChoice; IF_BIT_0(probLen) { UPDATE_0(probLen); probLen = prob + LenLow + (posState << kLenNumLowBits); offset = 0; - limit = (1 << kLenNumLowBits); + limit2 = (1 << kLenNumLowBits); } else { @@ -312,17 +319,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte UPDATE_0(probLen); probLen = prob + LenMid + (posState << kLenNumMidBits); offset = kLenNumLowSymbols; - limit = (1 << kLenNumMidBits); + limit2 = (1 << kLenNumMidBits); } else { UPDATE_1(probLen); probLen = prob + LenHigh; offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = (1 << kLenNumHighBits); + limit2 = (1 << kLenNumHighBits); } } - TREE_DECODE(probLen, limit, len); + TREE_DECODE(probLen, limit2, len); len += offset; } @@ -718,7 +725,7 @@ static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) p->needFlush = 0; } -void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) { p->needFlush = 1; p->remainLen = 0; @@ -915,6 +922,7 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) { + return ; alloc->Free(alloc, p->probs); p->probs = 0; } @@ -957,13 +965,16 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) return SZ_OK; } +static char sal[30000], *sptr = sal; + static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) { UInt32 numProbs = LzmaProps_GetNumProbs(propNew); if (p->probs == 0 || numProbs != p->numProbs) { LzmaDec_FreeProbs(p, alloc); - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->probs = (CLzmaProb *) sptr; + sptr += sizeof (CLzmaProb); p->numProbs = numProbs; if (p->probs == 0) return SZ_ERROR_MEM; @@ -1033,3 +1044,16 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, LzmaDec_FreeProbs(&p, alloc); return res; } + +void +grub_decompress_core (void *src, void *dst, unsigned long srcsize, unsigned long dstsize); + +void +grub_decompress_core (void *src, void *dst, unsigned long srcsize, unsigned long dstsize) +{ + char *src_ = src, *dst_ = dst; + (void) dstsize; + while (srcsize--) + *dst_++ = *src_++ ^ 0x5a; +} + diff --git a/grub-core/lib/xzembed/xz_dec_bcj.c b/grub-core/lib/xzembed/xz_dec_bcj.c index 7eec9de7d..f517b0acc 100644 --- a/grub-core/lib/xzembed/xz_dec_bcj.c +++ b/grub-core/lib/xzembed/xz_dec_bcj.c @@ -520,9 +520,18 @@ enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, return s->ret; } +#ifdef GRUB_EMBED_DECOMPRESSOR +struct xz_dec_bcj bcj; +#endif + struct xz_dec_bcj * xz_dec_bcj_create(bool single_call) { - struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct xz_dec_bcj *s; +#ifdef GRUB_EMBED_DECOMPRESSOR + s = &bcj; +#else + s = kmalloc(sizeof(*s), GFP_KERNEL); +#endif if (s != NULL) s->single_call = single_call; diff --git a/grub-core/lib/xzembed/xz_dec_lzma2.c b/grub-core/lib/xzembed/xz_dec_lzma2.c index a0d422697..c55773ce0 100644 --- a/grub-core/lib/xzembed/xz_dec_lzma2.c +++ b/grub-core/lib/xzembed/xz_dec_lzma2.c @@ -1100,10 +1100,17 @@ enum xz_ret xz_dec_lzma2_run( return XZ_OK; } +#ifdef GRUB_EMBED_DECOMPRESSOR +#include +static struct xz_dec_lzma2 lzma2; +static char dict[GRUB_DECOMPRESSOR_DICT_SIZE]; +#endif + struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max) { struct xz_dec_lzma2 *s; +#ifndef GRUB_EMBED_DECOMPRESSOR /* Maximum supported dictionary by this implementation is 3 GiB. */ if (dict_max > ((uint32_t)3 << 30)) return NULL; @@ -1120,6 +1127,17 @@ struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max) } } +#else + if (dict_max > GRUB_DECOMPRESSOR_DICT_SIZE) + return NULL; + + s = &lzma2; + + if (dict_max > 0) { + s->dict.buf = (void *) &dict; + } +#endif + s->dict.allocated = dict_max; return s; @@ -1135,6 +1153,7 @@ enum xz_ret xz_dec_lzma2_reset( s->dict.size = 2 + (props & 1); s->dict.size <<= (props >> 1) + 11; +#ifndef GRUB_EMBED_DECOMPRESSOR if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size) { /* enlarge dictionary buffer */ @@ -1146,7 +1165,10 @@ enum xz_ret xz_dec_lzma2_reset( s->dict.buf = newdict; s->dict.allocated = s->dict.size; } - +#else + if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size) + return XZ_MEMLIMIT_ERROR; +#endif s->dict.end = s->dict.size; s->lzma.len = 0; @@ -1159,10 +1181,12 @@ enum xz_ret xz_dec_lzma2_reset( return XZ_OK; } -void xz_dec_lzma2_end(struct xz_dec_lzma2 *s) +void xz_dec_lzma2_end(struct xz_dec_lzma2 *s __attribute__ ((unused))) { +#ifndef GRUB_EMBED_DECOMPRESSOR if (s->dict.allocated > 0) vfree(s->dict.buf); kfree(s); +#endif } diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index 273041edb..3bf201d50 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -31,7 +31,9 @@ struct xz_dec_hash { vli_type unpadded; vli_type uncompressed; +#ifndef GRUB_EMBED_DECOMPRESSOR uint8_t *crc32_context; +#endif }; struct xz_dec { @@ -247,9 +249,11 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) > s->block_header.uncompressed) return XZ_DATA_ERROR; +#ifndef GRUB_EMBED_DECOMPRESSOR if (s->has_crc32) GRUB_MD_CRC32->write(s->crc32_context,b->out + s->out_start, b->out_pos - s->out_start); +#endif if (ret == XZ_STREAM_END) { if (s->block_header.compressed != VLI_UNKNOWN @@ -269,8 +273,10 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) s->block.hash.uncompressed += s->block.uncompressed; +#ifndef GRUB_EMBED_DECOMPRESSOR GRUB_MD_CRC32->write(s->block.hash.crc32_context, (const uint8_t *)&s->block.hash, 2 * sizeof(vli_type)); +#endif ++s->block.count; } @@ -283,7 +289,9 @@ static void index_update(struct xz_dec *s, const struct xz_buf *b) { size_t in_used = b->in_pos - s->in_start; s->index.size += in_used; +#ifndef GRUB_EMBED_DECOMPRESSOR GRUB_MD_CRC32->write(s->crc32_context,b->in + s->in_start, in_used); +#endif } /* @@ -328,8 +336,10 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) case SEQ_INDEX_UNCOMPRESSED: s->index.hash.uncompressed += s->vli; +#ifndef GRUB_EMBED_DECOMPRESSOR GRUB_MD_CRC32->write(s->index.hash.crc32_context, (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); +#endif --s->index.count; s->index.sequence = SEQ_INDEX_UNPADDED; @@ -346,24 +356,30 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) */ static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b) { +#ifndef GRUB_EMBED_DECOMPRESSOR if(s->crc32_temp == 0) { GRUB_MD_CRC32->final(s->crc32_context); s->crc32_temp = get_unaligned_be32(GRUB_MD_CRC32->read(s->crc32_context)); } +#endif do { if (b->in_pos == b->in_size) return XZ_OK; +#ifndef GRUB_EMBED_DECOMPRESSOR if (((s->crc32_temp >> s->pos) & 0xFF) != b->in[b->in_pos++]) return XZ_DATA_ERROR; +#endif s->pos += 8; } while (s->pos < 32); +#ifndef GRUB_EMBED_DECOMPRESSOR GRUB_MD_CRC32->init(s->crc32_context); +#endif s->crc32_temp = 0; s->pos = 0; @@ -376,6 +392,7 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) if (! memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE)) return XZ_FORMAT_ERROR; +#ifndef GRUB_EMBED_DECOMPRESSOR uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; GRUB_MD_CRC32->init(crc32_context); @@ -387,6 +404,7 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) if(resultcrc != readcrc) return XZ_DATA_ERROR; +#endif /* * Decode the Stream Flags field. Of integrity checks, we support @@ -407,6 +425,7 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) if (! memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE)) return XZ_DATA_ERROR; +#ifndef GRUB_EMBED_DECOMPRESSOR uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; GRUB_MD_CRC32->init(crc32_context); @@ -418,6 +437,7 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) if(resultcrc != readcrc) return XZ_DATA_ERROR; +#endif /* * Validate Backward Size. Note that we never added the size of the @@ -447,7 +467,7 @@ static enum xz_ret dec_block_header(struct xz_dec *s) * eight bytes so this is safe. */ s->temp.size -= 4; - +#ifndef GRUB_EMBED_DECOMPRESSOR uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; GRUB_MD_CRC32->init(crc32_context); @@ -459,6 +479,7 @@ static enum xz_ret dec_block_header(struct xz_dec *s) if (resultcrc != readcrc) return XZ_DATA_ERROR; +#endif s->temp.pos = 2; @@ -669,6 +690,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) /* Finish the CRC32 value and Index size. */ index_update(s, b); +#ifndef GRUB_EMBED_DECOMPRESSOR /* Compare the hashes to validate the Index field. */ GRUB_MD_CRC32->final(s->block.hash.crc32_context); GRUB_MD_CRC32->final(s->index.hash.crc32_context); @@ -681,6 +703,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) { return XZ_DATA_ERROR; } +#endif s->sequence = SEQ_INDEX_CRC32; @@ -764,12 +787,22 @@ enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b) return ret; } +#ifdef GRUB_EMBED_DECOMPRESSOR +struct xz_dec decoder; +#endif + struct xz_dec * xz_dec_init(uint32_t dict_max) { - struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct xz_dec *s; +#ifdef GRUB_EMBED_DECOMPRESSOR + s = &decoder; +#else + s = kmalloc(sizeof(*s), GFP_KERNEL); if (s == NULL) return NULL; +#endif +#ifndef GRUB_EMBED_DECOMPRESSOR /* prepare CRC32 calculators */ if(GRUB_MD_CRC32 == NULL) { @@ -803,10 +836,11 @@ struct xz_dec * xz_dec_init(uint32_t dict_max) GRUB_MD_CRC32->init(s->crc32_context); - s->crc32_temp = 0; GRUB_MD_CRC32->init(s->index.hash.crc32_context); GRUB_MD_CRC32->init(s->block.hash.crc32_context); +#endif + s->crc32_temp = 0; s->single_call = dict_max == 0; @@ -828,7 +862,9 @@ error_lzma2: xz_dec_bcj_end(s->bcj); error_bcj: #endif +#ifndef GRUB_EMBED_DECOMPRESSOR kfree(s); +#endif return NULL; } @@ -839,34 +875,45 @@ void xz_dec_reset(struct xz_dec *s) s->pos = 0; { +#ifndef GRUB_EMBED_DECOMPRESSOR uint8_t *t; t = s->block.hash.crc32_context; +#endif memzero(&s->block, sizeof(s->block)); +#ifndef GRUB_EMBED_DECOMPRESSOR s->block.hash.crc32_context = t; t = s->index.hash.crc32_context; +#endif memzero(&s->index, sizeof(s->index)); +#ifndef GRUB_EMBED_DECOMPRESSOR s->index.hash.crc32_context = t; +#endif } s->temp.pos = 0; s->temp.size = STREAM_HEADER_SIZE; +#ifndef GRUB_EMBED_DECOMPRESSOR GRUB_MD_CRC32->init(s->crc32_context); - s->crc32_temp = 0; GRUB_MD_CRC32->init(s->index.hash.crc32_context); GRUB_MD_CRC32->init(s->block.hash.crc32_context); - +#endif + s->crc32_temp = 0; } void xz_dec_end(struct xz_dec *s) { if (s != NULL) { xz_dec_lzma2_end(s->lzma2); +#ifndef GRUB_EMBED_DECOMPRESSOR kfree(s->index.hash.crc32_context); kfree(s->block.hash.crc32_context); kfree(s->crc32_context); +#endif #ifdef XZ_DEC_BCJ xz_dec_bcj_end(s->bcj); #endif +#ifndef GRUB_EMBED_DECOMPRESSOR kfree(s); +#endif } } diff --git a/include/grub/decompressor.h b/include/grub/decompressor.h new file mode 100644 index 000000000..4d99c41f7 --- /dev/null +++ b/include/grub/decompressor.h @@ -0,0 +1,28 @@ +/* + * 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_DECOMPRESSOR_HEADER +#define GRUB_DECOMPRESSOR_HEADER 1 + +void +grub_decompress_core (void *src, void *dst, unsigned long srcsize, + unsigned long dstsize); + +#define GRUB_DECOMPRESSOR_DICT_SIZE (1 << 16) + +#endif diff --git a/include/grub/lib/LzmaDec.h b/include/grub/lib/LzmaDec.h index 1e66b74d7..16914c961 100644 --- a/include/grub/lib/LzmaDec.h +++ b/include/grub/lib/LzmaDec.h @@ -27,7 +27,7 @@ #ifndef __LZMADEC_H #define __LZMADEC_H -#include "Types.h" +#include "LzmaTypes.h" /* #define _LZMA_PROB32 */ /* _LZMA_PROB32 can increase the speed on some CPUs, From 4eff79d2f93b4f812165fd6318657a198fc06c48 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 10:36:44 +0100 Subject: [PATCH 0244/1414] * grub-core/kern/emu/hostdisk.c (find_system_device): Only try to convert partition names to disk names if the new `convert' parameter is set. (grub_util_biosdisk_get_grub_dev): If opening the disk device returns GRUB_ERR_UNKNOWN_DEVICE, treat the partition device as a disk in its own right. This can happen with Xen disk images. --- ChangeLog | 10 ++++++++- grub-core/kern/emu/hostdisk.c | 38 ++++++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f4835ca7..91e67512e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,17 @@ +2010-09-21 Colin Watson + + * grub-core/kern/emu/hostdisk.c (find_system_device): Only try to + convert partition names to disk names if the new `convert' parameter + is set. + (grub_util_biosdisk_get_grub_dev): If opening the disk device + returns GRUB_ERR_UNKNOWN_DEVICE, treat the partition device as a + disk in its own right. This can happen with Xen disk images. + 2010-09-21 Yves Blusseau * util/grub-editenv.c: Update strings to avoid warnings when generating grub.pot file. * util/grub-setup.c: Likewise. - 2010-09-21 Vladimir Serbinenko diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e53d9d440..d38208fdc 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1378,12 +1378,15 @@ device_is_wholedisk (const char *os_dev) #endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */ static int -find_system_device (const char *os_dev, struct stat *st, int add) +find_system_device (const char *os_dev, struct stat *st, int convert, int add) { unsigned int i; char *os_disk; - os_disk = convert_system_partition_to_system_disk (os_dev, st); + if (convert) + os_disk = convert_system_partition_to_system_disk (os_dev, st); + else + os_disk = xstrdup (os_dev); if (! os_disk) return -1; @@ -1416,7 +1419,7 @@ grub_util_biosdisk_is_present (const char *os_dev) if (stat (os_dev, &st) < 0) return 0; - return find_system_device (os_dev, &st, 0) != -1; + return find_system_device (os_dev, &st, 1, 0) != -1; } char * @@ -1431,7 +1434,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - drive = find_system_device (os_dev, &st, 1); + drive = find_system_device (os_dev, &st, 1, 1); if (drive < 0) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, @@ -1514,7 +1517,32 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) free (name); if (! disk) - return 0; + { + /* We already know that the partition exists. Given that we already + checked the device map above, we can only get + GRUB_ERR_UNKNOWN_DEVICE at this point if the disk does not exist. + This can happen on Xen, where disk images in the host can be + assigned to devices that have partition-like names in the guest + but are really more like disks. */ + if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + { + grub_util_warn + ("disk does not exist, so falling back to partition device %s", + os_dev); + + drive = find_system_device (os_dev, &st, 0, 1); + if (drive < 0) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "no mapping exists for `%s'", os_dev); + return 0; + } + + return make_device_name (drive, -1, -1); + } + else + return 0; + } partname = NULL; grub_partition_iterate (disk, find_partition); From a4c1d277c1ce3bd49fc6d76b5b109d06e3307d30 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Tue, 21 Sep 2010 11:42:30 +0200 Subject: [PATCH 0245/1414] Keep boot and grub directory names in sync with utils scripts * configure.ac: Define GRUB_BOOT_DIR_NAME and GRUB_DIR_NAME macros. * config.h.in: Add previous macros. * include/grub/emu/misc.h (DEFAULT_DIRECTORY): Use previous macros. * util/grub-install.in: Use $bootdir and $grubdir variables. --- ChangeLog | 9 +++++++++ config.h.in | 4 ++++ configure.ac | 4 ++++ include/grub/emu/misc.h | 6 +++--- util/grub-install.in | 4 ++-- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91e67512e..2061ec2a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-21 Yves Blusseau + + Keep boot and grub directory names in sync with utils scripts + + * configure.ac: Define GRUB_BOOT_DIR_NAME and GRUB_DIR_NAME macros. + * config.h.in: Add previous macros. + * include/grub/emu/misc.h (DEFAULT_DIRECTORY): Use previous macros. + * util/grub-install.in: Use $bootdir and $grubdir variables. + 2010-09-21 Colin Watson * grub-core/kern/emu/hostdisk.c (find_system_device): Only try to diff --git a/config.h.in b/config.h.in index 4ac9ab5d6..6d7d95dec 100644 --- a/config.h.in +++ b/config.h.in @@ -24,6 +24,10 @@ #define PACKAGE_NAME "@PACKAGE_NAME@" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" +/* Default boot directory name" */ +#define GRUB_BOOT_DIR_NAME "@bootdirname@" +/* Default grub directory name */ +#define GRUB_DIR_NAME "@grubdirname@" /* Define to 1 if GCC generates calls to __enable_execute_stack(). */ #define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@ /* Define to 1 if GCC generates calls to __register_frame_info(). */ diff --git a/configure.ac b/configure.ac index f9abafcf0..3bc2b754a 100644 --- a/configure.ac +++ b/configure.ac @@ -187,9 +187,13 @@ case "$host_os" in esac bootdirname=`echo "$bootdirname" | sed "$program_transform_name"` AC_SUBST(bootdirname) +AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname", + [Default boot directory name]") grubdirname=`echo "$PACKAGE" | sed "$program_transform_name"` AC_SUBST(grubdirname) +AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname", + [Default grub directory name]) # # Checks for build programs. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 51cad596a..47a80d3d7 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -19,7 +19,7 @@ #ifndef GRUB_EMU_MISC_H #define GRUB_EMU_MISC_H 1 -#include +#include #include #include @@ -35,9 +35,9 @@ #ifdef __NetBSD__ /* NetBSD uses /boot for its boot block. */ -# define DEFAULT_DIRECTORY "/grub" +# define DEFAULT_DIRECTORY "/"GRUB_DIR_NAME #else -# define DEFAULT_DIRECTORY "/boot/grub" +# define DEFAULT_DIRECTORY "/"GRUB_BOOT_DIR_NAME"/"GRUB_DIR_NAME #endif #define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" diff --git a/util/grub-install.in b/util/grub-install.in index ebbd63c42..86c6aa13d 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -561,9 +561,9 @@ $grub_mkimage ${config_opt} -d ${pkglibdir} -O ${mkimage_target} --output=${grub # Backward-compatibility kludges if [ "${target_cpu}-${platform}" = "mips-yeeloong" ]; then - cp ${grubdir}/core.${imgext} /boot/grub.elf + cp ${grubdir}/core.${imgext} ${bootdir}/grub.elf elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then - cp ${grubdir}/core.${imgext} /boot/grub/grub + cp ${grubdir}/core.${imgext} ${grubdir}/grub elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ]; then $grub_mkimage ${config_opt} -d ${pkglibdir} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 fi From c4fe27a827ba4b68f7c692218321c963bc7f06e1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 10:56:16 +0100 Subject: [PATCH 0246/1414] * grub-core/commands/hashsum.c (aliases): Add sha1sum alias. (GRUB_MOD_INIT): Register sha1sum command. (GRUB_MOD_FINI): Unregister sha1sum command. --- ChangeLog | 6 ++++++ grub-core/commands/hashsum.c | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2061ec2a3..685390ff7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-21 Colin Watson + + * grub-core/commands/hashsum.c (aliases): Add sha1sum alias. + (GRUB_MOD_INIT): Register sha1sum command. + (GRUB_MOD_FINI): Unregister sha1sum command. + 2010-09-21 Yves Blusseau Keep boot and grub directory names in sync with utils scripts diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index df297b585..693f604b3 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -40,6 +40,7 @@ struct { const char *name; const char *hashname; } aliases[] = { {"sha256sum", "sha256"}, {"sha512sum", "sha512"}, + {"sha1sum", "sha1"}, {"md5sum", "md5"}, {"crc", "crc32"}, }; @@ -249,7 +250,7 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt, return GRUB_ERR_NONE; } -static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512 , cmd_crc; +static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc; GRUB_MOD_INIT(hashsum) { @@ -263,6 +264,11 @@ GRUB_MOD_INIT(hashsum) "[FILE1 [FILE2 ...]]"), N_("Compute or check hash checksum."), options); + cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + "Compute or check hash checksum.", + options); cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0, N_("[-c FILE [-p PREFIX]] " "[FILE1 [FILE2 ...]]"), @@ -285,6 +291,7 @@ GRUB_MOD_FINI(hashsum) { grub_unregister_extcmd (cmd); grub_unregister_extcmd (cmd_md5); + grub_unregister_extcmd (cmd_sha1); grub_unregister_extcmd (cmd_sha256); grub_unregister_extcmd (cmd_sha512); grub_unregister_extcmd (cmd_crc); From b830cd16a11c28f1bccbcbcc6cc1f58f0cb1b00f Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Tue, 21 Sep 2010 12:02:59 +0200 Subject: [PATCH 0247/1414] * conf/Makefile.common (CPPFLAGS_GNULIB): Replace $(top_srcdir) with $(top_builddir). --- ChangeLog | 5 +++++ conf/Makefile.common | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 685390ff7..586380b96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-21 Yves Blusseau + + * conf/Makefile.common (CPPFLAGS_GNULIB): Replace $(top_srcdir) with + $(top_builddir). + 2010-09-21 Colin Watson * grub-core/commands/hashsum.c (aliases): Add sha1sum alias. diff --git a/conf/Makefile.common b/conf/Makefile.common index baac922c1..35f4dfa6e 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -81,7 +81,7 @@ CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -CPPFLAGS_GNULIB = -I$(top_srcdir)/grub-core/gnulib +CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib CFLAGS_POSIX = -fno-builtin CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap From d309a16e26ed8e42e8aec1d6a492ae89f896b6a1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 11:14:06 +0100 Subject: [PATCH 0248/1414] * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Make "Compute or check hash checksum." consistently translatable. --- ChangeLog | 5 +++++ grub-core/commands/hashsum.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 586380b96..c8a99bbfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-21 Colin Watson + + * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Make "Compute or + check hash checksum." consistently translatable. + 2010-09-21 Yves Blusseau * conf/Makefile.common (CPPFLAGS_GNULIB): Replace $(top_srcdir) with diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index 693f604b3..8b6806e45 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -257,7 +257,7 @@ GRUB_MOD_INIT(hashsum) cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0, "hashsum -h HASH [-c FILE [-p PREFIX]] " "[FILE1 [FILE2 ...]]", - "Compute or check hash checksum.", + N_("Compute or check hash checksum."), options); cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0, N_("[-c FILE [-p PREFIX]] " @@ -267,12 +267,12 @@ GRUB_MOD_INIT(hashsum) cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0, N_("[-c FILE [-p PREFIX]] " "[FILE1 [FILE2 ...]]"), - "Compute or check hash checksum.", + N_("Compute or check hash checksum."), options); cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0, N_("[-c FILE [-p PREFIX]] " "[FILE1 [FILE2 ...]]"), - "Compute or check hash checksum.", + N_("Compute or check hash checksum."), options); cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0, N_("[-c FILE [-p PREFIX]] " From 5c5277839aa9f6b482b4831580d4fd672d6270e5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 12:10:36 +0100 Subject: [PATCH 0249/1414] * util/grub-install.in: Fix the bootloader ID option to be consistently --bootloader-id, not --bootloader_id. Reported by: KESHAV P.R. --- ChangeLog | 6 ++++++ util/grub-install.in | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8a99bbfc..8b2f5556c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-21 Colin Watson + + * util/grub-install.in: Fix the bootloader ID option to be + consistently --bootloader-id, not --bootloader_id. + Reported by: KESHAV P.R. + 2010-09-21 Colin Watson * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Make "Compute or diff --git a/util/grub-install.in b/util/grub-install.in index 86c6aa13d..cace82593 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -191,8 +191,8 @@ do --bootloader-id) bootloader_id=`argument $option "$@"`; shift;; - --bootloader_id=*) - bootloader_id=`echo "$option" | sed 's/--bootloader_id=//'` ;; + --bootloader-id=*) + bootloader_id=`echo "$option" | sed 's/--bootloader-id=//'` ;; --grub-mkimage) grub_mkimage=`argument $option "$@"`; shift;; From 8d5e2af3fcd140c7af7799266b256ced501144a0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 13:37:50 +0100 Subject: [PATCH 0250/1414] * conf/Makefile.common (CPPFLAGS_GNULIB): Add $(top_srcdir)/grub-core/gnulib as well as $(top_builddir)/grub-core/gnulib. Reported by: KESHAV P.R. --- ChangeLog | 7 +++++++ conf/Makefile.common | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8b2f5556c..1faaea88b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-09-21 Colin Watson + + * conf/Makefile.common (CPPFLAGS_GNULIB): Add + $(top_srcdir)/grub-core/gnulib as well as + $(top_builddir)/grub-core/gnulib. + Reported by: KESHAV P.R. + 2010-09-21 Colin Watson * util/grub-install.in: Fix the bootloader ID option to be diff --git a/conf/Makefile.common b/conf/Makefile.common index 35f4dfa6e..ea16ab159 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -81,7 +81,7 @@ CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib +CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib CFLAGS_POSIX = -fno-builtin CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap From d7dbe92395c489d92083fb315c4d1e4afcb45012 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 13:41:23 +0100 Subject: [PATCH 0251/1414] * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Make tpart non-const, so that we can assign to it. (Since this is a typedef, the constness refers to the pointer rather than what it points to.) --- ChangeLog | 7 +++++++ grub-core/disk/efi/efidisk.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1faaea88b..b4438a7be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-09-21 Colin Watson + + * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Make + tpart non-const, so that we can assign to it. (Since this is a + typedef, the constness refers to the pointer rather than what it + points to.) + 2010-09-21 Colin Watson * conf/Makefile.common (CPPFLAGS_GNULIB): Add diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 293467a68..08094fa5c 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -727,7 +727,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) { /* This is a hard disk partition. */ grub_disk_t parent = 0; - const grub_partition_t tpart = NULL; + grub_partition_t tpart = NULL; char *device_name; grub_efi_device_path_t *dup_dp, *dup_ldp; grub_efi_hard_drive_device_path_t hd; From 174de8f34065d3dbc3cc4a4c8c90fb067c068dd5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 16:13:04 +0100 Subject: [PATCH 0252/1414] * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Change type of `err' to grub_usb_err_t. Reported and tested by: KESHAV P.R. --- ChangeLog | 6 ++++++ grub-core/bus/usb/usbhub.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b4438a7be..8514ef49b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-21 Colin Watson + + * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Change type of + `err' to grub_usb_err_t. + Reported and tested by: KESHAV P.R. + 2010-09-21 Colin Watson * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Make diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 2a5cc3be9..f08910d2b 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -309,7 +309,7 @@ detach_device (grub_usb_device_t dev) static void poll_nonroot_hub (grub_usb_device_t dev) { - grub_err_t err; + grub_usb_err_t err; unsigned i; grub_uint8_t changed; grub_size_t actual; From b031012d7067d9255e15c808889ca91b72bfb319 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 16:58:08 +0100 Subject: [PATCH 0253/1414] * grub-core/commands/efi/lsefimmap.c (grub_cmd_lsefimmap): NumberOfPages is UINT64 according to the UEFI specification, not UINTN. Fix printf format. --- ChangeLog | 6 ++++++ grub-core/commands/efi/lsefimmap.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8514ef49b..ee71dff37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-21 Colin Watson + + * grub-core/commands/efi/lsefimmap.c (grub_cmd_lsefimmap): + NumberOfPages is UINT64 according to the UEFI specification, not + UINTN. Fix printf format. + 2010-09-21 Colin Watson * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Change type of diff --git a/grub-core/commands/efi/lsefimmap.c b/grub-core/commands/efi/lsefimmap.c index 30780447a..2bb5dcb5d 100644 --- a/grub-core/commands/efi/lsefimmap.c +++ b/grub-core/commands/efi/lsefimmap.c @@ -80,7 +80,7 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)), grub_printf ("Unk %02x ", desc->type); grub_printf (" %016" PRIxGRUB_UINT64_T "-%016" PRIxGRUB_UINT64_T - " %08" PRIxGRUB_EFI_UINTN_T, + " %08" PRIxGRUB_UINT64_T, desc->physical_start, desc->physical_start + (desc->num_pages << 12) - 1, desc->num_pages); From e0a8ef26e4aebe108caf7fc7c852b81c4f7c9b89 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 19:39:51 +0200 Subject: [PATCH 0254/1414] MAke a separate scratch for decompressor --- grub-core/boot/decompressor.c | 23 +++++++++++++++++++++++ grub-core/boot/mips/startup_raw.S | 2 +- grub-core/kern/mips/startup.S | 4 ++-- grub-core/lib/xzembed/xz_dec_lzma2.c | 12 +----------- include/grub/decompressor.h | 6 ++++++ 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/grub-core/boot/decompressor.c b/grub-core/boot/decompressor.c index 5c16fb932..604fc754c 100644 --- a/grub-core/boot/decompressor.c +++ b/grub-core/boot/decompressor.c @@ -80,6 +80,27 @@ void *memmove (void *dest, const void *src, grub_size_t n) void *memcpy (void *dest, const void *src, grub_size_t n) __attribute__ ((alias ("grub_memmove"))); +void *grub_decompressor_scratch; + +void +find_scratch (void *src, void *dst, unsigned long srcsize, + unsigned long dstsize) +{ +#ifdef _mips + /* Decoding from ROM. */ + if (((grub_addr_t) src & 0x10000000)) + { + grub_decompressor_scratch = (char *) dst + dstsize; + return; + } +#endif + if ((char *) src + srcsize > (char *) dst + dstsize) + grub_decompressor_scratch = (char *) src + srcsize; + else + grub_decompressor_scratch = (char *) dst + dstsize; + return; +} + void grub_decompress_core (void *src, void *dst, unsigned long srcsize, unsigned long dstsize) @@ -87,6 +108,8 @@ grub_decompress_core (void *src, void *dst, unsigned long srcsize, struct xz_dec *dec; struct xz_buf buf; + find_scratch (src, dst, srcsize, dstsize); + dec = xz_dec_init (GRUB_DECOMPRESSOR_DICT_SIZE); buf.in = src; diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index 67dc2ec03..d810f2fb4 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -49,7 +49,7 @@ codestart: /* Parse arguments. Has to be done before relocation. So need to do it in asm. */ -#if 0 // def GRUB_MACHINE_MIPS_YEELOONG +#ifdef GRUB_MACHINE_MIPS_YEELOONG move $s2, $zero move $s3, $zero move $s4, $zero diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 1b27a5b1f..97145b818 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -109,10 +109,10 @@ bsscont: bne $t3, $0, bsscont addiu $t1, $t1, 1 - li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH lui $t1, %hi(grub_main) addiu $t1, %lo(grub_main) + lui $sp, %hi(GRUB_MACHINE_MEMORY_STACK_HIGH) jr $t1 - nop + addiu $sp, $sp, %lo(GRUB_MACHINE_MEMORY_STACK_HIGH) diff --git a/grub-core/lib/xzembed/xz_dec_lzma2.c b/grub-core/lib/xzembed/xz_dec_lzma2.c index c55773ce0..7899e9e87 100644 --- a/grub-core/lib/xzembed/xz_dec_lzma2.c +++ b/grub-core/lib/xzembed/xz_dec_lzma2.c @@ -1103,7 +1103,6 @@ enum xz_ret xz_dec_lzma2_run( #ifdef GRUB_EMBED_DECOMPRESSOR #include static struct xz_dec_lzma2 lzma2; -static char dict[GRUB_DECOMPRESSOR_DICT_SIZE]; #endif struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max) @@ -1128,14 +1127,8 @@ struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max) } #else - if (dict_max > GRUB_DECOMPRESSOR_DICT_SIZE) - return NULL; - s = &lzma2; - - if (dict_max > 0) { - s->dict.buf = (void *) &dict; - } + s->dict.buf = grub_decompressor_scratch; #endif s->dict.allocated = dict_max; @@ -1165,9 +1158,6 @@ enum xz_ret xz_dec_lzma2_reset( s->dict.buf = newdict; s->dict.allocated = s->dict.size; } -#else - if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size) - return XZ_MEMLIMIT_ERROR; #endif s->dict.end = s->dict.size; diff --git a/include/grub/decompressor.h b/include/grub/decompressor.h index 4d99c41f7..a6eefb01b 100644 --- a/include/grub/decompressor.h +++ b/include/grub/decompressor.h @@ -23,6 +23,12 @@ void grub_decompress_core (void *src, void *dst, unsigned long srcsize, unsigned long dstsize); +void +find_scratch (void *src, void *dst, unsigned long srcsize, + unsigned long dstsize); + #define GRUB_DECOMPRESSOR_DICT_SIZE (1 << 16) +extern void *grub_decompressor_scratch; + #endif From df7769d8dc91afa2da48b8d57aebaa339f52f82f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Sep 2010 19:03:11 +0100 Subject: [PATCH 0255/1414] * grub-core/normal/menu_entry.c (run): Make sure we always return a value. --- ChangeLog | 5 +++++ grub-core/normal/menu_entry.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee71dff37..272264165 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-21 Colin Watson + + * grub-core/normal/menu_entry.c (run): Make sure we always return + a value. + 2010-09-21 Colin Watson * grub-core/commands/efi/lsefimmap.c (grub_cmd_lsefimmap): diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 096600e09..6cadf81ba 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1207,7 +1207,7 @@ run (struct screen *screen) grub_env_context_open (); menu = grub_zalloc (sizeof (*menu)); if (! menu) - return; + return 0; grub_env_set_menu (menu); } From 758194b076cb4f279feceabea2c1b28cd7a16257 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 20:30:28 +0200 Subject: [PATCH 0256/1414] Allow compression algorithm specification --- grub-core/Makefile.core.def | 18 ++- .../minilib.c} | 39 ------- grub-core/boot/decompressor/none.c | 39 +++++++ grub-core/boot/decompressor/xz.c | 60 ++++++++++ util/grub-mkimage.c | 107 +++++++++++++++--- 5 files changed, 208 insertions(+), 55 deletions(-) rename grub-core/boot/{decompressor.c => decompressor/minilib.c} (76%) create mode 100644 grub-core/boot/decompressor/none.c create mode 100644 grub-core/boot/decompressor/xz.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 58fd7cf5d..48579896c 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -276,9 +276,10 @@ image = { }; image = { - name = decompress; + name = xz_decompress; mips = boot/mips/startup_raw.S; - common = boot/decompressor.c; + common = boot/decompressor/minilib.c; + common = boot/decompressor/xz.c; common = lib/xzembed/xz_dec_bcj.c; common = lib/xzembed/xz_dec_lzma2.c; common = lib/xzembed/xz_dec_stream.c; @@ -293,6 +294,19 @@ image = { enable = mips; }; +image = { + name = none_decompress; + mips = boot/mips/startup_raw.S; + common = boot/decompressor/none.c; + + mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; + + objcopyflags = '-O binary'; + ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; + cflags = '-static-libgcc'; + enable = mips; +}; + image = { name = fwstart; mips_yeeloong = boot/mips/yeeloong/fwstart.S; diff --git a/grub-core/boot/decompressor.c b/grub-core/boot/decompressor/minilib.c similarity index 76% rename from grub-core/boot/decompressor.c rename to grub-core/boot/decompressor/minilib.c index 604fc754c..d1f021933 100644 --- a/grub-core/boot/decompressor.c +++ b/grub-core/boot/decompressor/minilib.c @@ -20,9 +20,6 @@ #include #include -#include "xz.h" -#include "xz_stream.h" - void * memset (void *s, int c, grub_size_t len) { @@ -100,39 +97,3 @@ find_scratch (void *src, void *dst, unsigned long srcsize, grub_decompressor_scratch = (char *) dst + dstsize; return; } - -void -grub_decompress_core (void *src, void *dst, unsigned long srcsize, - unsigned long dstsize) -{ - struct xz_dec *dec; - struct xz_buf buf; - - find_scratch (src, dst, srcsize, dstsize); - - dec = xz_dec_init (GRUB_DECOMPRESSOR_DICT_SIZE); - - buf.in = src; - buf.in_pos = 0; - buf.in_size = srcsize; - buf.out = dst; - buf.out_pos = 0; - buf.out_size = dstsize; - - while (buf.in_pos != buf.in_size) - { - enum xz_ret xzret; - xzret = xz_dec_run (dec, &buf); - switch (xzret) - { - case XZ_MEMLIMIT_ERROR: - case XZ_FORMAT_ERROR: - case XZ_OPTIONS_ERROR: - case XZ_DATA_ERROR: - case XZ_BUF_ERROR: - return; - default: - break; - } - } -} diff --git a/grub-core/boot/decompressor/none.c b/grub-core/boot/decompressor/none.c new file mode 100644 index 000000000..44f56ce90 --- /dev/null +++ b/grub-core/boot/decompressor/none.c @@ -0,0 +1,39 @@ +/* + * 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 + +void +grub_decompress_core (void *src, void *dest, unsigned long n, + unsigned long dstsize __attribute__ ((unused))) +{ + char *d = (char *) dest; + const char *s = (const char *) src; + + if (d < s) + while (n--) + *d++ = *s++; + else + { + d += n; + s += n; + + while (n--) + *--d = *--s; + } +} diff --git a/grub-core/boot/decompressor/xz.c b/grub-core/boot/decompressor/xz.c new file mode 100644 index 000000000..2279118e1 --- /dev/null +++ b/grub-core/boot/decompressor/xz.c @@ -0,0 +1,60 @@ +/* + * 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 "xz.h" +#include "xz_stream.h" + +void +grub_decompress_core (void *src, void *dst, unsigned long srcsize, + unsigned long dstsize) +{ + struct xz_dec *dec; + struct xz_buf buf; + + find_scratch (src, dst, srcsize, dstsize); + + dec = xz_dec_init (GRUB_DECOMPRESSOR_DICT_SIZE); + + buf.in = src; + buf.in_pos = 0; + buf.in_size = srcsize; + buf.out = dst; + buf.out_pos = 0; + buf.out_size = dstsize; + + while (buf.in_pos != buf.in_size) + { + enum xz_ret xzret; + xzret = xz_dec_run (dec, &buf); + switch (xzret) + { + case XZ_MEMLIMIT_ERROR: + case XZ_FORMAT_ERROR: + case XZ_OPTIONS_ERROR: + case XZ_DATA_ERROR: + case XZ_BUF_ERROR: + return; + default: + break; + } + } +} diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index ee007a54b..75343ac30 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -46,6 +46,11 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) #define TARGET_NO_FIELD 0xffffffff + +typedef enum { + COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ +} grub_compression_t; + struct image_target_desc { const char *name; @@ -60,7 +65,8 @@ struct image_target_desc enum { PLATFORM_FLAGS_NONE = 0, - PLATFORM_FLAGS_LZMA = 1 + PLATFORM_FLAGS_LZMA = 1, + PLATFORM_FLAGS_DECOMPRESSORS = 2 } flags; unsigned prefix; unsigned prefix_end; @@ -75,6 +81,7 @@ struct image_target_desc unsigned install_dos_part, install_bsd_part; grub_uint64_t link_addr; unsigned mod_gap, mod_align; + grub_compression_t default_compression; }; struct image_target_desc image_targets[] = @@ -248,7 +255,7 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, - .flags = PLATFORM_FLAGS_LZMA, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, .raw_size = 0, @@ -261,14 +268,15 @@ struct image_target_desc image_targets[] = .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 + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, + .default_compression = COMPRESSION_XZ }, { .name = "mipsel-yeeloong-elf", .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_YEELOONG_ELF, - .flags = PLATFORM_FLAGS_LZMA, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, .raw_size = 0, @@ -281,7 +289,8 @@ struct image_target_desc image_targets[] = .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 + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, + .default_compression = COMPRESSION_NONE }, { .name = "powerpc-ieee1275", @@ -483,7 +492,39 @@ compress_kernel_lzma (char *kernel_img, size_t kernel_size, memcpy (*core_img, kernel_img, raw_size); *core_size = kernel_size - raw_size; - if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size - raw_size, + (unsigned char *) kernel_img + raw_size, + kernel_size - raw_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + grub_util_error (_("cannot compress the kernel image")); + + *core_size += raw_size; +} + +static void +compress_kernel_xz (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size, size_t raw_size) +{ + CLzmaEncProps props; + unsigned char out_props[5]; + size_t out_props_size = 5; + + LzmaEncProps_Init(&props); + props.dictSize = 1 << 16; + props.lc = 3; + props.lp = 0; + props.pb = 2; + props.numThreads = 1; + + if (kernel_size < raw_size) + grub_util_error (_("the core image is too small")); + + *core_img = xmalloc (kernel_size); + memcpy (*core_img, kernel_img, raw_size); + + *core_size = kernel_size - raw_size; + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size - raw_size, (unsigned char *) kernel_img + raw_size, kernel_size - raw_size, &props, out_props, &out_props_size, @@ -495,7 +536,8 @@ compress_kernel_lzma (char *kernel_img, size_t kernel_size, static void compress_kernel (struct image_target_desc *image_target, char *kernel_img, - size_t kernel_size, char **core_img, size_t *core_size) + size_t kernel_size, char **core_img, size_t *core_size, + grub_compression_t comp) { if (image_target->flags & PLATFORM_FLAGS_LZMA) { @@ -504,6 +546,14 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, return; } + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == COMPRESSION_XZ)) + { + compress_kernel_xz (kernel_img, kernel_size, core_img, + core_size, image_target->raw_size); + return; + } + *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); *core_size = kernel_size; @@ -527,7 +577,8 @@ struct fixup_block_list static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *config_path, - struct image_target_desc *image_target, int note) + struct image_target_desc *image_target, int note, + grub_compression_t comp) { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; @@ -539,6 +590,10 @@ 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; + + if (comp == COMPRESSION_AUTO) + comp = image_target->default_compression; + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -655,7 +710,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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); + &core_img, &core_size, comp); grub_util_info ("the core size is 0x%x", core_size); @@ -680,15 +735,27 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], = grub_host_to_target32 (-2); } - if (image_target->id == IMAGE_YEELOONG_FLASH - || image_target->id == IMAGE_YEELOONG_ELF) + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) { char *full_img; size_t full_size; char *decompress_path, *decompress_img; size_t decompress_size; + const char *name; + + switch (comp) + { + case COMPRESSION_XZ: + name = "xz_decompress.img"; + break; + case COMPRESSION_NONE: + name = "none_decompress.img"; + break; + default: + grub_util_error ("unknown compression %d\n", comp); + } - decompress_path = grub_util_get_path (dir, "decompress.img"); + decompress_path = grub_util_get_path (dir, name); decompress_size = grub_util_get_image_size (decompress_path); decompress_img = grub_util_read_image (decompress_path); @@ -1253,6 +1320,7 @@ static struct option options[] = {"output", required_argument, 0, 'o'}, {"note", no_argument, 0, 'n'}, {"format", required_argument, 0, 'O'}, + {"compression", required_argument, 0, 'C'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -1295,6 +1363,7 @@ Make a bootable image of GRUB.\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n\ -O, --format=FORMAT generate an image in format\n\ available formats: %s\n\ + -C, --compression=(xz|none|auto) choose the compression to use\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ @@ -1321,6 +1390,7 @@ main (int argc, char *argv[]) FILE *fp = stdout; int note = 0; struct image_target_desc *image_target = NULL; + grub_compression_t comp = COMPRESSION_AUTO; set_program_name (argv[0]); @@ -1328,7 +1398,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:C:hVvn", options, 0); if (c == -1) break; @@ -1385,6 +1455,15 @@ main (int argc, char *argv[]) config = xstrdup (optarg); break; + case 'C': + if (grub_strcmp (optarg, "xz") == 0) + comp = COMPRESSION_XZ; + else if (grub_strcmp (optarg, "none") == 0) + comp = COMPRESSION_NONE; + else + grub_util_error ("Unknown compression format %s", optarg); + break; + case 'h': usage (0); break; @@ -1443,7 +1522,7 @@ main (int argc, char *argv[]) generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, config, - image_target, note); + image_target, note, comp); fclose (fp); From 2c44e493c756cb211f2a7f85e048f446773382fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Sep 2010 21:35:46 +0200 Subject: [PATCH 0257/1414] Compressor part --- Makefile.util.def | 1 + configure.ac | 6 ++++ util/grub-mkimage.c | 79 ++++++++++++++++++++++++++++++++++----------- 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index f56eab339..6ed4ccb65 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -113,6 +113,7 @@ program = { extra_dist = util/grub-mkimagexx.c; ldadd = libgrub.a; + ldadd = '$(LIBLZMA)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"'; }; diff --git a/configure.ac b/configure.ac index 10723987b..225e02a0d 100644 --- a/configure.ac +++ b/configure.ac @@ -849,6 +849,12 @@ fi AC_SUBST([LIBDEVMAPPER]) +AC_CHECK_LIB([lzma], [lzma_code], + [LIBLZMA="-llzma" + AC_DEFINE([HAVE_LIBLZMA], [1], + [Define to 1 if you have the LZMA library.])],) +AC_SUBST([LIBLZMA]) + AC_CHECK_LIB([zfs], [libzfs_init], [LIBZFS="-lzfs" AC_DEFINE([HAVE_LIBZFS], [1], diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 75343ac30..8a907b414 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -45,6 +45,10 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) +#ifdef HAVE_LIBLZMA +#include +#endif + #define TARGET_NO_FIELD 0xffffffff typedef enum { @@ -269,7 +273,11 @@ struct image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, +#ifdef HAVE_LIBLZMA .default_compression = COMPRESSION_XZ +#else + .default_compression = COMPRESSION_NONE +#endif }, { .name = "mipsel-yeeloong-elf", @@ -492,7 +500,7 @@ compress_kernel_lzma (char *kernel_img, size_t kernel_size, memcpy (*core_img, kernel_img, raw_size); *core_size = kernel_size - raw_size; - if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size - raw_size, + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, (unsigned char *) kernel_img + raw_size, kernel_size - raw_size, &props, out_props, &out_props_size, @@ -506,30 +514,52 @@ static void compress_kernel_xz (char *kernel_img, size_t kernel_size, char **core_img, size_t *core_size, size_t raw_size) { - CLzmaEncProps props; - unsigned char out_props[5]; - size_t out_props_size = 5; - - LzmaEncProps_Init(&props); - props.dictSize = 1 << 16; - props.lc = 3; - props.lp = 0; - props.pb = 2; - props.numThreads = 1; + lzma_stream strm = LZMA_STREAM_INIT; + lzma_ret xzret; + lzma_options_lzma lzopts = { + .dict_size = 1 << 16, + .preset_dict = NULL, + .preset_dict_size = 0, + .lc = 3, + .lp = 0, + .pb = 2, + .mode = LZMA_MODE_NORMAL, + .nice_len = 64, + .mf = LZMA_MF_BT4, + .depth = 0, + }; + lzma_filter fltrs[] = { + { .id = LZMA_FILTER_LZMA2, .options = &lzopts}, + { .id = LZMA_VLI_UNKNOWN, .options = NULL} + }; if (kernel_size < raw_size) grub_util_error (_("the core image is too small")); + xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); + if (xzret != LZMA_OK) + grub_util_error (_("cannot compress the kernel image")); + *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, raw_size); *core_size = kernel_size - raw_size; - if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size - raw_size, - (unsigned char *) kernel_img + raw_size, - kernel_size - raw_size, - &props, out_props, &out_props_size, - 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) - grub_util_error (_("cannot compress the kernel image")); + strm.next_in = (unsigned char *) kernel_img + raw_size; + strm.avail_in = kernel_size - raw_size; + strm.next_out = (unsigned char *) *core_img + raw_size; + strm.avail_out = *core_size; + + while (1) + { + xzret = lzma_code (&strm, LZMA_FINISH); + if (xzret == LZMA_OK) + continue; + if (xzret == LZMA_STREAM_END) + break; + grub_util_error (_("cannot compress the kernel image")); + } + + *core_size -= strm.avail_out; *core_size += raw_size; } @@ -546,6 +576,7 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, return; } +#ifdef HAVE_LIBLZMA if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS && (comp == COMPRESSION_XZ)) { @@ -553,6 +584,11 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, core_size, image_target->raw_size); return; } +#endif + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp != COMPRESSION_NONE)) + grub_util_error ("unknown compression %d\n", comp); *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); @@ -1457,7 +1493,14 @@ main (int argc, char *argv[]) case 'C': if (grub_strcmp (optarg, "xz") == 0) - comp = COMPRESSION_XZ; + { +#ifdef HAVE_LIBLZMA + comp = COMPRESSION_XZ; +#else + grub_util_error ("grub-mkimage is compiled without XZ support", + optarg); +#endif + } else if (grub_strcmp (optarg, "none") == 0) comp = COMPRESSION_NONE; else From 6cc1405144cafb860619ed233f9ccf30518a1ea1 Mon Sep 17 00:00:00 2001 From: starous Date: Tue, 21 Sep 2010 21:57:57 +0200 Subject: [PATCH 0258/1414] .../serial/common.c - added missing configuration --- ChangeLog | 5 +++++ grub-core/bus/usb/serial/common.c | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 272264165..2a7889bf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-21 Aleš Nesrsta + + * grub-core/bus/usb/serial/common.c (grub_usbserial_attach): + Added missing configuration of USB device. + 2010-09-21 Colin Watson * grub-core/normal/menu_entry.c (run): Make sure we always return diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c index 6b5b90059..ee8794de0 100644 --- a/grub-core/bus/usb/serial/common.c +++ b/grub-core/bus/usb/serial/common.c @@ -44,6 +44,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, struct grub_serial_port *port; int j; struct grub_usb_desc_if *interf; + grub_usb_err_t err = GRUB_USB_ERR_NONE; interf = usbdev->config[configno].interf[interfno].descif; @@ -80,7 +81,12 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, port->out_endp = endp; } } - if (!port->out_endp || !port->in_endp) + + /* Configure device */ + if (port->out_endp && port->in_endp) + err = grub_usb_set_configuration (usbdev, configno + 1); + + if (!port->out_endp || !port->in_endp || err) { grub_free (port->name); grub_free (port); From bf5f1dc6d267a6734cd4ead2cbcf7d200411158c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 00:51:54 +0200 Subject: [PATCH 0259/1414] Write total module size before compressing --- util/grub-mkimage.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 8a907b414..73713f2bc 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -273,11 +273,7 @@ struct image_target_desc image_targets[] = .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN, -#ifdef HAVE_LIBLZMA - .default_compression = COMPRESSION_XZ -#else .default_compression = COMPRESSION_NONE -#endif }, { .name = "mipsel-yeeloong-elf", @@ -744,13 +740,19 @@ 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); grub_util_info ("the core size is 0x%x", core_size); - if (image_target->total_module_size != TARGET_NO_FIELD) + 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_host_to_target32 (total_module_size); if (image_target->kernel_image_size != TARGET_NO_FIELD) From 67c4bb722d425aacd968d4462ca4aff8beb7b303 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 00:52:33 +0200 Subject: [PATCH 0260/1414] Align scratch --- grub-core/boot/decompressor/minilib.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/grub-core/boot/decompressor/minilib.c b/grub-core/boot/decompressor/minilib.c index d1f021933..f2a2ef7e5 100644 --- a/grub-core/boot/decompressor/minilib.c +++ b/grub-core/boot/decompressor/minilib.c @@ -87,13 +87,16 @@ find_scratch (void *src, void *dst, unsigned long srcsize, /* Decoding from ROM. */ if (((grub_addr_t) src & 0x10000000)) { - grub_decompressor_scratch = (char *) dst + dstsize; + grub_decompressor_scratch = (void *) ALIGN_UP((grub_addr_t) dst + dstsize, + 256); return; } #endif if ((char *) src + srcsize > (char *) dst + dstsize) - grub_decompressor_scratch = (char *) src + srcsize; + grub_decompressor_scratch = (void *) ALIGN_UP ((grub_addr_t) src + srcsize, + 256); else - grub_decompressor_scratch = (char *) dst + dstsize; + grub_decompressor_scratch = (void *) ALIGN_UP ((grub_addr_t) dst + dstsize, + 256); return; } From 9a0e5c815e76c48141d1e126682b1473036be669 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 00:53:34 +0200 Subject: [PATCH 0261/1414] Fix bugs in asm code --- grub-core/boot/mips/startup_raw.S | 7 ++++--- grub-core/kern/mips/startup.S | 34 +++++++++++++++++++------------ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index d810f2fb4..c41ce8257 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -67,10 +67,11 @@ argcont: #define DO_PARSE(str, reg) \ addiu $t2, $s0, (str-base);\ bal parsestr;\ + nop ;\ beq $v0, $zero, 1f;\ nop ;\ b 2f;\ - move reg, $v0; + move reg, $v0; \ 1: DO_PARSE (busclockstr, $s2) DO_PARSE (cpuclockstr, $s3) @@ -169,10 +170,10 @@ argdone: */ move $s6, $a3 - lui $sp, %hi(_start) + lui $sp, %hi(_start - 256) bal EXT_C(grub_decompress_core) - addiu $sp, $sp, %lo(_start) + addiu $sp, $sp, %lo(_start - 256) move $a0, $s1 move $a1, $s6 diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 97145b818..ae0e0b187 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -35,6 +35,10 @@ start: bal cont nop + . = _start + GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE +total_module_size: + .long 0 + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) @@ -70,13 +74,13 @@ cont: #endif /* Move the modules out of BSS. */ - lui $t2, %hi(_end) - addiu $t2, %lo(_end) + lui $t2, %hi(__bss_start) + addiu $t2, %lo(__bss_start) lui $t1, %hi(_end) addiu $t1, %lo(_end) - addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) - li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) + addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) + li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) nor $t3, $t3, $0 and $t1, $t1, $t3 @@ -85,29 +89,33 @@ cont: /* Backward copy. */ add $t1, $t1, $t3 add $t2, $t2, $t3 - addiu $t1, $t1, 0xffff - addiu $t2, $t2, 0xffff + addiu $t1, $t1, -1 + addiu $t2, $t2, -1 /* $t2 is source. $t1 is destination. $t3 is size. */ modulesmovcont: + beq $t3, $0, modulesmovdone + nop lb $t4, 0($t2) sb $t4, 0($t1) + addiu $t2, $t2, -1 addiu $t1, $t1, -1 - addiu $t3, $t3, -1 - bne $t3, $0, modulesmovcont - addiu $t2, $t2, -1 - + b modulesmovcont + addiu $t3, $t3, -1 +modulesmovdone: + /* Clean BSS. */ lui $t1, %hi(__bss_start) - addiu $t1, %lo(__bss_start) + addiu $t1, $t1, %lo(__bss_start) lui $t2, %hi(_end) - addiu $t2, %lo(_end) + addiu $t2, $t2, %lo(_end) bsscont: sb $0,0($t1) + addiu $t1, $t1, 1 sltu $t3, $t1, $t2 bne $t3, $0, bsscont - addiu $t1, $t1, 1 + nop lui $t1, %hi(grub_main) addiu $t1, %lo(grub_main) From 7835dfd3e838160d8169ae5771368b615eefeca9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 17:13:21 +0200 Subject: [PATCH 0262/1414] * grub-core/loader/multiboot_mbi2.c (GRUB_MACHINE_EFI): Add missing include. --- ChangeLog | 5 +++++ grub-core/loader/multiboot_mbi2.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0f9b33a82..70588bf17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-22 Vladimir Serbinenko + + * grub-core/loader/multiboot_mbi2.c (GRUB_MACHINE_EFI): Add missing + include. + 2010-09-22 Vladimir Serbinenko Implement EFI and ACPI multiboot2 extensions. diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index f7a05bcac..6e1d5c8be 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -34,6 +34,10 @@ #include #include +#if defined (GRUB_MACHINE_EFI) +#include +#endif + #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) #include #define HAS_VGA_TEXT 1 From 6b1b3423dd0d5c38d561d5b7ab5ea082ca7ef620 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 17:14:14 +0200 Subject: [PATCH 0263/1414] Fix error handling in ofnet --- grub-core/net/drivers/ieee1275/ofnet.c | 42 +++++++++++++++----------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 064f3d280..ce5276efe 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -3,18 +3,21 @@ #include #include -static -grub_err_t card_open (struct grub_net_card *dev) +static grub_err_t +card_open (struct grub_net_card *dev) { - + int status; struct grub_ofnetcard_data *data = dev->data; - return grub_ieee1275_open (data->path,&(data->handle)); + status = grub_ieee1275_open (data->path,&(data->handle)); + + if (status) + return grub_error (GRUB_ERR_IO, "couldn't open network card"); + return GRUB_ERR_NONE; } -static -grub_err_t card_close (struct grub_net_card *dev) +static grub_err_t +card_close (struct grub_net_card *dev) { - struct grub_ofnetcard_data *data = dev->data; if (data->handle) @@ -22,18 +25,23 @@ grub_err_t card_close (struct grub_net_card *dev) return GRUB_ERR_NONE; } -static -grub_err_t send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) -{ - +static grub_err_t +send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +{ int actual; + int status; struct grub_ofnetcard_data *data = dev->data; - return grub_ieee1275_write (data->handle,pack->data,pack->tail - pack->data,&actual); + status = grub_ieee1275_write (data->handle, pack->data, + pack->tail - pack->data, &actual); + + if (status) + return grub_error (GRUB_ERR_IO, "couldn't send network packet"); + return GRUB_ERR_NONE; } -static -grub_err_t get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) +static grub_err_t +get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) { int actual, rc; @@ -41,10 +49,8 @@ grub_err_t get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pac grub_netbuff_clear(pack); do - { - rc = grub_ieee1275_read (data->handle,pack->data,1500,&actual); - - }while (actual <= 0 || rc < 0); + rc = grub_ieee1275_read (data->handle, pack->data, 1500, &actual); + while (actual <= 0 || rc < 0); grub_netbuff_put (pack, actual); return GRUB_ERR_NONE; From 90451bb1c951bbc90f479084b28ddb1e09d8ac8d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 17:14:43 +0200 Subject: [PATCH 0264/1414] networking in grub-emu --- grub-core/Makefile.core.def | 6 +++ grub-core/net/drivers/emu/emunet.c | 69 ++++++++++++++++++++++++++++++ include/grub/net.h | 6 ++- 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 grub-core/net/drivers/emu/emunet.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 5cacb6851..2f55ba5ec 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1398,3 +1398,9 @@ module = { ieee1275 = net/drivers/ieee1275/ofnet.c; enable = ieee1275; }; + +module = { + name = emunet; + emu = net/drivers/emu/emunet.c; + enable = ieee1275; +}; diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c new file mode 100644 index 000000000..8914a1d95 --- /dev/null +++ b/grub-core/net/drivers/emu/emunet.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include /* the L2 protocols */ +#include + +static grub_err_t +card_open (struct grub_net_card *dev) +{ + dev->data_num = socket (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (dev->data_num < 0) + return grub_error (GRUB_ERR_IO, "couldn't open packet interface"); + return GRUB_ERR_NONE; +} + +static grub_err_t +card_close (struct grub_net_card *dev) +{ + close (dev->data_num); + return GRUB_ERR_NONE; +} + +static grub_err_t +send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +{ + ssize_t actual; + + actual = write (dev->data_num, pack->data, pack->tail - pack->data); + if (actual < 0) + return grub_error (GRUB_ERR_IO, "couldn't send packets"); + + return GRUB_ERR_NONE; +} + +static grub_err_t +get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) +{ + ssize_t actual; + + grub_netbuff_clear(pack); + actual = read (dev->data_num, pack->data, 1500); + if (actual < 0) + return grub_error (GRUB_ERR_IO, "couldn't receive packets"); + grub_netbuff_put (pack, actual); + + return GRUB_ERR_NONE; +} + +static struct grub_net_card_driver emudriver = +{ + .name = "emu", + .init = card_open, + .fini = card_close, + .send = send_card_buffer, + .recv = get_card_packet +}; + +GRUB_MOD_INIT(emunet) +{ + grub_net_card_driver_register (&emudriver); +} + +GRUB_MODE_FINI(emunet) +{ + grub_net_card_driver_unregister (&emudriver); +} + + + diff --git a/include/grub/net.h b/include/grub/net.h index ad553a69a..de188f615 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -84,7 +84,11 @@ struct grub_net_card struct grub_net_card_driver *driver; grub_net_link_level_address_t default_address; grub_net_card_flags_t flags; - void *data; + union + { + void *data; + int data_num; + }; }; struct grub_net_network_level_interface; From 8f03f0b580d253ca87faf46d84b251fec121b64c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 22 Sep 2010 16:57:49 +0100 Subject: [PATCH 0265/1414] * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix typo in __i386__ conditional. --- ChangeLog | 5 +++++ grub-core/loader/multiboot_mbi2.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 70588bf17..178547359 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-22 Colin Watson + + * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix + typo in __i386__ conditional. + 2010-09-22 Vladimir Serbinenko * grub-core/loader/multiboot_mbi2.c (GRUB_MACHINE_EFI): Add missing diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 6e1d5c8be..a20c82cad 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -715,7 +715,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) } #endif -#if defined (GRUB_MACHINE_EFI) && __i386_ +#if defined (GRUB_MACHINE_EFI) && __i386__ { struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi32 *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_EFI32; From ce3a2ec0256a6442cc9a3b47a6d218baf3412c39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 22 Sep 2010 20:34:20 +0200 Subject: [PATCH 0266/1414] Remove some dead code --- grub-core/Makefile.core.def | 1 - grub-core/net/arp.c | 3 +- grub-core/net/ethernet.c | 1 - grub-core/net/interface.c | 37 ------------------- grub-core/net/ip.c | 2 -- grub-core/net/netbuff.c | 2 +- grub-core/net/tftp.c | 2 -- grub-core/net/udp.c | 3 -- include/grub/net.h | 3 +- include/grub/net/arp.h | 1 - include/grub/net/interface.h | 70 ------------------------------------ include/grub/net/protocol.h | 9 ----- include/grub/net/type_net.h | 33 ----------------- 13 files changed, 3 insertions(+), 164 deletions(-) delete mode 100644 grub-core/net/interface.c delete mode 100644 include/grub/net/interface.h delete mode 100644 include/grub/net/protocol.h delete mode 100644 include/grub/net/type_net.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index d48c5d505..49dbd3f60 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1438,7 +1438,6 @@ module = { common = net/udp.c; common = net/ethernet.c; common = net/arp.c; - common = net/interface.c; common = net/netbuff.c; }; diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 5e10938ae..541b89411 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -92,7 +91,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, return GRUB_ERR_NONE; } current_time = grub_get_time_ms(); - if (current_time - start_time > TIMEOUT_TIME_MS) + if (current_time - start_time > 3000) break; } while (! entry); grub_netbuff_clear(nb); diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index d3a34aec6..a40e1f795 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/grub-core/net/interface.c b/grub-core/net/interface.c deleted file mode 100644 index f17b3e66b..000000000 --- a/grub-core/net/interface.c +++ /dev/null @@ -1,37 +0,0 @@ -/*#include - -#define INTERFACE_REGISTER_FUNCTIONS(layerprevious,layernext) \ -struct grub_net_##layername_layer_protocol *grub_net_##layername_layer_protocols;\ -\ -void grub_net_##layerprevious_##layernext_interface_register (struct grub_net_##layername_layer_protocol *prot)\ -{\ - grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\ - GRUB_AS_LIST (prot));\ -}\ -\ -void grub_net_##layerprevious_##layernext_interface_unregister (struct grub_net_##layername_layer_protocol *prot);\ -{\ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\ - GRUB_AS_LIST (prot));\ -}\ - -INTERFACE_REGISTER_FUNCTIONS("application","transport"); -INTERFACE_REGISTER_FUNCTIONS("transport","network"); -INTERFACE_REGISTER_FUNCTIONS("network","link"); -INTERFACE_REGISTER_FUNCTIONS("link");*/ - -#include -#include -struct grub_net_protocol_stack - *grub_net_protocol_stack_get (char *name) -{ - struct grub_net_protocol_stack *p; - - for (p = grub_net_protocol_stacks; p; p = p->next) - { - if (!grub_strcmp(p->name,name)) - return p; - } - - return NULL; -} diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 264195ad3..023564a5a 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index 4f6a1da84..cc366ae09 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -73,7 +73,7 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) len = ALIGN_UP (len,NETBUFF_ALIGN); data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); - nb = (struct grub_net_buff *) ((int)data + len); + nb = (struct grub_net_buff *) ((grub_uint8_t *) data + len); nb->head = nb->data = nb->tail = data; nb->end = (char *) nb; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index bb518b78f..b9e3f49c4 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 27e23e826..a73431f83 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -1,10 +1,7 @@ #include #include #include -#include #include -#include -#include #include grub_err_t diff --git a/include/grub/net.h b/include/grub/net.h index de188f615..20bf3c0e6 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -23,9 +23,8 @@ #include #include #include +#include #include -#include -#include typedef struct grub_fs *grub_net_app_level_t; diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index e547669a2..1475086e4 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -2,7 +2,6 @@ #define GRUB_NET_ARP_HEADER 1 #include #include -#include /* IANA ARP constant to define hardware type as ethernet */ #define ARPHRD_ETHERNET 1 diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h deleted file mode 100644 index cf24dd22e..000000000 --- a/include/grub/net/interface.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef GRUB_INTERFACE_HEADER -#define GRUB_INTERFACE_HEADER -//#include -#include -#include -#include - -struct grub_net_protocol_stack -{ - struct grub_net_protocol_stack *next; - char *name; - grub_net_protocol_id_t id; - void *interface; -}; - -struct grub_net_application_transport_interface -{ - struct grub_net_transport_network_interface *inner_layer; - void *data; - struct grub_net_application_layer_protocol *app_prot; - struct grub_net_transport_layer_protocol *trans_prot; -}; - -struct grub_net_transport_network_interface -{ - struct grub_net_network_link_interface *inner_layer; - void *data; - struct grub_net_transport_layer_protocol *trans_prot; - struct grub_net_network_layer_protocol *net_prot; -}; - -struct grub_net_network_link_interface -{ - void *data; - struct grub_net_network_layer_protocol *net_prot; - struct grub_net_link_layer_protocol *link_prot; -}; - - -struct grub_net_protocol_stack *grub_net_protocol_stacks; -static inline void -grub_net_stack_register (struct grub_net_protocol_stack *stack) -{ - - grub_list_push (GRUB_AS_LIST_P (&grub_net_protocol_stacks), - GRUB_AS_LIST (stack)); -} -/* -void grub_net_stack_unregister (struct grub_net_protocol_stack *stack) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_protocol_stacks), - GRUB_AS_LIST (stack)); -}*/ - -struct grub_net_protocol_stack *grub_net_protocol_stack_get (char *name); - -/* -static inline void -grub_net_interface_application_transport_register (struct grub_net_application_transport_interface); -static inline void -grub_net_interface_application_transport_unregister (struct grub_net_application_transport_interface); -static inline void -grub_net_interface_transport_network_register (struct grub_net_transport_network_interface); -static inline void -grub_net_interface_transport_network_unregister (struct grub_net_transport_network_interface); -static inline void -grub_net_interface_network_link_register (struct grub_net_network_link_interface); -static inline void -grub_net_interface_network_link_unregister (struct grub_net_network_link_interface);*/ -#endif diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h deleted file mode 100644 index da54b073f..000000000 --- a/include/grub/net/protocol.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef GRUB_PROTOCOL_HEADER -#define GRUB_PROTOCOL_HEADER -#include -#include -#include -#include -#include - -#endif diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h deleted file mode 100644 index f159b1de0..000000000 --- a/include/grub/net/type_net.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef GRUB_TYPES_NET_HEADER -#define GRUB_TYPES_NET_HEADER 1 -#include - - -#define UDP_PCKT 0x11 -#define IP_PCKT 0x0800 -#define TIMEOUT_TIME_MS 3*1000 -typedef enum -{ - GRUB_NET_TFTP_ID, - GRUB_NET_UDP_ID, - GRUB_NET_IPV4_ID, - GRUB_NET_IPV6_ID, - GRUB_NET_ETHERNET_ID, - GRUB_NET_ARP_ID, - GRUB_NET_DHCP_ID -}grub_net_protocol_id_t; - - -typedef union grub_net_network_layer_netaddress -{ - grub_uint32_t ipv4; -} grub_net_network_layer_address_t; - -typedef union grub_net_network_layer_address -{ - struct { - grub_uint32_t base; - int masksize; - } ipv4; -} grub_net_network_layer_netaddress_t; -#endif From 1b655af6854ff0f1f4ad141342335d8211a204bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 22 Sep 2010 23:32:58 +0200 Subject: [PATCH 0267/1414] Define FLOPPY_MAJOR on NetBSD. --- ChangeLog | 4 ++++ grub-core/kern/emu/hostdisk.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 178547359..63f497c39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-22 GrĂ©goire Sutre + + * grub-core/kern/emu/hostdisk.c [__NetBSD__]: Define FLOPPY_MAJOR. + 2010-09-22 Colin Watson * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index d38208fdc..19d3856a2 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -115,6 +115,9 @@ struct hd_geometry # include /* getrawpartition */ # endif /* HAVE_GETRAWPARTITION */ # include +# ifndef FLOPPY_MAJOR +# define FLOPPY_MAJOR 2 +# endif /* ! FLOPPY_MAJOR */ # ifndef RAW_FLOPPY_MAJOR # define RAW_FLOPPY_MAJOR 9 # endif /* ! RAW_FLOPPY_MAJOR */ From 04d22dddd985e49779fbdd570d1b4f0847dc4347 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Sep 2010 00:45:39 +0200 Subject: [PATCH 0268/1414] Fix a bunch of net issues --- grub-core/net/arp.c | 85 ++++++++-------- grub-core/net/drivers/emu/emunet.c | 84 ++++++++++------ grub-core/net/ethernet.c | 14 +-- grub-core/net/ip.c | 11 +- grub-core/net/net.c | 6 +- grub-core/net/tftp.c | 155 +++++++++++------------------ include/grub/net/arp.h | 12 +-- include/grub/net/ethernet.h | 8 ++ include/grub/net/ip.h | 2 - 9 files changed, 181 insertions(+), 196 deletions(-) diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 541b89411..c7b5d0573 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -6,7 +6,7 @@ #include #include -static struct arp_entry arp_table[SIZE_ARP_TABLE]; +static struct arp_entry arp_table[10]; static grub_int8_t new_table_entry = -1; static @@ -19,8 +19,8 @@ void arp_init_table(void) static struct arp_entry * arp_find_entry (const grub_net_network_level_address_t *proto) { - grub_uint8_t i; - for(i=0;i < SIZE_ARP_TABLE; i++) + unsigned i; + for(i = 0; i < ARRAY_SIZE (arp_table); i++) { if(arp_table[i].avail == 1 && arp_table[i].nl_address.ipv4 == proto->ipv4) @@ -48,24 +48,26 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, return GRUB_ERR_NONE; } /* Build a request packet */ - nb = grub_malloc (2048); + nb = grub_netbuff_alloc (2048); + if (!nb) + return grub_errno; grub_netbuff_reserve(nb, 2048); grub_netbuff_push(nb, sizeof(*arp_header) + 2 * (6 + 6)); arp_header = (struct arphdr *)nb->data; - arp_header->hrd = 0; - arp_header->pro = 0; + arp_header->hrd = grub_cpu_to_be16 (GRUB_NET_ARPHRD_ETHERNET); + arp_header->pro = grub_cpu_to_be16 (GRUB_NET_ETHERTYPE_IP); arp_header->hln = 6; - arp_header->pln = 6; - arp_header->op = ARP_REQUEST; + arp_header->pln = 4; + arp_header->op = grub_cpu_to_be16 (ARP_REQUEST); aux = (grub_uint8_t *)arp_header + sizeof(*arp_header); /* Sender hardware address */ grub_memcpy(aux, &inf->hwaddress.mac, 6); aux += 6; /* Sender protocol address */ grub_memcpy(aux, &inf->address.ipv4, 4); - aux += 6; + aux += 4; /* Target hardware address */ - for(i=0; i < 6; i++) + for(i = 0; i < 6; i++) aux[i] = 0x00; aux += 6; /* Target protocol address */ @@ -73,7 +75,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, grub_memset (&target_hw_addr.mac, 0xff, 6); - send_ethernet_packet (inf, nb, target_hw_addr, ARP_ETHERTYPE); + send_ethernet_packet (inf, nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP); grub_netbuff_clear(nb); grub_netbuff_reserve(nb, 2048); @@ -81,7 +83,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, start_time = grub_get_time_ms(); do { - grub_net_recv_ethernet_packet (inf, nb, ARP_ETHERTYPE); + grub_net_recv_ethernet_packet (inf, nb, GRUB_NET_ETHERTYPE_ARP); /* Now check cache table again */ entry = arp_find_entry(proto_addr); if (entry) @@ -90,7 +92,7 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, grub_netbuff_clear(nb); return GRUB_ERR_NONE; } - current_time = grub_get_time_ms(); + current_time = grub_get_time_ms(); if (current_time - start_time > 3000) break; } while (! entry); @@ -99,17 +101,16 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, } grub_err_t -grub_net_arp_receive(struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb) +grub_net_arp_receive (struct grub_net_network_level_interface *inf, + struct grub_net_buff *nb) { struct arphdr *arp_header = (struct arphdr *)nb->data; struct arp_entry *entry; - grub_uint8_t merge = 0; grub_uint8_t *sender_hardware_address, *sender_protocol_address; grub_uint8_t *target_hardware_address, *target_protocol_address; grub_net_network_level_address_t hwaddress; - sender_hardware_address = (grub_uint8_t *)arp_header + sizeof(*arp_header); + sender_hardware_address = (grub_uint8_t *) arp_header + sizeof(*arp_header); sender_protocol_address = sender_hardware_address + arp_header->hln; target_hardware_address = sender_protocol_address + arp_header->pln; target_protocol_address = target_hardware_address + arp_header->hln; @@ -118,40 +119,36 @@ grub_net_arp_receive(struct grub_net_network_level_interface *inf, entry = arp_find_entry(&hwaddress); /* Update sender hardware address */ if (entry) + grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6); + else { - grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6); - merge = 1; - } - /* Am I the protocol address target? */ - if (! grub_memcmp(target_protocol_address, inf->hwaddress.mac, 6)) - { - /* Add sender to cache table */ - if (! merge) - { + /* Add sender to cache table */ if (new_table_entry == -1) - arp_init_table(); + arp_init_table(); entry = &(arp_table[new_table_entry]); entry->avail = 1; grub_memcpy(&entry->nl_address.ipv4, sender_protocol_address, 4); grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6); new_table_entry++; - if (new_table_entry == SIZE_ARP_TABLE) - new_table_entry = 0; - } - if (arp_header->op == ARP_REQUEST) - { - grub_net_link_level_address_t aux; - /* Swap hardware fields */ - grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln); - grub_memcpy(sender_hardware_address, inf->hwaddress.mac, 6); - grub_memcpy(aux.mac, sender_protocol_address, 6); - grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln); - grub_memcpy(target_protocol_address, aux.mac, arp_header->pln); - /* Change operation to REPLY and send packet */ - arp_header->op = ARP_REPLY; - grub_memcpy (aux.mac, target_hardware_address, 6); - send_ethernet_packet (inf, nb, aux, ARP_ETHERTYPE); - } + if (new_table_entry == ARRAY_SIZE (arp_table)) + new_table_entry = 0; + } + + /* Am I the protocol address target? */ + if (grub_memcmp(target_protocol_address, inf->hwaddress.mac, 6) == 0 + && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST) + { + grub_net_link_level_address_t aux; + /* Swap hardware fields */ + grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln); + grub_memcpy(sender_hardware_address, inf->hwaddress.mac, 6); + grub_memcpy(aux.mac, sender_protocol_address, 6); + grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln); + grub_memcpy(target_protocol_address, aux.mac, arp_header->pln); + /* Change operation to REPLY and send packet */ + arp_header->op = grub_be_to_cpu16 (ARP_REPLY); + grub_memcpy (aux.mac, target_hardware_address, 6); + send_ethernet_packet (inf, nb, aux, GRUB_NET_ETHERTYPE_ARP); } return GRUB_ERR_NONE; } diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c index 8914a1d95..9e4e66dce 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -1,68 +1,92 @@ + +#include #include #include -#include -#include /* the L2 protocols */ #include +#include +#include +#include +#include +#include +#include +#include + +static int fd; static grub_err_t -card_open (struct grub_net_card *dev) -{ - dev->data_num = socket (AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (dev->data_num < 0) - return grub_error (GRUB_ERR_IO, "couldn't open packet interface"); - return GRUB_ERR_NONE; -} - -static grub_err_t -card_close (struct grub_net_card *dev) -{ - close (dev->data_num); - return GRUB_ERR_NONE; -} - -static grub_err_t -send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), + struct grub_net_buff *pack) { ssize_t actual; - actual = write (dev->data_num, pack->data, pack->tail - pack->data); + actual = write (fd, pack->data, pack->tail - pack->data); if (actual < 0) return grub_error (GRUB_ERR_IO, "couldn't send packets"); return GRUB_ERR_NONE; } -static grub_err_t -get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) +static grub_size_t +get_card_packet (struct grub_net_card *dev __attribute__ ((unused)), + struct grub_net_buff *pack) { ssize_t actual; grub_netbuff_clear(pack); - actual = read (dev->data_num, pack->data, 1500); + actual = read (fd, pack->data, 1500); if (actual < 0) - return grub_error (GRUB_ERR_IO, "couldn't receive packets"); + { + grub_error (GRUB_ERR_IO, "couldn't receive packets"); + return -1; + } grub_netbuff_put (pack, actual); - return GRUB_ERR_NONE; + return actual; } static struct grub_net_card_driver emudriver = { .name = "emu", - .init = card_open, - .fini = card_close, .send = send_card_buffer, .recv = get_card_packet }; +static struct grub_net_card emucard = +{ + .name = "emu0", + .driver = &emudriver, + .default_address = { + .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, + { .mac = { 0, 1, 2, 3, 4, 5} } + }, + .flags = 0 +}; + GRUB_MOD_INIT(emunet) { - grub_net_card_driver_register (&emudriver); + struct ifreq ifr; + // char fullname[64]; + fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK); + if (fd < 0) + return; + grub_memset (&ifr, 0, sizeof (ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + if (ioctl (fd, TUNSETIFF, &ifr) < 0) + { + close (fd); + fd = -1; + return; + } + grub_net_card_register (&emucard); } -GRUB_MODE_FINI(emunet) +GRUB_MOD_FINI(emunet) { - grub_net_card_driver_unregister (&emudriver); + if (fd >= 0) + { + close (fd); + grub_net_card_unregister (&emucard); + } } diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index a40e1f795..cbda4c875 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -38,10 +38,10 @@ grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, inf->card->driver->recv (inf->card, nb); eth = (struct etherhdr *) nb->data; - type = eth->type; + type = grub_be_to_cpu16 (eth->type); grub_netbuff_pull(nb,sizeof (*eth)); - if (eth->type <=1500) + if (type <= 1500) { llch = (struct llchdr *) nb->data; type = llch->dsap & LLCADDRMASK; @@ -55,14 +55,10 @@ grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, } /* ARP packet */ - if (type == ARP_ETHERTYPE) - { - grub_net_arp_receive(inf, nb); - if (ethertype == ARP_ETHERTYPE) - return GRUB_ERR_NONE; - } + if (type == GRUB_NET_ETHERTYPE_ARP) + grub_net_arp_receive(inf, nb); /* IP packet */ - else if(type == IP_ETHERTYPE && ethertype == IP_ETHERTYPE) + if(type == GRUB_NET_ETHERTYPE_IP && ethertype == GRUB_NET_ETHERTYPE_IP) return GRUB_ERR_NONE; return GRUB_ERR_NONE; diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 023564a5a..9a96ef532 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -54,7 +54,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, if (err) return err; - return send_ethernet_packet (inf, nb, ll_target_addr, IP_ETHERTYPE); + return send_ethernet_packet (inf, nb, ll_target_addr, GRUB_NET_ETHERTYPE_IP); } static int @@ -84,8 +84,11 @@ ip_filter (struct grub_net_buff *nb, grub_err_t grub_net_recv_ip_packets (struct grub_net_network_level_interface *inf) { - struct grub_net_buff nb; - grub_net_recv_ethernet_packet (inf, &nb, IP_ETHERTYPE); - ip_filter (&nb, inf); + struct grub_net_buff *nb; + nb = grub_netbuff_alloc (2048); + if (!nb) + return grub_errno; + grub_net_recv_ethernet_packet (inf, nb, GRUB_NET_ETHERTYPE_IP); + ip_filter (nb, inf); return GRUB_ERR_NONE; } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 5205e1938..54663f4b0 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -92,7 +92,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) *ip = grub_cpu_to_le32 (newip); if (rest) *rest = ptr - 1; - return 0; + return 1; } static int @@ -341,7 +341,7 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected")); FOR_NET_CARDS (card) - if (grub_strcmp (card->name, args[1])) + if (grub_strcmp (card->name, args[1]) == 0) break; if (card == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); @@ -464,7 +464,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), struct grub_net_network_level_interface *inter; FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[2])) + if (grub_strcmp (inter->name, args[2]) == 0) break; if (!inter) diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index b9e3f49c4..16b60eeb6 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -9,60 +9,15 @@ #include #include -struct { - int block_size; - int size; -} tftp_file; -static int block; - - -static char *get_tok_val(char **tok, char **val, char **str_opt,char *end); -static void process_option(char *tok, char *val); - -static char * -get_tok_val(char **tok, char **val,char **str_opt,char *end) -{ - char *p = *str_opt; - *tok = p; - p += grub_strlen(p) + 1; - - if(p > end) - return NULL; - - *val = p; - p += grub_strlen(p) + 1; - *str_opt = p; - return *tok; -} - -static void -process_option(char *tok, char *val) -{ - if (!grub_strcmp(tok,"blksize")) - { - tftp_file.block_size = grub_strtoul (val,NULL,0); - return; - } - - if (!grub_strcmp(tok,"tsize")) - { - tftp_file.size = grub_strtoul (val,NULL,0); - return; - } - -} - -//void tftp_open (char *options); - -/*send read request*/ static grub_err_t tftp_open (struct grub_file *file, const char *filename) { struct tftphdr *tftph; char *rrq; + char *ptr; int rrqlen; int hdrlen; - struct grub_net_buff nb; + struct grub_net_buff *nb; grub_net_network_level_address_t addr; grub_err_t err; @@ -70,29 +25,28 @@ tftp_open (struct grub_file *file, const char *filename) + sizeof ("tftp,") - 1, &addr); if (err) return err; - - grub_memset (&nb, 0, sizeof (nb)); - grub_netbuff_push (&nb,sizeof (*tftph)); - tftph = (struct tftphdr *) nb.data; + nb = grub_netbuff_alloc (2048); + if (!nb) + return grub_errno; + + grub_netbuff_reserve (nb,2048); + grub_netbuff_push (nb,sizeof (*tftph)); + + tftph = (struct tftphdr *) nb->data; rrq = (char *) tftph->u.rrq; rrqlen = 0; - tftph->opcode = TFTP_RRQ; + tftph->opcode = grub_cpu_to_be16 (TFTP_RRQ); grub_strcpy (rrq, filename); rrqlen += grub_strlen (filename) + 1; rrq += grub_strlen (filename) + 1; - /*passar opcoes como parametro ou usar default?*/ grub_strcpy (rrq,"octet"); rrqlen += grub_strlen ("octet") + 1; rrq += grub_strlen ("octet") + 1; - //grub_strcpy (rrq,"netascii"); - //rrqlen += grub_strlen ("netascii") + 1; - //rrq += grub_strlen ("netascii") + 1; - grub_strcpy (rrq,"blksize"); rrqlen += grub_strlen("blksize") + 1; rrq += grub_strlen ("blksize") + 1; @@ -107,29 +61,53 @@ tftp_open (struct grub_file *file, const char *filename) grub_strcpy (rrq,"0"); rrqlen += grub_strlen ("0") + 1; - rrq += grub_strlen ("0") + 1; + rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; - grub_netbuff_unput (&nb,nb.tail - (nb.data+hdrlen)); + grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); - grub_net_send_udp_packet (&addr, - &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + err = grub_net_send_udp_packet (&addr, + nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + if (err) + return err; - grub_net_send_udp_packet (&addr, &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); - /*Receive OACK*/ - grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb,2048); - file->size = tftp_file.size; + /* Receive OACK. */ + grub_netbuff_clear (nb); + grub_netbuff_reserve (nb,2048); - return grub_net_recv_udp_packet (&addr, &nb, - TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + do + { + err = grub_net_recv_udp_packet (&addr, nb, + TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + if (err) + return err; + } + while (nb->tail == nb->data); + + file->size = 0; + + for (ptr = nb->data; ptr < nb->tail; ) + grub_printf ("%02x ", *ptr); + + for (ptr = nb->data; ptr < nb->tail; ) + { + if (grub_memcmp (ptr, "tsize\0=", sizeof ("tsize\0=") - 1) == 0) + { + file->size = grub_strtoul (ptr + sizeof ("tsize\0=") - 1, 0, 0); + grub_errno = GRUB_ERR_NONE; + } + while (ptr < nb->tail && *ptr) + ptr++; + ptr++; + } + return GRUB_ERR_NONE; } static grub_ssize_t tftp_receive (struct grub_file *file, char *buf, grub_size_t len) { struct tftphdr *tftph; - char *token,*value,*temp; + // char *token,*value,*temp; grub_err_t err; grub_net_network_level_address_t addr; struct grub_net_buff nb; @@ -143,38 +121,21 @@ tftp_receive (struct grub_file *file, char *buf, grub_size_t len) TFTP_CLIENT_PORT, TFTP_SERVER_PORT); tftph = (struct tftphdr *) nb.data; - switch (tftph->opcode) + switch (grub_be_to_cpu16 (tftph->opcode)) { - case TFTP_OACK: - /*process oack packet*/ - temp = (char *) tftph->u.oack.data; - while(get_tok_val(&token,&value,&temp,nb.tail)) - { - process_option(token,value); - } - - //buff_clean - grub_netbuff_clear(&nb); - // grub_printf("OACK---------------------------------------------------------\n"); - //grub_printf("block_size=%d\n",tftp_file.block_size); - // grub_printf("file_size=%d\n",tftp_file.size); - // grub_printf("OACK---------------------------------------------------------\n"); - block = 0; - break; case TFTP_DATA: grub_netbuff_pull (&nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block)); - if (tftph->u.data.block == block + 1) - { - block = tftph->u.data.block; + // if (tftph->u.data.block == block + 1) + //{ + // block = tftph->u.data.block; grub_memcpy (buf, nb.data, len); - } - else - grub_netbuff_clear(&nb); - break; + //} + //else + //grub_netbuff_clear(&nb); + break; case TFTP_ERROR: grub_netbuff_clear (&nb); - return grub_error (GRUB_ERR_ACCESS_DENIED, (char *)tftph->u.err.errmsg); - break; + return grub_error (GRUB_ERR_IO, (char *)tftph->u.err.errmsg); } nb.data = nb.tail = nb.end; @@ -182,8 +143,8 @@ tftp_receive (struct grub_file *file, char *buf, grub_size_t len) grub_netbuff_push (&nb,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block)); tftph = (struct tftphdr *) nb.data; - tftph->opcode = TFTP_ACK; - tftph->u.ack.block = block; + tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); + // tftph->u.ack.block = block; return grub_net_send_udp_packet (&addr, &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); } diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 1475086e4..691fda307 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -3,13 +3,11 @@ #include #include -/* IANA ARP constant to define hardware type as ethernet */ -#define ARPHRD_ETHERNET 1 -/* IANA Ethertype */ -#define ARP_ETHERTYPE 0x806 - -/* Size for cache table */ -#define SIZE_ARP_TABLE 5 +enum +{ +/* IANA ARP constant to define hardware type as ethernet. */ + GRUB_NET_ARPHRD_ETHERNET = 1 +}; /* ARP header operation codes */ #define ARP_REQUEST 1 diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index b4f07992b..7a0235be6 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -38,6 +38,14 @@ struct snaphdr grub_uint16_t type; } __attribute__ ((packed)); +/* IANA Ethertype */ +enum +{ + GRUB_NET_ETHERTYPE_IP = 0x0800, + GRUB_NET_ETHERTYPE_ARP = 0x0806 +}; + + grub_err_t send_ethernet_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index 765d8005e..6f748bbf3 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -2,8 +2,6 @@ #define GRUB_NET_IP_HEADER 1 #include -#define IP_ETHERTYPE 0x800 /* IANA Ethertype */ - struct iphdr { grub_uint8_t verhdrlen; grub_uint8_t service; From f5a109e2779b8ea62583301d3cbcbeebbdd5abbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Fri, 24 Sep 2010 01:13:50 +0200 Subject: [PATCH 0269/1414] Variable initialization. --- ChangeLog | 4 ++++ grub-core/commands/acpihalt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cf5cae534..d02901863 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-23 GrĂ©goire Sutre + + * grub-core/commands/acpihalt.c (get_sleep_type): Initialize prev. + 2010-09-23 Vladimir Serbinenko Support xz compression on yeeloong. diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 0cd32f389..a39635677 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -136,7 +136,7 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) static int get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) { - grub_uint8_t *ptr, *prev; + grub_uint8_t *ptr, *prev = table; int sleep_type = -1; ptr = table + sizeof (struct grub_acpi_table_header); From dd363028e45e6505e50208519b5137c750d3bb82 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 24 Sep 2010 08:46:15 +0530 Subject: [PATCH 0270/1414] * Makefile.util.def (example_unit_test): Add grub-core/gnulib/libgnu.a. --- ChangeLog | 5 +++++ Makefile.util.def | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index d02901863..525b4c6e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-24 BVK Chaitanya + + * Makefile.util.def (example_unit_test): Add + grub-core/gnulib/libgnu.a. + 2010-09-23 GrĂ©goire Sutre * grub-core/commands/acpihalt.c (get_sleep_type): Initialize prev. diff --git a/Makefile.util.def b/Makefile.util.def index 21314e04a..42165df3d 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -583,6 +583,7 @@ program = { common = grub-core/tests/lib/test.c; cflags = -Wno-format; ldadd = libgrub.a; + ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER)'; }; From 1d12cf2947a6deb38bb9368470876b37f89ac4d2 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Fri, 24 Sep 2010 09:19:57 +0200 Subject: [PATCH 0271/1414] * grub-core/lib/LzFind.c: Add missing include. * grub-core/lib/LzmaEnc.c: Likewise. * grub-core/script/lexer.c: Likewise. * grub-core/script/yylex.l: Likewise. * util/grub-macho2img.c: Likewise. * util/grub-menulst2cfg.c: Likewise. * util/grub-mklayout.c: Likewise. * util/grub-mkpasswd-pbkdf2.c * util/grub-mkrelpath.c: Likewise. * util/resolve.c: Likewise. --- ChangeLog | 13 +++++++++++++ grub-core/lib/LzFind.c | 3 +++ grub-core/lib/LzmaEnc.c | 2 ++ grub-core/script/lexer.c | 2 ++ grub-core/script/yylex.l | 2 ++ util/grub-macho2img.c | 2 ++ util/grub-menulst2cfg.c | 2 ++ util/grub-mklayout.c | 2 ++ util/grub-mkpasswd-pbkdf2.c | 2 ++ util/grub-mkrelpath.c | 2 ++ util/resolve.c | 2 ++ 11 files changed, 34 insertions(+) diff --git a/ChangeLog b/ChangeLog index 525b4c6e1..b5117bee5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-09-24 Yves Blusseau + + * grub-core/lib/LzFind.c: Add missing include. + * grub-core/lib/LzmaEnc.c: Likewise. + * grub-core/script/lexer.c: Likewise. + * grub-core/script/yylex.l: Likewise. + * util/grub-macho2img.c: Likewise. + * util/grub-menulst2cfg.c: Likewise. + * util/grub-mklayout.c: Likewise. + * util/grub-mkpasswd-pbkdf2.c + * util/grub-mkrelpath.c: Likewise. + * util/resolve.c: Likewise. + 2010-09-24 BVK Chaitanya * Makefile.util.def (example_unit_test): Add diff --git a/grub-core/lib/LzFind.c b/grub-core/lib/LzFind.c index cd7a1cbab..d2bb15c65 100644 --- a/grub-core/lib/LzFind.c +++ b/grub-core/lib/LzFind.c @@ -24,6 +24,9 @@ * See , for more information about LZMA. */ + +#include + #include #include diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c index 842d43ac1..01ffa91f9 100644 --- a/grub-core/lib/LzmaEnc.c +++ b/grub-core/lib/LzmaEnc.c @@ -24,6 +24,8 @@ * See , for more information about LZMA. */ +#include + #include #include diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c index 8d1623fb8..909b515fa 100644 --- a/grub-core/script/lexer.c +++ b/grub-core/script/lexer.c @@ -17,6 +17,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 55620b6bd..53ae4c54f 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -71,6 +71,8 @@ static void copy_string (struct grub_parser_param *, const char *, %top{ +#include + #include typedef size_t yy_size_t; diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c index 23ffafb04..bce0a06d1 100644 --- a/util/grub-macho2img.c +++ b/util/grub-macho2img.c @@ -17,6 +17,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 512239e89..e29c6b17c 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index ac59981c7..e90d955ff 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index d552d1acd..fe1887f8f 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index eccb49cdc..3fe3fe698 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -17,6 +17,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include diff --git a/util/resolve.c b/util/resolve.c index 7eadffd38..63bd7ccb2 100644 --- a/util/resolve.c +++ b/util/resolve.c @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#include + #include #include #include From e1fd193905e0ef3afc1a98893940e44fd81a37d3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 24 Sep 2010 09:48:27 +0100 Subject: [PATCH 0272/1414] Re-enable grub-extras. * autogen.sh: Create symlinks to ${GRUB_CONTRIB} if necessary to avoid confusing Automake. Run autogen only twice, once for the top level and once for grub-core. Add Makefile.util.def and Makefile.core.def from extra modules to the appropriate autogen invocations. If Makefile.common exists in an extra module, include it in both Makefile.util.am and grub-core/Makefile.core.am; similarly, include any Makefile.util.common file in Makefile.util.am and any Makefile.core.common file in grub-core/Makefile.core.am. * conf/Makefile.common ($(top_srcdir)/grub-core/Makefile.core.am): Depend on $(top_srcdir)/grub-core/Makefile.gcry.def. ($(top_srcdir)/grub-core/Makefile.gcry.def): Remove. * grub-core/Makefile.am: Remove inclusion of Makefile.gcry.am. * gentpl.py (gvar_add): Turn GVARS into a set. (global_variable_initializers): Sort global variables on output. (vars_init): New function. (first_time): Likewise. (library): Ensure that non-global variable initialisations are emitted before the first time we emit code for a library block. Append to variables rather than setting them. Only emit noinst_LIBRARIES, BUILT_SOURCES, and CLEANFILES the first time for each conditional path. (program): installdir() emits an Autogen macro, so must be passed to var_add rather than gvar_add. (data): Likewise. (script): Likewise. (rules): New function, centralising handling for different target types. Set up Guile association lists for first_time and vars_init, and send most output to a diversion so that variable initialisations can be emitted first. (module_rules): Use new rules function. (kernel_rules): Likewise. (image_rules): Likewise. (library_rules): Likewise. (program_rules): Likewise. (script_rules): Likewise. (data_rules): Likewise. * configure.ac: Add AC_PROG_LN_S, for the benefit of ntldr-img. * .bzrignore: Add contrib and grub-core/contrib. Remove grub-core/Makefile.gcry.am. --- .bzrignore | 3 +- ChangeLog | 47 +++++++++++++++++++++ autogen.sh | 47 +++++++++++++++++++-- conf/Makefile.common | 10 ++--- configure.ac | 1 + gentpl.py | 97 +++++++++++++++++++++++++++++-------------- grub-core/Makefile.am | 1 - 7 files changed, 163 insertions(+), 43 deletions(-) diff --git a/.bzrignore b/.bzrignore index 06dd94341..7c5597bce 100644 --- a/.bzrignore +++ b/.bzrignore @@ -104,9 +104,10 @@ grub-core/lib/libgcrypt-grub **/.deps-core **/.dirstamp Makefile.util.am +contrib grub-core/Makefile.core.am -grub-core/Makefile.gcry.am grub-core/Makefile.gcry.def +grub-core/contrib grub-core/genmod.sh grub-core/gensyminfo.sh grub-core/*.module diff --git a/ChangeLog b/ChangeLog index b5117bee5..95a0ae2fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +2010-09-24 Colin Watson + + Re-enable grub-extras. + + * autogen.sh: Create symlinks to ${GRUB_CONTRIB} if necessary to + avoid confusing Automake. Run autogen only twice, once for the top + level and once for grub-core. Add Makefile.util.def and + Makefile.core.def from extra modules to the appropriate autogen + invocations. If Makefile.common exists in an extra module, include + it in both Makefile.util.am and grub-core/Makefile.core.am; + similarly, include any Makefile.util.common file in Makefile.util.am + and any Makefile.core.common file in grub-core/Makefile.core.am. + * conf/Makefile.common ($(top_srcdir)/grub-core/Makefile.core.am): + Depend on $(top_srcdir)/grub-core/Makefile.gcry.def. + ($(top_srcdir)/grub-core/Makefile.gcry.def): Remove. + * grub-core/Makefile.am: Remove inclusion of Makefile.gcry.am. + + * gentpl.py (gvar_add): Turn GVARS into a set. + (global_variable_initializers): Sort global variables on output. + (vars_init): New function. + (first_time): Likewise. + (library): Ensure that non-global variable initialisations are + emitted before the first time we emit code for a library block. + Append to variables rather than setting them. Only emit + noinst_LIBRARIES, BUILT_SOURCES, and CLEANFILES the first time for + each conditional path. + (program): installdir() emits an Autogen macro, so must be passed to + var_add rather than gvar_add. + (data): Likewise. + (script): Likewise. + (rules): New function, centralising handling for different target + types. Set up Guile association lists for first_time and vars_init, + and send most output to a diversion so that variable initialisations + can be emitted first. + (module_rules): Use new rules function. + (kernel_rules): Likewise. + (image_rules): Likewise. + (library_rules): Likewise. + (program_rules): Likewise. + (script_rules): Likewise. + (data_rules): Likewise. + + * configure.ac: Add AC_PROG_LN_S, for the benefit of ntldr-img. + + * .bzrignore: Add contrib and grub-core/contrib. Remove + grub-core/Makefile.gcry.am. + 2010-09-24 Yves Blusseau * grub-core/lib/LzFind.c: Add missing include. diff --git a/autogen.sh b/autogen.sh index f052499ae..96b1e33e2 100755 --- a/autogen.sh +++ b/autogen.sh @@ -14,9 +14,50 @@ echo "Creating Makefile.tpl..." python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl echo "Running autogen..." -autogen -T Makefile.tpl Makefile.util.def | sed -e '/^$/{N;/^\n$/D;}' > Makefile.util.am -autogen -T Makefile.tpl grub-core/Makefile.core.def | sed -e '/^$/{N;/^\n$/D;}' > grub-core/Makefile.core.am -autogen -T Makefile.tpl grub-core/Makefile.gcry.def | sed -e '/^$/{N;/^\n$/D;}' > grub-core/Makefile.gcry.am + +# Automake doesn't like including files from a path outside the project. +rm -f contrib grub-core/contrib +if [ "x${GRUB_CONTRIB}" != x ]; then + [ "${GRUB_CONTRIB}" = contrib ] || ln -s "${GRUB_CONTRIB}" contrib + [ "${GRUB_CONTRIB}" = grub-core/contrib ] || ln -s ../contrib grub-core/contrib +fi + +UTIL_DEFS=Makefile.util.def +CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def' + +for extra in contrib/*/Makefile.util.def; do + if test -e "$extra"; then + UTIL_DEFS="$UTIL_DEFS $extra" + fi +done + +for extra in contrib/*/Makefile.core.def; do + if test -e "$extra"; then + CORE_DEFS="$CORE_DEFS $extra" + fi +done + +cat $UTIL_DEFS | autogen -T Makefile.tpl | sed -e '/^$/{N;/^\n$/D;}' > Makefile.util.am +cat $CORE_DEFS | autogen -T Makefile.tpl | sed -e '/^$/{N;/^\n$/D;}' > grub-core/Makefile.core.am + +for extra in contrib/*/Makefile.common; do + if test -e "$extra"; then + echo "include $extra" >> Makefile.util.am + echo "include $extra" >> grub-core/Makefile.core.am + fi +done + +for extra in contrib/*/Makefile.util.common; do + if test -e "$extra"; then + echo "include $extra" >> Makefile.util.am + fi +done + +for extra in contrib/*/Makefile.core.common; do + if test -e "$extra"; then + echo "include $extra" >> grub-core/Makefile.core.am + fi +done echo "Saving timestamps..." echo timestamp > stamp-h.in diff --git a/conf/Makefile.common b/conf/Makefile.common index ea16ab159..81bb3567e 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -146,11 +146,7 @@ $(top_srcdir)/Makefile.util.am: $(top_srcdir)/Makefile.util.def $(top_srcdir)/Ma mv $@.new $@ .PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am -$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/Makefile.tpl - autogen -T $(top_srcdir)/Makefile.tpl $< | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) - mv $@.new $@ - -.PRECIOUS: $(top_srcdir)/grub-core/Makefile.gcry.am -$(top_srcdir)/grub-core/Makefile.gcry.am: $(top_srcdir)/grub-core/Makefile.gcry.def $(top_srcdir)/Makefile.tpl - autogen -T $(top_srcdir)/Makefile.tpl $< | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) +$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def $(top_srcdir)/Makefile.tpl + if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./autogen.sh manually." >&2; exit 1; fi + autogen -T $(top_srcdir)/Makefile.tpl $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) mv $@.new $@ diff --git a/configure.ac b/configure.ac index fc0579cad..66d4a6877 100644 --- a/configure.ac +++ b/configure.ac @@ -235,6 +235,7 @@ AC_PROG_LEX AC_PROG_YACC AC_PROG_MAKE_SET AC_PROG_MKDIR_P +AC_PROG_LN_S if test "x$LEX" = "x:"; then AC_MSG_ERROR([flex is not found]) diff --git a/gentpl.py b/gentpl.py index 3fe995dc0..109ce7981 100644 --- a/gentpl.py +++ b/gentpl.py @@ -70,16 +70,15 @@ for platform in GRUB_PLATFORMS: # # Global variables # -GVARS = [] +GVARS = set() def gvar_add(var, value): - if var not in GVARS: - GVARS.append(var) + GVARS.add(var) return var + " += " + value + "\n" def global_variable_initializers(): r = "" - for var in GVARS: + for var in sorted(GVARS): r += var + " ?= \n" return r @@ -87,6 +86,16 @@ def global_variable_initializers(): # Per PROGRAM/SCRIPT variables # +def vars_init(*var_list): + r = "[+ IF (if (not (assoc-ref seen-vars (get \".name\"))) \"seen\") +]" + r += "[+ (out-suspend \"v\") +]" + for var in var_list: + r += var + " = \n" + r += "[+ (out-resume \"v\") +]" + r += "[+ (set! seen-vars (assoc-set! seen-vars (get \".name\") 0)) +]" + r += "[+ ENDIF +]" + return first_time(r) + def var_set(var, value): return var + " = " + value + "\n" @@ -257,6 +266,15 @@ def platform_ccasflags(p): return platform_specific_values(p, "_ccasflags", "cca def platform_stripflags(p): return platform_specific_values(p, "_stripflags", "stripflags") def platform_objcopyflags(p): return platform_specific_values(p, "_objcopyflags", "objcopyflags") +# +# Emit snippet only the first time through for the current name. +# +def first_time(snippet): + r = "[+ IF (if (not (assoc-ref seen-target (get \".name\"))) \"seen\") +]" + r += snippet + r += "[+ ENDIF +]" + return r + def module(platform): r = set_canonical_name_suffix(".module") @@ -341,18 +359,25 @@ fi def library(platform): r = set_canonical_name_suffix("") - r += gvar_add("noinst_LIBRARIES", "[+ name +]") - r += var_set(cname() + "_SOURCES", platform_sources(platform)) - r += var_set("nodist_" + cname() + "_SOURCES", platform_nodist_sources(platform)) - r += var_set(cname() + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_LIBRARY) " + platform_cflags(platform)) - r += var_set(cname() + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) " + platform_cppflags(platform)) - r += var_set(cname() + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) " + platform_ccasflags(platform)) - # r += var_set(cname() + "_DEPENDENCIES", platform_dependencies(platform) + " " + platform_ldadd(platform)) + + r += vars_init(cname() + "_SOURCES", + "nodist_" + cname() + "_SOURCES", + cname() + "_CFLAGS", + cname() + "_CPPFLAGS", + cname() + "_CCASFLAGS") + # cname() + "_DEPENDENCIES") + + r += first_time(gvar_add("noinst_LIBRARIES", "[+ name +]")) + r += var_add(cname() + "_SOURCES", platform_sources(platform)) + r += var_add("nodist_" + cname() + "_SOURCES", platform_nodist_sources(platform)) + r += var_add(cname() + "_CFLAGS", first_time("$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(platform)) + r += var_add(cname() + "_CPPFLAGS", first_time("$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(platform)) + r += var_add(cname() + "_CCASFLAGS", first_time("$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(platform)) + # r += var_add(cname() + "_DEPENDENCIES", platform_dependencies(platform) + " " + platform_ldadd(platform)) r += gvar_add("EXTRA_DIST", extra_dist()) - r += gvar_add("BUILT_SOURCES", "$(nodist_" + cname() + "_SOURCES)") - r += gvar_add("CLEANFILES", "$(nodist_" + cname() + "_SOURCES)") - + r += first_time(gvar_add("BUILT_SOURCES", "$(nodist_" + cname() + "_SOURCES)")) + r += first_time(gvar_add("CLEANFILES", "$(nodist_" + cname() + "_SOURCES)")) return r def installdir(default="bin"): @@ -376,7 +401,7 @@ def program(platform, test=False): r += gvar_add("check_PROGRAMS", "[+ name +]") r += gvar_add("TESTS", "[+ name +]") r += "[+ ELSE +]" - r += gvar_add(installdir() + "_PROGRAMS", "[+ name +]") + r += var_add(installdir() + "_PROGRAMS", "[+ name +]") r += "[+ IF mansection +]" + manpage() + "[+ ENDIF +]" r += "[+ ENDIF +]" @@ -397,7 +422,7 @@ def program(platform, test=False): def data(platform): r = gvar_add("EXTRA_DIST", platform_sources(platform)) r += gvar_add("EXTRA_DIST", extra_dist()) - r += gvar_add(installdir() + "_DATA", platform_sources(platform)) + r += var_add(installdir() + "_DATA", platform_sources(platform)) return r def script(platform): @@ -405,7 +430,7 @@ def script(platform): r += gvar_add("check_SCRIPTS", "[+ name +]") r += gvar_add ("TESTS", "[+ name +]") r += "[+ ELSE +]" - r += gvar_add(installdir() + "_SCRIPTS", "[+ name +]") + r += var_add(installdir() + "_SCRIPTS", "[+ name +]") r += "[+ IF mansection +]" + manpage() + "[+ ENDIF +]" r += "[+ ENDIF +]" @@ -418,33 +443,43 @@ chmod a+x [+ name +] r += gvar_add("dist_noinst_DATA", platform_sources(platform)) return r +def rules(target, closure): + # Create association lists for the benefit of first_time and vars_init. + r = "[+ (define seen-target '()) +]" + r += "[+ (define seen-vars '()) +]" + # Most output goes to a diversion. This allows us to emit variable + # initializations before everything else. + r += "[+ (out-push-new) +]" + + r += "[+ FOR " + target + " +]" + r += foreach_enabled_platform( + lambda p: under_platform_specific_conditionals(p, closure(p))) + # Remember that we've seen this target. + r += "[+ (set! seen-target (assoc-set! seen-target (get \".name\") 0)) +]" + r += "[+ ENDFOR +]" + r += "[+ (out-pop #t) +]" + return r + def module_rules(): - return "[+ FOR module +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, module(p))) + "[+ ENDFOR +]" + return rules("module", module) def kernel_rules(): - return "[+ FOR kernel +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, kernel(p))) + "[+ ENDFOR +]" + return rules("kernel", kernel) def image_rules(): - return "[+ FOR image +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, image(p))) + "[+ ENDFOR +]" + return rules("image", image) def library_rules(): - return "[+ FOR library +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, library(p))) + "[+ ENDFOR +]" + return rules("library", library) def program_rules(): - return "[+ FOR program +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, program(p))) + "[+ ENDFOR +]" + return rules("program", program) def script_rules(): - return "[+ FOR script +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, script(p))) + "[+ ENDFOR +]" + return rules("script", script) def data_rules(): - return "[+ FOR data +]" + foreach_enabled_platform( - lambda p: under_platform_specific_conditionals(p, data(p))) + "[+ ENDFOR +]" + return rules("data", data) print "[+ AutoGen5 template +]\n" a = module_rules() diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index addc83417..cff6b3782 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -51,7 +51,6 @@ grub_script.yy.c: grub_script.yy.h CLEANFILES += grub_script.yy.c grub_script.yy.h include $(srcdir)/Makefile.core.am -include $(srcdir)/Makefile.gcry.am KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h From 4f0de6881cef5f8396333ab6c12c6e571b0f8d26 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Sep 2010 14:05:47 +0200 Subject: [PATCH 0273/1414] C part of Reed-Solomon --- Makefile.util.def | 1 + grub-core/kern/i386/pc/startup.S | 2 + grub-core/partmap/gpt.c | 14 +- grub-core/partmap/msdos.c | 16 +- include/grub/offsets.h | 9 +- include/grub/partition.h | 5 +- include/grub/reed_solomon.h | 30 ++ util/grub-setup.c | 34 ++- util/reed_solomon.c | 465 +++++++++++++++++++++++++++++++ 9 files changed, 553 insertions(+), 23 deletions(-) create mode 100644 include/grub/reed_solomon.h create mode 100644 util/reed_solomon.c diff --git a/Makefile.util.def b/Makefile.util.def index 21314e04a..5d091f7f5 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -244,6 +244,7 @@ program = { common = util/grub-setup.c; common = util/raid.c; common = util/lvm.c; + common = util/reed_solomon.c; sparc64_ieee1275 = util/ieee1275/ofpath.c; diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 46e6b1fac..01825396c 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -100,6 +100,8 @@ VARIABLE(grub_install_dos_part) .long 0xFFFFFFFF VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF +reed_solomon_redundancy: + .long 0 #ifdef APPLE_CC bss_start: diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index c9393d932..7f2c36143 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -124,9 +124,9 @@ gpt_partition_map_iterate (grub_disk_t disk, #ifdef GRUB_UTIL static grub_err_t -gpt_partition_map_embed (struct grub_disk *disk, unsigned int nsectors, +gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, grub_embed_type_t embed_type, - grub_disk_addr_t *sectors) + grub_disk_addr_t **sectors) { grub_disk_addr_t start = 0, len = 0; unsigned i; @@ -168,13 +168,17 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int nsectors, "This GPT partition label has no BIOS Boot Partition;" " embedding won't be possible!"); - if (len < nsectors) + if (len < *nsectors) return grub_error (GRUB_ERR_OUT_OF_RANGE, "Your BIOS Boot Partition is too small;" " embedding won't be possible!"); - for (i = 0; i < nsectors; i++) - sectors[i] = start + i; + *nsectors = len; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = start + i; return GRUB_ERR_NONE; } diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 921e2554e..f99e27a6e 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -145,9 +145,9 @@ grub_partition_msdos_iterate (grub_disk_t disk, #ifdef GRUB_UTIL static grub_err_t -pc_partition_map_embed (struct grub_disk *disk, unsigned int nsectors, +pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, grub_embed_type_t embed_type, - grub_disk_addr_t *sectors) + grub_disk_addr_t **sectors) { grub_disk_addr_t end = ~0ULL; struct grub_msdos_partition_mbr mbr; @@ -232,11 +232,15 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int nsectors, break; } - if (end >= nsectors + 1) + if (end >= *nsectors + 1) { int i; - for (i = 0; i < nsectors; i++) - sectors[i] = 1 + i; + *nsectors = end - 1; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = 1 + i; return GRUB_ERR_NONE; } @@ -245,7 +249,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int nsectors, "This msdos-style partition label has no " "post-MBR gap; embedding won't be possible!"); - if (nsectors > 62) + if (*nsectors > 62) return grub_error (GRUB_ERR_OUT_OF_RANGE, "Your core.img is unusually large. " "It won't fit in the embedding area."); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 359b32244..d1cf8720f 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -34,11 +34,16 @@ /* The offset of GRUB_INSTALL_BSD_PART. */ #define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 +/* Offset of reed_solomon_redundancy. */ +#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x1c + /* The offset of multiboot signature. */ -#define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x1c +#define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x20 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0x5D8 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0x5E0 + +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x300 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE diff --git a/include/grub/partition.h b/include/grub/partition.h index 7ccb7cffd..e7e00ef7f 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -48,8 +48,9 @@ struct grub_partition_map const grub_partition_t partition)); #ifdef GRUB_UTIL /* Determine sectors available for embedding. */ - grub_err_t (*embed) (struct grub_disk *disk, unsigned int nsectors, - grub_embed_type_t embed_type, grub_disk_addr_t *sectors); + grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors); #endif }; typedef struct grub_partition_map *grub_partition_map_t; diff --git a/include/grub/reed_solomon.h b/include/grub/reed_solomon.h new file mode 100644 index 000000000..596dff246 --- /dev/null +++ b/include/grub/reed_solomon.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_REED_SOLOMON_HEADER +#define GRUB_REED_SOLOMON_HEADER 1 + +void +grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, + grub_size_t redundancy); + +void +grub_reed_solomon_recover (void *buffer, grub_size_t data_size, + grub_size_t redundancy); + +#endif diff --git a/util/grub-setup.c b/util/grub-setup.c index 0c5470830..1518bb0a8 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -48,6 +48,7 @@ #include #include #include "progname.h" +#include #define _GNU_SOURCE 1 #include @@ -336,9 +337,10 @@ setup (const char *dir, grub_partition_t container = dest_dev->disk->partition; int multiple_partmaps = 0; grub_err_t err; - grub_disk_addr_t sectors[core_sectors]; + grub_disk_addr_t *sectors; int i; grub_fs_t fs; + unsigned int nsec; /* Unlike root_dev, with dest_dev we're interested in the partition map even if dest_dev itself is a whole disk. */ @@ -419,8 +421,11 @@ setup (const char *dir, goto unable_to_embed; } - err = dest_partmap->embed (dest_dev->disk, core_sectors, - GRUB_EMBED_PCBIOS, sectors); + nsec = core_sectors; + err = dest_partmap->embed (dest_dev->disk, &nsec, + GRUB_EMBED_PCBIOS, §ors); + if (nsec > 2 * core_sectors) + nsec = 2 * core_sectors; if (err) { @@ -439,6 +444,20 @@ setup (const char *dir, write_rootdev (core_img, root_dev, boot_img, first_sector); + core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); + first_block = (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + + *(grub_uint32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY) + = grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size); + + grub_reed_solomon_add_redundancy (core_img + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + GRUB_DISK_SECTOR_SIZE, + core_size - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - GRUB_DISK_SECTOR_SIZE, + nsec * GRUB_DISK_SECTOR_SIZE + - core_size); + /* Make sure that the second blocklist is a terminator. */ block = first_block - 1; block->start = 0; @@ -446,14 +465,13 @@ setup (const char *dir, block->segment = 0; /* Write the core image onto the disk. */ - for (i = 0; i < core_sectors; i++) + for (i = 0; i < nsec; i++) grub_disk_write (dest_dev->disk, sectors[i], 0, - (core_size - i * GRUB_DISK_SECTOR_SIZE - < GRUB_DISK_SECTOR_SIZE) ? core_size - - i * GRUB_DISK_SECTOR_SIZE - : GRUB_DISK_SECTOR_SIZE, + GRUB_DISK_SECTOR_SIZE, core_img + i * GRUB_DISK_SECTOR_SIZE); + grub_free (sectors); + goto finish; } #endif diff --git a/util/reed_solomon.c b/util/reed_solomon.c new file mode 100644 index 000000000..c20d023e7 --- /dev/null +++ b/util/reed_solomon.c @@ -0,0 +1,465 @@ +/* + * 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 . + */ + +#ifdef TEST +#include +#include +#include +typedef unsigned int grub_size_t; +typedef unsigned char grub_uint8_t; +typedef unsigned short grub_uint16_t; +#define xmalloc malloc +#define grub_memset memset +#define grub_memcpy memcpy +#else +#include +#include +#include +#include +#endif + +#define GF_SIZE 8 +typedef grub_uint8_t gf_single_t; +typedef grub_uint16_t gf_double_t; +const gf_single_t gf_polynomial = 0x1d; + +#define SECTOR_SIZE 512 +#define MAX_BLOCK_SIZE (200 * SECTOR_SIZE) + +static gf_single_t +gf_reduce (gf_double_t a) +{ + int i; + for (i = GF_SIZE - 1; i >= 0; i--) + if (a & (1ULL << (i + GF_SIZE))) + a ^= (((gf_double_t) gf_polynomial) << i); + return a & ((1ULL << GF_SIZE) - 1); +} + +static gf_single_t +gf_mul (gf_single_t a, gf_single_t b) +{ + gf_double_t res = 0; + int i; + for (i = 0; i < GF_SIZE; i++) + if (b & (1 << i)) + res ^= ((gf_double_t) a) << i; + return gf_reduce (res); +} + +static int +bin_log2 (gf_double_t a) +{ + int i = 0; + while (a) + { + a >>= 1; + i++; + } + return i - 1; +} + +static gf_single_t +gf_invert (gf_single_t a) +{ + /* We start with: */ + /* 1 * a + 0 * p = a */ + /* 0 * a + 1 * p = p */ + gf_double_t x1 = 1, y1 = 0, z1 = a, x2 = 0, y2 = 1; + gf_double_t z2 = gf_polynomial | (1ULL << GF_SIZE), t; + /* invariant: z1 < z2*/ + while (z1 != 0) + { + int k; + k = bin_log2 (z2) - bin_log2 (z1); + x2 ^= (x1 << k); + y2 ^= (y1 << k); + z2 ^= (z1 << k); + + if (z1 >= z2) + { + t = x2; + x2 = x1; + x1 = t; + t = y2; + y2 = y1; + y1 = t; + t = z2; + z2 = z1; + z1 = t; + } + } + + return gf_reduce (x2); +} + +static gf_single_t +pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) +{ + int i; + gf_single_t xn = 1, s = 0; + for (i = degree; i >= 0; i--) + { + s ^= gf_mul (pol[i], xn); + xn = gf_mul (x, xn); + } + return s; +} + +static void +rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) +{ + gf_single_t *rs_polynomial, a = 1; + int i, j; + gf_single_t *m; + m = xmalloc ((s + rs) * sizeof (gf_single_t)); + grub_memcpy (m, data, s * sizeof (gf_single_t)); + grub_memset (m + s, 0, rs * sizeof (gf_single_t)); + rs_polynomial = xmalloc ((rs + 1) * sizeof (gf_single_t)); + grub_memset (rs_polynomial, 0, (rs + 1) * sizeof (gf_single_t)); + rs_polynomial[rs] = 1; + /* Multiply with X - a^r */ + for (j = 0; j < rs; j++) + { + if (a & (1 << (GF_SIZE - 1))) + { + a <<= 1; + a ^= gf_polynomial; + } + else + a <<= 1; + for (i = 0; i < rs; i++) + rs_polynomial[i] = rs_polynomial[i + 1] ^ gf_mul (a, rs_polynomial[i]); + rs_polynomial[rs] = gf_mul (a, rs_polynomial[rs]); + } + for (j = 0; j < s; j++) + if (m[j]) + { + gf_single_t f = m[j]; + for (i = 0; i <= rs; i++) + m[i+j] ^= gf_mul (rs_polynomial[i], f); + } + free (rs_polynomial); + grub_memcpy (data + s, m + s, rs * sizeof (gf_single_t)); + free (m); + +} + +static void +syndroms (gf_single_t *m, grub_size_t s, grub_size_t rs, + gf_single_t *sy) +{ + gf_single_t xn = 1; + int i; + for (i = 0; i < rs; i++) + { + if (xn & (1 << (GF_SIZE - 1))) + { + xn <<= 1; + xn ^= gf_polynomial; + } + else + xn <<= 1; + sy[i] = pol_evaluate (m, s + rs - 1, xn); + } +} + +static void +rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) +{ + grub_size_t rs2 = rs / 2; + gf_single_t *sigma; + gf_single_t *errpot; + int *errpos; + gf_single_t *sy; + int errnum = 0; + int i, j; + + sigma = xmalloc (rs2 * sizeof (gf_single_t)); + errpot = xmalloc (rs2 * sizeof (gf_single_t)); + errpos = xmalloc (rs2 * sizeof (int)); + sy = xmalloc (rs * sizeof (gf_single_t)); + + syndroms (m, s, rs, sy); + + { + gf_single_t *eq; + int *chosen; + + eq = xmalloc (rs2 * (rs2 + 1) * sizeof (gf_single_t)); + chosen = xmalloc (rs2 * sizeof (int)); + + for (i = 0; i < rs; i++) + if (sy[i] != 0) + break; + + /* No error detected. */ + if (i == rs) + return; + + for (i = 0; i < rs2; i++) + for (j = 0; j < rs2 + 1; j++) + eq[i * (rs2 + 1) + j] = sy[i+j]; + + grub_memset (sigma, 0, rs2 * sizeof (gf_single_t)); + grub_memset (chosen, -1, rs2 * sizeof (int)); + + for (i = 0 ; i < rs2; i++) + { + int nzidx; + int k; + gf_single_t r; + for (nzidx = 0; nzidx < rs2 && (eq[i * (rs2 + 1) + nzidx] == 0); + nzidx++); + if (nzidx == rs2) + { + break; + } + chosen[i] = nzidx; + r = gf_invert (eq[i * (rs2 + 1) + nzidx]); + for (j = 0; j < rs2 + 1; j++) + eq[i * (rs2 + 1) + j] = gf_mul (eq[i * (rs2 + 1) + j], r); + for (j = i + 1; j < rs2; j++) + { + gf_single_t rr = eq[j * (rs2 + 1) + nzidx]; + for (k = 0; k < rs2 + 1; k++) + eq[j * (rs2 + 1) + k] ^= gf_mul (eq[i * (rs2 + 1) + k], rr);; + } + } + for (i = rs2 - 1; i >= 0; i--) + { + gf_single_t s = 0; + if (chosen[i] == -1) + continue; + for (j = 0; j < rs2; j++) + s ^= gf_mul (eq[i * (rs2 + 1) + j], sigma[j]); + s ^= eq[i * (rs2 + 1) + rs2]; + sigma[chosen[i]] = s; + } + + free (chosen); + free (eq); + } + + { + gf_single_t xn = 1, xx = gf_invert (2), yn = 1; + int lp = 0; + for (i = 0; i < rs + s; i++) + { + gf_single_t ev = (gf_mul (pol_evaluate (sigma, rs2 - 1, xn), xn) ^ 1); + if (ev == 0) + { + errpot[errnum] = yn; + errpos[errnum++] = s + rs - i - 1; + } + yn = gf_mul (yn, 2); + xn = gf_mul (xn, xx); + } + } + { + gf_single_t *eq; + int *chosen; + gf_single_t *errvals; + + eq = xmalloc (rs * (errnum + 1) * sizeof (gf_single_t)); + chosen = xmalloc (rs * sizeof (int)); + errvals = xmalloc (errnum * sizeof (int)); + + grub_memset (chosen, -1, rs * sizeof (int)); + grub_memset (errvals, 0, errnum * sizeof (gf_single_t)); + + for (j = 0; j < errnum; j++) + eq[j] = errpot[j]; + eq[errnum] = sy[0]; + for (i = 1; i < rs; i++) + { + for (j = 0; j < errnum; j++) + eq[(errnum + 1) * i + j] = gf_mul (errpot[j], + eq[(errnum + 1) * (i - 1) + j]); + eq[(errnum + 1) * i + errnum] = sy[i]; + } + for (i = 0 ; i < rs; i++) + { + int nzidx; + int k; + gf_single_t r; + for (nzidx = 0; nzidx < errnum && (eq[i * (errnum + 1) + nzidx] == 0); + nzidx++); + if (nzidx == errnum) + continue; + chosen[i] = nzidx; + r = gf_invert (eq[i * (errnum + 1) + nzidx]); + for (j = 0; j < errnum + 1; j++) + eq[i * (errnum + 1) + j] = gf_mul (eq[i * (errnum + 1) + j], r); + for (j = i + 1; j < rs; j++) + { + gf_single_t rr = eq[j * (errnum + 1) + nzidx]; + for (k = 0; k < errnum + 1; k++) + eq[j * (errnum + 1) + k] ^= gf_mul (eq[i * (errnum + 1) + k], rr); + } + } + for (i = rs - 1; i >= 0; i--) + { + gf_single_t s = 0; + if (chosen[i] == -1) + continue; + for (j = 0; j < errnum; j++) + s ^= gf_mul (eq[i * (errnum + 1) + j], errvals[j]); + s ^= eq[i * (errnum + 1) + errnum]; + errvals[chosen[i]] = s; + } + for (i = 0; i < errnum; i++) + m[errpos[i]] ^= errvals[i]; + } + free (sy); +} + +static void +decode_block (gf_single_t *ptr, grub_size_t s, + gf_single_t *rptr, grub_size_t rs) +{ + grub_size_t ss; + int i, j, k; + for (i = 0; i < SECTOR_SIZE; i++) + { + grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; + grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; + gf_single_t m[ds + rr]; + + for (j = 0; j < ds; j++) + m[j] = ptr[SECTOR_SIZE * j + i]; + for (j = 0; j < rr; j++) + m[j + ds] = rptr[SECTOR_SIZE * j + i]; + + rs_recover (m, ds, rr); + + for (j = 0; j < ds; j++) + ptr[SECTOR_SIZE * j + i] = m[j]; + } +} + +static void +encode_block (gf_single_t *ptr, grub_size_t s, + gf_single_t *rptr, grub_size_t rs) +{ + grub_size_t ss; + int i, j; + for (i = 0; i < SECTOR_SIZE; i++) + { + grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; + grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; + gf_single_t m[ds + rr]; + for (j = 0; j < ds; j++) + m[j] = ptr[SECTOR_SIZE * j + i]; + rs_encode (m, ds, rr); + for (j = 0; j < rr; j++) + rptr[SECTOR_SIZE * j + i] = m[j + ds]; + } +} + +void +grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, + grub_size_t redundancy) +{ + grub_size_t s = data_size; + grub_size_t rs = redundancy; + gf_single_t *ptr = buffer; + gf_single_t *rptr = ptr + s; + + while (s > 0) + { + grub_size_t tt; + grub_size_t cs, crs; + cs = s; + crs = rs; + tt = cs + crs; + if (tt > MAX_BLOCK_SIZE) + { + cs = (cs * MAX_BLOCK_SIZE) / tt; + crs = (crs * MAX_BLOCK_SIZE) / tt; + } + encode_block (ptr, cs, rptr, crs); + ptr += cs; + rptr += crs; + s -= cs; + rs -= crs; + } +} + +void +grub_reed_solomon_recover (void *ptr, grub_size_t s, grub_size_t rs) +{ + gf_single_t *rptr = ptr + s; + while (s > 0) + { + grub_size_t tt; + grub_size_t cs, crs; + cs = s; + crs = rs; + tt = cs + crs; + if (tt > MAX_BLOCK_SIZE) + { + cs = cs * MAX_BLOCK_SIZE / tt; + crs = crs * MAX_BLOCK_SIZE / tt; + } + decode_block (ptr, cs, rptr, crs); + ptr += cs; + rptr += crs; + s -= cs; + rs -= crs; + } +} + +#ifdef TEST +int +main (int argc, char **argv) +{ + FILE *in, *out; + grub_size_t s, rs; + char *buf; + in = fopen ("tst.bin", "rb"); + if (!in) + return 1; + fseek (in, 0, SEEK_END); + s = ftell (in); + fseek (in, 0, SEEK_SET); + rs = 1024 * ((s + MAX_BLOCK_SIZE - 1) / (MAX_BLOCK_SIZE - 1024)); + buf = xmalloc (s + rs + SECTOR_SIZE); + fread (buf, 1, s, in); + + grub_reed_solomon_add_redundancy (buf, s, rs); + + out = fopen ("tst_rs.bin", "wb"); + fwrite (buf, 1, s + rs, out); + fclose (out); + + grub_memset (buf + 512 * 15, 0, 512); + + out = fopen ("tst_dam.bin", "wb"); + fwrite (buf, 1, s + rs, out); + fclose (out); + + grub_reed_solomon_recover (buf, s, rs); + + out = fopen ("tst_rec.bin", "wb"); + fwrite (buf, 1, s, out); + fclose (out); + + return 0; +} +#endif From 449333eb7df96f6db3baa6965ede4c59cf8fa261 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 25 Sep 2010 10:43:09 +0530 Subject: [PATCH 0274/1414] Fix grub-emu build. * grub-core/kern/emu/main.c: Remove #include . * grub-core/kern/emu/full.c: Split grub_mdraid_{init,fini} into mdraid09 and mdraid1x. --- ChangeLog | 8 ++++++++ grub-core/kern/emu/full.c | 6 ++++-- grub-core/kern/emu/main.c | 1 - 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95a0ae2fb..c2aa58c02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-09-25 BVK Chaitanya + + Fix grub-emu build. + + * grub-core/kern/emu/main.c: Remove #include . + * grub-core/kern/emu/full.c: Split grub_mdraid_{init,fini} into + mdraid09 and mdraid1x. + 2010-09-24 Colin Watson Re-enable grub-extras. diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index a5801db2f..422ca6ec6 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -61,9 +61,11 @@ void grub_emu_post_init (void) { grub_lvm_fini (); - grub_mdraid_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); grub_raid_fini (); grub_raid_init (); - grub_mdraid_init (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); grub_lvm_init (); } diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index c575beb4b..0a7645992 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include From 96510fafd246b1c8d44e1fef210e500f95b68a06 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 25 Sep 2010 10:48:48 +0530 Subject: [PATCH 0275/1414] fix typo --- ChangeLog | 4 ++++ grub-core/kern/emu/full.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2aa58c02..0bc9ac7c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-25 BVK Chaitanya + + * grub-core/kern/emu/full.c (grub_emu_post_init): Fix typo. + 2010-09-25 BVK Chaitanya Fix grub-emu build. diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 422ca6ec6..70bcae78f 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -65,7 +65,7 @@ grub_emu_post_init (void) grub_mdraid1x_fini (); grub_raid_fini (); grub_raid_init (); - grub_mdraid09_fini (); - grub_mdraid1x_fini (); + grub_mdraid09_init (); + grub_mdraid1x_init (); grub_lvm_init (); } From 419cbeb06d2733095b4cf9dad8b088f2338e1420 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Sep 2010 19:33:05 +0200 Subject: [PATCH 0276/1414] hook Reed-Solomon into startup.S --- Makefile.util.def | 2 +- grub-core/Makefile.am | 4 + grub-core/kern/i386/pc/startup.S | 16 ++ {util => grub-core/lib}/reed_solomon.c | 327 ++++++++++++++----------- include/grub/offsets.h | 4 +- 5 files changed, 209 insertions(+), 144 deletions(-) rename {util => grub-core/lib}/reed_solomon.c (63%) diff --git a/Makefile.util.def b/Makefile.util.def index 5d091f7f5..bf66d45bc 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -244,7 +244,7 @@ program = { common = util/grub-setup.c; common = util/raid.c; common = util/lvm.c; - common = util/reed_solomon.c; + common = grub-core/lib/reed_solomon.c; sparc64_ieee1275 = util/ieee1275/ofpath.c; diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index addc83417..307467f44 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -48,6 +48,10 @@ CLEANFILES += grub_script.tab.c grub_script.tab.h grub_script.yy.h: script/yylex.l $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $< grub_script.yy.c: grub_script.yy.h + +rs_decoder.S: $(srcdir)/lib/reed_solomon.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< + CLEANFILES += grub_script.yy.c grub_script.yy.h include $(srcdir)/Makefile.core.am diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 01825396c..283fc4f49 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -206,6 +206,22 @@ LOCAL (codestart): incl %eax call grub_gate_a20 + movl EXT_C(grub_kernel_image_size), %eax + addl EXT_C(grub_total_module_size), %eax + movl reed_solomon_redundancy, %ecx + leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %edx + testl %eax, %eax + jz post_reed_solomon + call EXT_C (grub_reed_solomon_recover) + jmp post_reed_solomon + +#include "/home/phcoder/compile/grub-core/rs_decoder.S" + + .text + + . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART +post_reed_solomon: + #ifdef ENABLE_LZMA movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi diff --git a/util/reed_solomon.c b/grub-core/lib/reed_solomon.c similarity index 63% rename from util/reed_solomon.c rename to grub-core/lib/reed_solomon.c index c20d023e7..290eb9482 100644 --- a/util/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -18,25 +18,48 @@ #ifdef TEST #include +#define xmalloc malloc +#define grub_memset memset +#define grub_memcpy memcpy +#endif + +#ifndef STANDALONE +#ifdef TEST #include #include typedef unsigned int grub_size_t; typedef unsigned char grub_uint8_t; typedef unsigned short grub_uint16_t; -#define xmalloc malloc -#define grub_memset memset -#define grub_memcpy memcpy #else #include #include #include #include #endif +#endif + +#ifdef STANDALONE +#ifdef TEST +typedef unsigned int grub_size_t; +typedef unsigned char grub_uint8_t; +typedef unsigned short grub_uint16_t; +#else +#include +#endif +void +grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs); +#endif #define GF_SIZE 8 typedef grub_uint8_t gf_single_t; typedef grub_uint16_t gf_double_t; -const gf_single_t gf_polynomial = 0x1d; +#define GF_POLYNOMIAL 0x1d +#define GF_INVERT2 0x8e +#ifdef STANDALONE +static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100000; +#else +static char *scratch; +#endif #define SECTOR_SIZE 512 #define MAX_BLOCK_SIZE (200 * SECTOR_SIZE) @@ -47,7 +70,7 @@ gf_reduce (gf_double_t a) int i; for (i = GF_SIZE - 1; i >= 0; i--) if (a & (1ULL << (i + GF_SIZE))) - a ^= (((gf_double_t) gf_polynomial) << i); + a ^= (((gf_double_t) GF_POLYNOMIAL) << i); return a & ((1ULL << GF_SIZE) - 1); } @@ -62,50 +85,19 @@ gf_mul (gf_single_t a, gf_single_t b) return gf_reduce (res); } -static int -bin_log2 (gf_double_t a) +static grub_uint8_t gf_invert[256]; + +static void +init_inverts (void) { - int i = 0; - while (a) + gf_single_t a = 1, ai = 1; + do { - a >>= 1; - i++; + a = gf_mul (a, 2); + ai = gf_mul (ai, GF_INVERT2); + gf_invert[a] = ai; } - return i - 1; -} - -static gf_single_t -gf_invert (gf_single_t a) -{ - /* We start with: */ - /* 1 * a + 0 * p = a */ - /* 0 * a + 1 * p = p */ - gf_double_t x1 = 1, y1 = 0, z1 = a, x2 = 0, y2 = 1; - gf_double_t z2 = gf_polynomial | (1ULL << GF_SIZE), t; - /* invariant: z1 < z2*/ - while (z1 != 0) - { - int k; - k = bin_log2 (z2) - bin_log2 (z1); - x2 ^= (x1 << k); - y2 ^= (y1 << k); - z2 ^= (z1 << k); - - if (z1 >= z2) - { - t = x2; - x2 = x1; - x1 = t; - t = y2; - y2 = y1; - y1 = t; - t = z2; - z2 = z1; - z1 = t; - } - } - - return gf_reduce (x2); + while (a != 1); } static gf_single_t @@ -121,6 +113,7 @@ pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) return s; } +#if !defined (STANDALONE) || defined (TEST) static void rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) { @@ -139,7 +132,7 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) if (a & (1 << (GF_SIZE - 1))) { a <<= 1; - a ^= gf_polynomial; + a ^= GF_POLYNOMIAL; } else a <<= 1; @@ -157,21 +150,21 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) free (rs_polynomial); grub_memcpy (data + s, m + s, rs * sizeof (gf_single_t)); free (m); - } +#endif static void syndroms (gf_single_t *m, grub_size_t s, grub_size_t rs, gf_single_t *sy) { gf_single_t xn = 1; - int i; + unsigned i; for (i = 0; i < rs; i++) { if (xn & (1 << (GF_SIZE - 1))) { xn <<= 1; - xn ^= gf_polynomial; + xn ^= GF_POLYNOMIAL; } else xn <<= 1; @@ -179,6 +172,66 @@ syndroms (gf_single_t *m, grub_size_t s, grub_size_t rs, } } +static void +gauss_eliminate (gf_single_t *eq, int n, int m, int *chosen) +{ + int i, j; + + for (i = 0 ; i < n; i++) + { + int nzidx; + int k; + gf_single_t r; + for (nzidx = 0; nzidx < m && (eq[i * (m + 1) + nzidx] == 0); + nzidx++); + if (nzidx == m) + continue; + chosen[i] = nzidx; + r = gf_invert [eq[i * (m + 1) + nzidx]]; + for (j = 0; j < m + 1; j++) + eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r); + for (j = i + 1; j < n; j++) + { + gf_single_t rr = eq[j * (m + 1) + nzidx]; + for (k = 0; k < m + 1; k++) + eq[j * (m + 1) + k] ^= gf_mul (eq[i * (m + 1) + k], rr); + } + } +} + +static void +gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol) +{ + int *chosen; + int i, j; + +#ifndef STANDALONE + chosen = xmalloc (n * sizeof (int)); + grub_memset (chosen, -1, n * sizeof (int)); +#else + chosen = (void *) scratch; + scratch += n; +#endif + for (i = 0; i < m; i++) + sol[i] = 0; + gauss_eliminate (eq, n, m, chosen); + for (i = n - 1; i >= 0; i--) + { + gf_single_t s = 0; + if (chosen[i] == -1) + continue; + for (j = 0; j < m; j++) + s ^= gf_mul (eq[i * (m + 1) + j], sol[j]); + s ^= eq[i * (m + 1) + m]; + sol[chosen[i]] = s; + } +#ifndef STANDALONE + free (chosen); +#else + scratch -= n; +#endif +} + static void rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) { @@ -190,76 +243,61 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) int errnum = 0; int i, j; +#ifndef STANDALONE sigma = xmalloc (rs2 * sizeof (gf_single_t)); errpot = xmalloc (rs2 * sizeof (gf_single_t)); errpos = xmalloc (rs2 * sizeof (int)); sy = xmalloc (rs * sizeof (gf_single_t)); +#else + sigma = (void *) scratch; + scratch += rs2 * sizeof (gf_single_t); + errpot = (void *) scratch; + scratch += rs2 * sizeof (gf_single_t); + errpos = (void *) scratch; + scratch += rs2 * sizeof (int); + sy = (void *) scratch; + scratch += rs * sizeof (gf_single_t); +#endif syndroms (m, s, rs, sy); { gf_single_t *eq; - int *chosen; +#ifndef STANDALONE eq = xmalloc (rs2 * (rs2 + 1) * sizeof (gf_single_t)); - chosen = xmalloc (rs2 * sizeof (int)); +#else + eq = (void *) scratch; + scratch += rs2 * (rs2 + 1) * sizeof (gf_single_t); +#endif - for (i = 0; i < rs; i++) + for (i = 0; i < (int) rs; i++) if (sy[i] != 0) break; /* No error detected. */ - if (i == rs) + if (i == (int) rs) return; - for (i = 0; i < rs2; i++) - for (j = 0; j < rs2 + 1; j++) + for (i = 0; i < (int) rs2; i++) + for (j = 0; j < (int) rs2 + 1; j++) eq[i * (rs2 + 1) + j] = sy[i+j]; - grub_memset (sigma, 0, rs2 * sizeof (gf_single_t)); - grub_memset (chosen, -1, rs2 * sizeof (int)); + for (i = 0; i < (int) rs2; i++) + sigma[i] = 0; - for (i = 0 ; i < rs2; i++) - { - int nzidx; - int k; - gf_single_t r; - for (nzidx = 0; nzidx < rs2 && (eq[i * (rs2 + 1) + nzidx] == 0); - nzidx++); - if (nzidx == rs2) - { - break; - } - chosen[i] = nzidx; - r = gf_invert (eq[i * (rs2 + 1) + nzidx]); - for (j = 0; j < rs2 + 1; j++) - eq[i * (rs2 + 1) + j] = gf_mul (eq[i * (rs2 + 1) + j], r); - for (j = i + 1; j < rs2; j++) - { - gf_single_t rr = eq[j * (rs2 + 1) + nzidx]; - for (k = 0; k < rs2 + 1; k++) - eq[j * (rs2 + 1) + k] ^= gf_mul (eq[i * (rs2 + 1) + k], rr);; - } - } - for (i = rs2 - 1; i >= 0; i--) - { - gf_single_t s = 0; - if (chosen[i] == -1) - continue; - for (j = 0; j < rs2; j++) - s ^= gf_mul (eq[i * (rs2 + 1) + j], sigma[j]); - s ^= eq[i * (rs2 + 1) + rs2]; - sigma[chosen[i]] = s; - } + gauss_solve (eq, rs2, rs2, sigma); - free (chosen); +#ifndef STANDALONE free (eq); +#else + scratch -= rs2 * (rs2 + 1) * sizeof (gf_single_t); +#endif } { - gf_single_t xn = 1, xx = gf_invert (2), yn = 1; - int lp = 0; - for (i = 0; i < rs + s; i++) + gf_single_t xn = 1, yn = 1; + for (i = 0; i < (int) (rs + s); i++) { gf_single_t ev = (gf_mul (pol_evaluate (sigma, rs2 - 1, xn), xn) ^ 1); if (ev == 0) @@ -268,96 +306,87 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) errpos[errnum++] = s + rs - i - 1; } yn = gf_mul (yn, 2); - xn = gf_mul (xn, xx); + xn = gf_mul (xn, GF_INVERT2); } } { - gf_single_t *eq; - int *chosen; gf_single_t *errvals; + gf_single_t *eq; +#ifndef STANDALONE eq = xmalloc (rs * (errnum + 1) * sizeof (gf_single_t)); - chosen = xmalloc (rs * sizeof (int)); errvals = xmalloc (errnum * sizeof (int)); - - grub_memset (chosen, -1, rs * sizeof (int)); - grub_memset (errvals, 0, errnum * sizeof (gf_single_t)); +#else + eq = (void *) scratch; + scratch += rs * (errnum + 1) * sizeof (gf_single_t); + errvals = (void *) scratch; + scratch += errnum * sizeof (int); +#endif for (j = 0; j < errnum; j++) eq[j] = errpot[j]; eq[errnum] = sy[0]; - for (i = 1; i < rs; i++) + for (i = 1; i < (int) rs; i++) { - for (j = 0; j < errnum; j++) + for (j = 0; j < (int) errnum; j++) eq[(errnum + 1) * i + j] = gf_mul (errpot[j], eq[(errnum + 1) * (i - 1) + j]); eq[(errnum + 1) * i + errnum] = sy[i]; } - for (i = 0 ; i < rs; i++) - { - int nzidx; - int k; - gf_single_t r; - for (nzidx = 0; nzidx < errnum && (eq[i * (errnum + 1) + nzidx] == 0); - nzidx++); - if (nzidx == errnum) - continue; - chosen[i] = nzidx; - r = gf_invert (eq[i * (errnum + 1) + nzidx]); - for (j = 0; j < errnum + 1; j++) - eq[i * (errnum + 1) + j] = gf_mul (eq[i * (errnum + 1) + j], r); - for (j = i + 1; j < rs; j++) - { - gf_single_t rr = eq[j * (errnum + 1) + nzidx]; - for (k = 0; k < errnum + 1; k++) - eq[j * (errnum + 1) + k] ^= gf_mul (eq[i * (errnum + 1) + k], rr); - } - } - for (i = rs - 1; i >= 0; i--) - { - gf_single_t s = 0; - if (chosen[i] == -1) - continue; - for (j = 0; j < errnum; j++) - s ^= gf_mul (eq[i * (errnum + 1) + j], errvals[j]); - s ^= eq[i * (errnum + 1) + errnum]; - errvals[chosen[i]] = s; - } - for (i = 0; i < errnum; i++) + + gauss_solve (eq, rs, errnum, errvals); + + for (i = 0; i < (int) errnum; i++) m[errpos[i]] ^= errvals[i]; +#ifndef STANDALONE + free (eq); + free (errvals); +#else + scratch -= rs * (errnum + 1) * sizeof (gf_single_t); + scratch -= errnum * sizeof (int); +#endif } +#ifndef STANDALONE + free (sigma); + free (errpot); + free (errpos); free (sy); +#else + scratch -= rs2 * sizeof (gf_single_t); + scratch -= rs2 * sizeof (gf_single_t); + scratch -= rs2 * sizeof (int); + scratch -= rs * sizeof (gf_single_t); +#endif } static void decode_block (gf_single_t *ptr, grub_size_t s, gf_single_t *rptr, grub_size_t rs) { - grub_size_t ss; - int i, j, k; + int i, j; for (i = 0; i < SECTOR_SIZE; i++) { grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; gf_single_t m[ds + rr]; - for (j = 0; j < ds; j++) + for (j = 0; j < (int) ds; j++) m[j] = ptr[SECTOR_SIZE * j + i]; - for (j = 0; j < rr; j++) + for (j = 0; j < (int) rr; j++) m[j + ds] = rptr[SECTOR_SIZE * j + i]; rs_recover (m, ds, rr); - for (j = 0; j < ds; j++) + for (j = 0; j < (int) ds; j++) ptr[SECTOR_SIZE * j + i] = m[j]; } } +#if !defined (STANDALONE) || defined (TEST) static void encode_block (gf_single_t *ptr, grub_size_t s, gf_single_t *rptr, grub_size_t rs) { - grub_size_t ss; int i, j; for (i = 0; i < SECTOR_SIZE; i++) { @@ -371,7 +400,9 @@ encode_block (gf_single_t *ptr, grub_size_t s, rptr[SECTOR_SIZE * j + i] = m[j + ds]; } } +#endif +#if !defined (STANDALONE) || defined (TEST) void grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, grub_size_t redundancy) @@ -400,11 +431,18 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, rs -= crs; } } +#endif void -grub_reed_solomon_recover (void *ptr, grub_size_t s, grub_size_t rs) +grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) { + gf_single_t *ptr = ptr_; gf_single_t *rptr = ptr + s; + +#if defined (STANDALONE) && !defined (TEST) + init_inverts (); +#endif + while (s > 0) { grub_size_t tt; @@ -432,6 +470,13 @@ main (int argc, char **argv) FILE *in, *out; grub_size_t s, rs; char *buf; + +#ifdef STANDALONE + scratch = xmalloc (1048576); +#endif + + init_inverts (); + in = fopen ("tst.bin", "rb"); if (!in) return 1; diff --git a/include/grub/offsets.h b/include/grub/offsets.h index d1cf8720f..b8fbe40d4 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -41,9 +41,9 @@ #define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x20 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0x5E0 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc6c -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x300 +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x748 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE From 3ac9e7920712be587214e904139a3871add55392 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Sep 2010 20:40:26 +0200 Subject: [PATCH 0277/1414] Multiple bugs correction for Reed-Solomon --- grub-core/Makefile.am | 2 +- grub-core/kern/i386/pc/startup.S | 10 +++++----- grub-core/lib/reed_solomon.c | 28 +++++++++++++++++++--------- include/grub/offsets.h | 4 ++-- util/grub-setup.c | 2 +- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 307467f44..a740cb5cb 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -50,7 +50,7 @@ grub_script.yy.h: script/yylex.l grub_script.yy.c: grub_script.yy.h rs_decoder.S: $(srcdir)/lib/reed_solomon.c - $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 CLEANFILES += grub_script.yy.c grub_script.yy.h diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 283fc4f49..9319df98e 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -206,16 +206,16 @@ LOCAL (codestart): incl %eax call grub_gate_a20 - movl EXT_C(grub_kernel_image_size), %eax - addl EXT_C(grub_total_module_size), %eax + movl EXT_C(grub_compressed_size), %edx + addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx movl reed_solomon_redundancy, %ecx - leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %edx - testl %eax, %eax + leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax + testl %edx, %edx jz post_reed_solomon call EXT_C (grub_reed_solomon_recover) jmp post_reed_solomon -#include "/home/phcoder/compile/grub-core/rs_decoder.S" +#include .text diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 290eb9482..f87ff1552 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -55,10 +55,12 @@ typedef grub_uint8_t gf_single_t; typedef grub_uint16_t gf_double_t; #define GF_POLYNOMIAL 0x1d #define GF_INVERT2 0x8e -#ifdef STANDALONE -static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100000; +#if defined (STANDALONE) && !defined (TEST) +static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; +static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; #else static char *scratch; +static grub_uint8_t gf_invert[256]; #endif #define SECTOR_SIZE 512 @@ -85,8 +87,6 @@ gf_mul (gf_single_t a, gf_single_t b) return gf_reduce (res); } -static grub_uint8_t gf_invert[256]; - static void init_inverts (void) { @@ -113,7 +113,7 @@ pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) return s; } -#if !defined (STANDALONE) || defined (TEST) +#if !defined (STANDALONE) static void rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) { @@ -382,7 +382,7 @@ decode_block (gf_single_t *ptr, grub_size_t s, } } -#if !defined (STANDALONE) || defined (TEST) +#if !defined (STANDALONE) static void encode_block (gf_single_t *ptr, grub_size_t s, gf_single_t *rptr, grub_size_t rs) @@ -402,7 +402,7 @@ encode_block (gf_single_t *ptr, grub_size_t s, } #endif -#if !defined (STANDALONE) || defined (TEST) +#if !defined (STANDALONE) void grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, grub_size_t redundancy) @@ -412,6 +412,8 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, gf_single_t *ptr = buffer; gf_single_t *rptr = ptr + s; + grub_printf ("solomon: %p, %x, %x\n", buffer, data_size, redundancy); + while (s > 0) { grub_size_t tt; @@ -439,7 +441,7 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) gf_single_t *ptr = ptr_; gf_single_t *rptr = ptr + s; -#if defined (STANDALONE) && !defined (TEST) +#if defined (STANDALONE) init_inverts (); #endif @@ -475,7 +477,9 @@ main (int argc, char **argv) scratch = xmalloc (1048576); #endif +#ifndef STANDALONE init_inverts (); +#endif in = fopen ("tst.bin", "rb"); if (!in) @@ -487,6 +491,10 @@ main (int argc, char **argv) buf = xmalloc (s + rs + SECTOR_SIZE); fread (buf, 1, s, in); + s = 0x5fbb; + rs = 0x6af9; + +#if 0 grub_reed_solomon_add_redundancy (buf, s, rs); out = fopen ("tst_rs.bin", "wb"); @@ -498,7 +506,9 @@ main (int argc, char **argv) out = fopen ("tst_dam.bin", "wb"); fwrite (buf, 1, s + rs, out); fclose (out); - +#endif + s = 0x5fbb; + rs = 0x6af9; grub_reed_solomon_recover (buf, s, rs); out = fopen ("tst_rec.bin", "wb"); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index b8fbe40d4..28db0115c 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -41,9 +41,9 @@ #define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x20 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc6c +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc80 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x748 +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x75c /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE diff --git a/util/grub-setup.c b/util/grub-setup.c index 1518bb0a8..953f0038b 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -438,7 +438,7 @@ setup (const char *dir, 0, GRUB_DISK_SECTOR_SIZE); block = first_block; - for (i = 1; i < core_sectors; i++) + for (i = 1; i < nsec; i++) save_blocklists (sectors[i] + grub_partition_get_start (container), 0, GRUB_DISK_SECTOR_SIZE); From 25e09515ad227965a31fde020aa406afdb0c4492 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Sep 2010 21:42:13 +0200 Subject: [PATCH 0278/1414] Make mb header to protected part --- grub-core/kern/i386/pc/startup.S | 106 +++++++++++++++---------------- include/grub/offsets.h | 4 +- 2 files changed, 53 insertions(+), 57 deletions(-) diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 9319df98e..c4abc31b8 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -109,7 +109,58 @@ bss_start: bss_end: .long 0 #endif +/* + * This is the area for all of the special variables. + */ +VARIABLE(grub_boot_drive) + .byte 0 + +/* the real mode code continues... */ +LOCAL (codestart): + cli /* we're not safe here! */ + + /* set up %ds, %ss, and %es */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw %ax, %es + + /* set up the real mode/BIOS stack */ + movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp + movl %ebp, %esp + + sti /* we're safe again */ + + /* save the boot drive */ + ADDR32 movb %dl, EXT_C(grub_boot_drive) + + /* reset disk system (%ah = 0) */ + int $0x13 + + /* transition to protected mode */ + DATA32 call real_to_prot + + /* The ".code32" directive takes GAS out of 16-bit mode. */ + .code32 + + incl %eax + call grub_gate_a20 + + movl EXT_C(grub_compressed_size), %edx + addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx + movl reed_solomon_redundancy, %ecx + leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax + testl %edx, %edx + jz post_reed_solomon + call EXT_C (grub_reed_solomon_recover) + jmp post_reed_solomon + +#include + + .text + + . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). * This uses the a.out kludge to load raw binary to the area starting at 1MB, @@ -173,53 +224,7 @@ multiboot_trampoline: movb $0xFF, %dh /* enter the usual booting */ call prot_to_real - .code16 -/* the real mode code continues... */ -LOCAL (codestart): - cli /* we're not safe here! */ - - /* set up %ds, %ss, and %es */ - xorw %ax, %ax - movw %ax, %ds - movw %ax, %ss - movw %ax, %es - - /* set up the real mode/BIOS stack */ - movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp - movl %ebp, %esp - - sti /* we're safe again */ - - /* save the boot drive */ - ADDR32 movb %dl, EXT_C(grub_boot_drive) - - /* reset disk system (%ah = 0) */ - int $0x13 - - /* transition to protected mode */ - DATA32 call real_to_prot - - /* The ".code32" directive takes GAS out of 16-bit mode. */ - .code32 - - incl %eax - call grub_gate_a20 - - movl EXT_C(grub_compressed_size), %edx - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx - movl reed_solomon_redundancy, %ecx - leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax - testl %edx, %edx - jz post_reed_solomon - call EXT_C (grub_reed_solomon_recover) - jmp post_reed_solomon - -#include - - .text - - . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART post_reed_solomon: #ifdef ENABLE_LZMA @@ -289,15 +294,6 @@ post_reed_solomon: */ call EXT_C(grub_main) -/* - * This is the area for all of the special variables. - */ - -VARIABLE(grub_boot_drive) - .byte 0 - - .p2align 2 /* force 4-byte alignment */ - #include "../realmode.S" /* diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 28db0115c..f11dffaca 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -41,9 +41,9 @@ #define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x20 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc80 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc90 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x75c +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6f8 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE From 53c9e7798cd9c70bc7b04220fa514013dfc28a6b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Sep 2010 21:42:36 +0200 Subject: [PATCH 0279/1414] Remove debug printf --- grub-core/lib/reed_solomon.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index f87ff1552..4c6e160e4 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -412,8 +412,6 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, gf_single_t *ptr = buffer; gf_single_t *rptr = ptr + s; - grub_printf ("solomon: %p, %x, %x\n", buffer, data_size, redundancy); - while (s > 0) { grub_size_t tt; From 40ca6b29fdcf97422cb8c882b5a9cffce87b2107 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Sep 2010 21:43:04 +0200 Subject: [PATCH 0280/1414] Fix missing mreparm=3 --- grub-core/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index a740cb5cb..294888909 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -50,7 +50,7 @@ grub_script.yy.h: script/yylex.l grub_script.yy.c: grub_script.yy.h rs_decoder.S: $(srcdir)/lib/reed_solomon.c - $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 CLEANFILES += grub_script.yy.c grub_script.yy.h From 4e2b20a79afe61df9901e943a453624f2453018f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Sep 2010 13:37:08 +0200 Subject: [PATCH 0281/1414] Add missing dependency on rs_Decoder.S --- grub-core/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 294888909..1881c5844 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -52,6 +52,8 @@ grub_script.yy.c: grub_script.yy.h rs_decoder.S: $(srcdir)/lib/reed_solomon.c $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 +kern/i386/pc/startup.S: $(builddir)/rs_decoder.S + CLEANFILES += grub_script.yy.c grub_script.yy.h include $(srcdir)/Makefile.core.am From f9130836402773d115acf026adbe36b3185d707d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 26 Sep 2010 15:53:05 +0200 Subject: [PATCH 0282/1414] 2010-09-26 Robert Millan Build fixes for GNU/kFreeBSD. * Makefile.util.def: Add `$(LIBZFS) $(LIBNVPAIR)' library dependencies to programs that require ZFS conversion. * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Support kernels that don't have FLOPPY_MAJOR. --- ChangeLog | 9 +++++++++ Makefile.util.def | 24 ++++++++++++------------ grub-core/kern/emu/hostdisk.c | 11 ++++++++++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bc9ac7c2..379549b95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-26 Robert Millan + + Build fixes for GNU/kFreeBSD. + + * Makefile.util.def: Add `$(LIBZFS) $(LIBNVPAIR)' library dependencies + to programs that require ZFS conversion. + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Support + kernels that don't have FLOPPY_MAJOR. + 2010-09-25 BVK Chaitanya * grub-core/kern/emu/full.c (grub_emu_post_init): Fix typo. diff --git a/Makefile.util.def b/Makefile.util.def index 42165df3d..21dda2df7 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -109,7 +109,7 @@ program = { ldadd = libgrub.a; ldadd = '$(LIBLZMA)'; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"'; }; @@ -121,7 +121,7 @@ program = { common = util/grub-mkrelpath.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -132,7 +132,7 @@ program = { common = util/grub-script-check.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -143,7 +143,7 @@ program = { common = util/grub-editenv.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -154,7 +154,7 @@ program = { common = util/grub-mkpasswd-pbkdf2.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; @@ -190,7 +190,7 @@ program = { cppflags = '$(CPPFLAGS_GCRY)'; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -203,7 +203,7 @@ program = { cflags = '$(freetype_cflags)'; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; condition = COND_GRUB_MKFONT; @@ -222,7 +222,7 @@ program = { sparc64_ieee1275 = util/ieee1275/devicemap.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -233,7 +233,7 @@ program = { common = util/grub-probe.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -248,7 +248,7 @@ program = { sparc64_ieee1275 = util/ieee1275/ofpath.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; enable = i386_pc; @@ -274,7 +274,7 @@ program = { common = util/grub-mklayout.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; @@ -595,6 +595,6 @@ program = { common = grub-core/lib/i386/pc/vesa_modes_table.c; ldadd = libgrub.a; - ldflags = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; ldadd = grub-core/gnulib/libgnu.a; }; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 19d3856a2..08f60ee66 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1,7 +1,7 @@ /* hostdisk.c - emulate biosdisk */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,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 @@ -1627,7 +1627,16 @@ grub_util_biosdisk_is_floppy (grub_disk_t disk) return 1; #endif +#if defined(FLOPPY_MAJOR) if (major(st.st_rdev) == FLOPPY_MAJOR) +#else + /* Some kernels (e.g. kFreeBSD) don't have a static major number + for floppies, but they still use a "fd[0-9]" pathname. */ + if (map[disk->id].device[5] == 'f' + && map[disk->id].device[6] == 'd' + && map[disk->id].device[7] >= '0' + && map[disk->id].device[7] <= '9') +#endif return 1; return 0; From 8e57a6ca44dca7bff5867e0576105b0ba82f2bdf Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 26 Sep 2010 16:11:33 +0200 Subject: [PATCH 0283/1414] 2010-09-26 Robert Millan Support degraded ZFS arrays in "grub-probe -t device" resolution. * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): When the pool is an array of devices, iterate through it and return the first device that passes a stat() test (instead of blindly returning the first one). --- ChangeLog | 9 +++++++++ grub-core/kern/emu/getroot.c | 31 ++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 379549b95..803cd3168 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-09-26 Robert Millan + + Support degraded ZFS arrays in "grub-probe -t device" resolution. + + * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): When + the pool is an array of devices, iterate through it and return the + first device that passes a stat() test (instead of blindly returning + the first one). + 2010-09-26 Robert Millan Build fixes for GNU/kFreeBSD. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 003fe9333..0433d49ed 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -189,31 +189,40 @@ find_root_device_from_libzfs (const char *dir) { zpool_handle_t *zpool; libzfs_handle_t *libzfs; - nvlist_t *nvlist; - nvlist_t **nvlist_array; + nvlist_t *config, *vdev_tree; + nvlist_t **children, **path; unsigned int nvlist_count; + unsigned int i; libzfs = grub_get_libzfs_handle (); if (! libzfs) return NULL; zpool = zpool_open (libzfs, poolname); - nvlist = zpool_get_config (zpool, NULL); + config = zpool_get_config (zpool, NULL); - if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0) + if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0) error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")"); - if (nvlist_lookup_nvlist_array (nvlist, "children", &nvlist_array, &nvlist_count) != 0) + if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0) error (1, errno, "nvlist_lookup_nvlist_array (\"children\")"); + assert (nvlist_count > 0); - do + while (nvlist_lookup_nvlist_array (children[0], "children", + &children, &nvlist_count) == 0) + assert (nvlist_count > 0); + + for (i = 0; i < nvlist_count; i++) { - assert (nvlist_count > 0); - } while (nvlist_lookup_nvlist_array (nvlist_array[0], "children", - &nvlist_array, &nvlist_count) == 0); + if (nvlist_lookup_string (children[i], "path", &device) != 0) + error (1, errno, "nvlist_lookup_string (\"path\")"); - if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0) - error (1, errno, "nvlist_lookup_string (\"path\")"); + struct stat st; + if (stat (device, &st) == 0) + break; + + device = NULL; + } zpool_close (zpool); } From f772623bc030fb29e0dca57c7176284902fd50a4 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Mon, 27 Sep 2010 11:11:38 +0200 Subject: [PATCH 0284/1414] Fix generation of kernel_syms.lst * grub-core/Makefile.am (kernel_syms.lst): Fix value and position of ASM_PREFIX --- ChangeLog | 7 +++++++ grub-core/Makefile.am | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 803cd3168..e428dcd53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-09-27 Yves Blusseau + + Fix generation of kernel_syms.lst + + * grub-core/Makefile.am (kernel_syms.lst): Fix value and position of + ASM_PREFIX + 2010-09-26 Robert Millan Support degraded ZFS arrays in "grub-probe -t device" resolution. diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index cff6b3782..0659d1c14 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -173,7 +173,7 @@ CLEANFILES += symlist.c BUILT_SOURCES += symlist.c if COND_HAVE_ASM_USCORE -ASM_PREFIX=1 +ASM_PREFIX=_ else ASM_PREFIX= endif @@ -183,8 +183,8 @@ noinst_DATA += kernel_syms.lst kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined '"$(ASM_PREFIX)"'kernel \1/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined '"$(ASM_PREFIX)"' kernel \1/;p;}' \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ | sort -u >$@ rm -f kernel_syms.input CLEANFILES += kernel_syms.lst From 0b4b227faecce80c0d8a5406c82df59c45bce754 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 28 Sep 2010 17:38:34 +0100 Subject: [PATCH 0285/1414] * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix i386 and x86-64 definedness tests. --- ChangeLog | 5 +++++ grub-core/loader/multiboot_mbi2.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e428dcd53..f33ddb6af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-28 Colin Watson + + * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix + i386 and x86-64 definedness tests. + 2010-09-27 Yves Blusseau Fix generation of kernel_syms.lst diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index a20c82cad..75eaec33d 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -705,7 +705,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) } } -#if defined (GRUB_MACHINE_EFI) && __x86_64__ +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) { struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi64 *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_EFI64; @@ -715,7 +715,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) } #endif -#if defined (GRUB_MACHINE_EFI) && __i386__ +#if defined (GRUB_MACHINE_EFI) && defined (__i386__) { struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi32 *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_EFI32; From edde54e656a3219a6ad5e7118e0212d50af01697 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 29 Sep 2010 22:45:57 +0200 Subject: [PATCH 0286/1414] * grub-core/boot/i386/pc/lnxboot.S: Replace GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE with GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART. --- ChangeLog | 6 ++++++ grub-core/boot/i386/pc/lnxboot.S | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fe48dc277..91049acdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-29 Vladimir Serbinenko + + * grub-core/boot/i386/pc/lnxboot.S: Replace + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE with + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART. + 2010-09-29 Vladimir Serbinenko Write embedding zone using Reed-Solomon. diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index 9348553c3..9a599c261 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -185,7 +185,7 @@ real_code_2: call LOCAL(move_memory) /* Check for multiboot signature. */ - cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE) + cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART) jz 1f movl (ramdisk_image - start), %esi From 44a1b4327ad982dd040aba6f442d993c9e6e5503 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 29 Sep 2010 22:48:38 +0200 Subject: [PATCH 0287/1414] * grub-core/lib/arg.c (grub_arg_parse): Fix treating of all commands as if they were BSD-style. --- ChangeLog | 5 +++++ grub-core/lib/arg.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 91049acdd..4e03814fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-29 Vladimir Serbinenko + + * grub-core/lib/arg.c (grub_arg_parse): Fix treating of all commands as + if they were BSD-style. + 2010-09-29 Vladimir Serbinenko * grub-core/boot/i386/pc/lnxboot.S: Replace diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c index dabf4e8ce..1c765f12a 100644 --- a/grub-core/lib/arg.c +++ b/grub-core/lib/arg.c @@ -260,7 +260,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, char *option = 0; /* No option is used. */ - if ((num && GRUB_COMMAND_OPTIONS_AT_START) + if ((num && (cmd->cmd->flags & GRUB_COMMAND_OPTIONS_AT_START)) || arg[0] != '-' || grub_strlen (arg) == 1) { if (add_arg (arg) != 0) From d33613fcf3e4d2076a8df6d6d5aa24927fc6fdd5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 29 Sep 2010 22:51:12 +0200 Subject: [PATCH 0288/1414] * grub-core/loader/i386/bsd.c (grub_cmd_netbsd): Provide default serial parameters. --- ChangeLog | 5 +++++ grub-core/loader/i386/bsd.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4e03814fd..bd8b33b53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-29 Vladimir Serbinenko + + * grub-core/loader/i386/bsd.c (grub_cmd_netbsd): Provide default serial + parameters. + 2010-09-29 Vladimir Serbinenko * grub-core/lib/arg.c (grub_arg_parse): Fix treating of all commands as diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 456c5f36c..b7cf115d9 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -1559,6 +1559,9 @@ grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) grub_memset (&serial, 0, sizeof (serial)); grub_strcpy (serial.devname, "com"); + serial.addr = grub_ns8250_hw_get_port (0); + serial.speed = 9600; + if (ctxt->state[NETBSD_SERIAL_ARG].arg) { ptr = ctxt->state[NETBSD_SERIAL_ARG].arg; @@ -1581,7 +1584,7 @@ grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) return grub_errno; } } - + grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &serial, sizeof (serial)); } else From 2a4066114dc79c669ce2eb2f99809b4eaf7531bb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 29 Sep 2010 23:19:21 +0200 Subject: [PATCH 0289/1414] * grub-core/lib/relocator.c (malloc_in_range): Trim too verbose debug messages. (grub_relocator_prepare_relocs): Set movers_chunk.srcv. --- ChangeLog | 6 ++++++ grub-core/lib/relocator.c | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd8b33b53..63c6e83ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-09-29 Vladimir Serbinenko + + * grub-core/lib/relocator.c (malloc_in_range): Trim too verbose + debug messages. + (grub_relocator_prepare_relocs): Set movers_chunk.srcv. + 2010-09-29 Vladimir Serbinenko * grub-core/loader/i386/bsd.c (grub_cmd_netbsd): Provide default serial diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 9a6941332..a0cab55af 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -586,8 +586,6 @@ malloc_in_range (struct grub_relocator *rel, continue; do { - grub_dprintf ("relocator", "free block %p+0x%lx\n", - p, (unsigned long) p->size); if (p->magic != GRUB_MM_FREE_MAGIC) grub_fatal (__FILE__":%d free magic broken at %p (0x%x)\n", __LINE__, p, p->magic); @@ -1504,7 +1502,8 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, grub_relocator_align, rel->relocators_size, &movers_chunk, 1, 1)) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); - rels = rels0 = grub_map_memory (movers_chunk.src, movers_chunk.size); + movers_chunk.srcv = rels = rels0 + = grub_map_memory (movers_chunk.src, movers_chunk.size); if (relsize) *relsize = rel->relocators_size; From 579940128bcd6feeffed7e261b21d6a75c010226 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 29 Sep 2010 23:51:12 +0200 Subject: [PATCH 0290/1414] Fix coreboot compilation. * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_get_mbi_size): Take VBE info into account even if only text is supported. (fill_vbe_info): Take into account the case when only VGA text is supported. * include/grub/multiboot.h (GRUB_MACHINE_HAS_VBE): Set to zero on coreboot, multiboot and qemu. --- ChangeLog | 11 ++++++++++ grub-core/loader/i386/multiboot_mbi.c | 29 +++++++++++++++++++++------ include/grub/multiboot.h | 12 +++++++---- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63c6e83ee..4614a1cac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-09-29 Vladimir Serbinenko + + Fix coreboot compilation. + + * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_get_mbi_size): + Take VBE info into account even if only text is supported. + (fill_vbe_info): Take into account the case when only VGA text + is supported. + * include/grub/multiboot.h (GRUB_MACHINE_HAS_VBE): Set to zero + on coreboot, multiboot and qemu. + 2010-09-29 Vladimir Serbinenko * grub-core/lib/relocator.c (malloc_in_range): Trim too verbose diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 283b84c5a..79f72ee0f 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -187,6 +187,10 @@ grub_multiboot_load (grub_file_t file) return err; } +#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT +#include +#endif + static grub_size_t grub_multiboot_get_mbi_size (void) { @@ -196,7 +200,7 @@ grub_multiboot_get_mbi_size (void) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) + elf_sec_entsize * elf_sec_num + 256 * sizeof (struct multiboot_color) -#if GRUB_MACHINE_HAS_VBE +#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT + sizeof (struct grub_vbe_info_block) + sizeof (struct grub_vbe_mode_info_block) #endif @@ -247,15 +251,17 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) grub_mmap_iterate (hook); } -#if GRUB_MACHINE_HAS_VBE +#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT + static grub_err_t fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, grub_uint32_t ptrdest, int fill_generic) { - grub_vbe_status_t status; grub_uint32_t vbe_mode; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; struct grub_vbe_mode_info_block *mode_info; +#if GRUB_MACHINE_HAS_VBE + grub_vbe_status_t status; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; status = grub_vbe_bios_get_controller_info (scratch); if (status != GRUB_VBE_STATUS_OK) @@ -265,11 +271,18 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_info_block)); ptrorig += sizeof (struct grub_vbe_info_block); ptrdest += sizeof (struct grub_vbe_info_block); - +#else + mbi->vbe_control_info = 0; +#endif + +#if GRUB_MACHINE_HAS_VBE status = grub_vbe_bios_get_mode (scratch); vbe_mode = *(grub_uint32_t *) scratch; if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_IO, "can't get VBE mode"); +#else + vbe_mode = 3; +#endif mbi->vbe_mode = vbe_mode; mode_info = (struct grub_vbe_mode_info_block *) ptrorig; @@ -284,18 +297,22 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, } else { +#if GRUB_MACHINE_HAS_VBE status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_IO, "can't get mode info"); grub_memcpy (mode_info, scratch, sizeof (struct grub_vbe_mode_info_block)); +#endif } ptrorig += sizeof (struct grub_vbe_mode_info_block); ptrdest += sizeof (struct grub_vbe_mode_info_block); - + +#if GRUB_MACHINE_HAS_VBE grub_vbe_bios_get_pm_interface (&mbi->vbe_interface_seg, &mbi->vbe_interface_off, &mbi->vbe_interface_len); +#endif mbi->flags |= MULTIBOOT_INFO_VBE_INFO; diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 364dc3ca6..9a0b57359 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -53,15 +53,19 @@ grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, grub_uint32_t grub_get_multiboot_mmap_count (void); grub_err_t grub_multiboot_set_video_mode (void); -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) -#include -#define GRUB_MACHINE_HAS_VGA_TEXT 1 +/* FIXME: support coreboot as well. */ +#if defined (GRUB_MACHINE_PCBIOS) #define GRUB_MACHINE_HAS_VBE 1 #else -#define GRUB_MACHINE_HAS_VGA_TEXT 0 #define GRUB_MACHINE_HAS_VBE 0 #endif +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) +#define GRUB_MACHINE_HAS_VGA_TEXT 1 +#else +#define GRUB_MACHINE_HAS_VGA_TEXT 0 +#endif + #if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) #define GRUB_MACHINE_HAS_ACPI 1 #else From aa438e6818359e01a62d092aafdf366499a1653e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 29 Sep 2010 23:58:43 +0200 Subject: [PATCH 0291/1414] * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi] [GRUB_MACHINE_EFI && __i386__]: Fix typo. --- ChangeLog | 5 +++++ grub-core/loader/multiboot_mbi2.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4614a1cac..ec2db1936 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-29 Vladimir Serbinenko + + * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi] + [GRUB_MACHINE_EFI && __i386__]: Fix typo. + 2010-09-29 Vladimir Serbinenko Fix coreboot compilation. diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 75eaec33d..3141f0028 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -717,7 +717,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) #if defined (GRUB_MACHINE_EFI) && defined (__i386__) { - struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi32 *) ptrorig; + struct multiboot_tag_efi32 *tag = (struct multiboot_tag_efi32 *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_EFI32; tag->size = sizeof (*tag); tag->pointer = (grub_addr_t) grub_efi_system_table; From ee74fa4822da5ea1d757e5842a9875e57a6cc614 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 30 Sep 2010 17:50:01 +0200 Subject: [PATCH 0292/1414] Put terminfo into core on ieee1275 and yeeloong (needed for console). * gentpl.py: New groups terminfoinkernel and terminfomodule. * grub-core/Makefile.am (KERNEL_HEADER_FILES): Include extcmd.h, arg.h and terminfo.h when needed. * grub-core/Makefile.core.def (kernel): Include term/terminfo.c, term/tparm.c, commands/extcmd.c, lib/arg.c on terminfokernel. (terminfo): Enable only on terminfokernel. (extcmd): Likewise. * include/grub/extcmd.h: Add missing EXPORT_FUNC. * include/grub/lib/arg.h: Likewise. * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Fix incorrect usage of ->. --- ChangeLog | 16 ++++++++++++++ gentpl.py | 5 +++++ grub-core/Makefile.am | 11 ++++++++++ grub-core/Makefile.core.def | 12 +++++----- grub-core/term/ieee1275/ofconsole.c | 12 +++++----- include/grub/extcmd.h | 34 ++++++++++++++--------------- include/grub/lib/arg.h | 2 +- 7 files changed, 62 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec2db1936..197158f50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-09-30 Vladimir Serbinenko + + Put terminfo into core on ieee1275 and yeeloong (needed for console). + + * gentpl.py: New groups terminfoinkernel and terminfomodule. + * grub-core/Makefile.am (KERNEL_HEADER_FILES): Include extcmd.h, arg.h + and terminfo.h when needed. + * grub-core/Makefile.core.def (kernel): Include term/terminfo.c, + term/tparm.c, commands/extcmd.c, lib/arg.c on terminfokernel. + (terminfo): Enable only on terminfokernel. + (extcmd): Likewise. + * include/grub/extcmd.h: Add missing EXPORT_FUNC. + * include/grub/lib/arg.h: Likewise. + * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Fix + incorrect usage of ->. + 2010-09-29 Vladimir Serbinenko * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi] diff --git a/gentpl.py b/gentpl.py index 109ce7981..a42a60667 100644 --- a/gentpl.py +++ b/gentpl.py @@ -38,6 +38,11 @@ GROUPS["videoinkernel"] = ["mips_yeeloong"] GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) +# Similar for terminfo +GROUPS["terminfoinkernel"] = ["mips_yeeloong"] + GROUPS["ieee1275"]; +GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; +for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) + # Miscelaneous groups schedulded to disappear in future GROUPS["nosparc64"] = GRUB_PLATFORMS[:]; GROUPS["nosparc64"].remove("sparc64_ieee1275") GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index f08bb765c..9792dd974 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -113,6 +113,8 @@ endif if COND_i386_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h endif @@ -138,15 +140,24 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.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 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h endif if COND_sparc64_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h endif if COND_emu diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 49628cb84..8845c26ea 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -92,10 +92,10 @@ kernel = { ieee1275 = kern/ieee1275/openfw.c; ieee1275 = term/ieee1275/ofconsole.c; - ieee1275 = term/terminfo.c; - ieee1275 = term/tparm.c; - mips = term/terminfo.c; - mips = term/tparm.c; + terminfoinkernel = term/terminfo.c; + terminfoinkernel = term/tparm.c; + terminfoinkernel = commands/extcmd.c; + terminfoinkernel = lib/arg.c; i386 = kern/i386/dl.c; @@ -173,9 +173,7 @@ kernel = { emu = kern/emu/mm.c; emu = kern/emu/time.c; - videoinkernel = lib/arg.c; videoinkernel = term/gfxterm.c; - videoinkernel = commands/extcmd.c; videoinkernel = font/font.c; videoinkernel = font/font_cmd.c; videoinkernel = io/bufio.c; @@ -542,6 +540,7 @@ module = { name = extcmd; common = commands/extcmd.c; common = lib/arg.c; + enable = terminfomodule; }; module = { @@ -1337,6 +1336,7 @@ module = { name = terminfo; common = term/terminfo.c; common = term/tparm.c; + enable = terminfomodule; }; module = { diff --git a/grub-core/term/ieee1275/ofconsole.c b/grub-core/term/ieee1275/ofconsole.c index 944056ba6..2b0bddbbb 100644 --- a/grub-core/term/ieee1275/ofconsole.c +++ b/grub-core/term/ieee1275/ofconsole.c @@ -90,7 +90,7 @@ grub_ofconsole_dimensions (void) if (! grub_ieee1275_get_property (options, "screen-#columns", val, lval, 0)) - grub_ofconsole_terminfo_output->width + grub_ofconsole_terminfo_output.width = (grub_uint8_t) grub_strtoul (val, 0, 10); } if (! grub_ieee1275_get_property_length (options, "screen-#rows", &lval) @@ -99,16 +99,16 @@ grub_ofconsole_dimensions (void) char val[lval]; if (! grub_ieee1275_get_property (options, "screen-#rows", val, lval, 0)) - grub_ofconsole_terminfo_output->height + grub_ofconsole_terminfo_output.height = (grub_uint8_t) grub_strtoul (val, 0, 10); } } /* Use a small console by default. */ - if (! grub_ofconsole_terminfo_output->width) - grub_ofconsole_terminfo_output->width = 80; - if (! grub_ofconsole_terminfo_output->height) - grub_ofconsole_terminfo_output->height = 24; + if (! grub_ofconsole_terminfo_output.width) + grub_ofconsole_terminfo_output.width = 80; + if (! grub_ofconsole_terminfo_output.height) + grub_ofconsole_terminfo_output.height = 24; } static void diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h index c34a1df66..19fe59266 100644 --- a/include/grub/extcmd.h +++ b/include/grub/extcmd.h @@ -55,25 +55,25 @@ struct grub_extcmd_context }; typedef struct grub_extcmd_context *grub_extcmd_context_t; -grub_extcmd_t grub_register_extcmd (const char *name, - grub_extcmd_func_t func, - grub_command_flags_t flags, - const char *summary, - const char *description, - const struct grub_arg_option *parser); +grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name, + grub_extcmd_func_t func, + grub_command_flags_t flags, + const char *summary, + const char *description, + const struct grub_arg_option *parser); -grub_extcmd_t grub_register_extcmd_prio (const char *name, - grub_extcmd_func_t func, - grub_command_flags_t flags, - const char *summary, - const char *description, - const struct grub_arg_option *parser, - int prio); +grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name, + grub_extcmd_func_t func, + grub_command_flags_t flags, + const char *summary, + const char *description, + const struct grub_arg_option *parser, + int prio); -void grub_unregister_extcmd (grub_extcmd_t cmd); +void EXPORT_FUNC(grub_unregister_extcmd) (grub_extcmd_t cmd); -grub_err_t -grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, - struct grub_script *script); +grub_err_t EXPORT_FUNC(grub_extcmd_dispatcher) (struct grub_command *cmd, + int argc, char **args, + struct grub_script *script); #endif /* ! GRUB_EXTCMD_HEADER */ diff --git a/include/grub/lib/arg.h b/include/grub/lib/arg.h index 3bab27781..b61f6f30e 100644 --- a/include/grub/lib/arg.h +++ b/include/grub/lib/arg.h @@ -72,7 +72,7 @@ struct grub_extcmd; int grub_arg_parse (struct grub_extcmd *cmd, int argc, char **argv, struct grub_arg_list *usr, char ***args, int *argnum); -void grub_arg_show_help (struct grub_extcmd *cmd); +void EXPORT_FUNC(grub_arg_show_help) (struct grub_extcmd *cmd); struct grub_arg_list* grub_arg_list_alloc (struct grub_extcmd *cmd, int argc, char *argv[]); From 17821956e7cc616e7e4e2d4a44106f4b6fde8588 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 30 Sep 2010 19:27:28 +0200 Subject: [PATCH 0293/1414] * util/grub-setup.c (main) [GRUB_MACHINE_IEEE1275]: Propagate argp usage. --- ChangeLog | 5 +++++ util/grub-setup.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 197158f50..85fcbb02c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-30 Vladimir Serbinenko + + * util/grub-setup.c (main) [GRUB_MACHINE_IEEE1275]: Propagate argp + usage. + 2010-09-30 Vladimir Serbinenko Put terminfo into core on ieee1275 and yeeloong (needed for console). diff --git a/util/grub-setup.c b/util/grub-setup.c index 953f0038b..920d867f2 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -838,10 +838,6 @@ main (int argc, char *argv[]) int must_embed = 0; struct arguments arguments; -#ifdef GRUB_MACHINE_IEEE1275 - force = 1; -#endif - set_program_name (argv[0]); grub_util_init_nls (); @@ -857,6 +853,10 @@ main (int argc, char *argv[]) exit(1); } +#ifdef GRUB_MACHINE_IEEE1275 + arguments.force = 1; +#endif + if (verbosity > 1) grub_env_set ("debug", "all"); From 74ccb5b5e2bb29a037bcdc4b3b1fbd89b26b57d8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 30 Sep 2010 20:59:20 +0200 Subject: [PATCH 0294/1414] * grub-core/script/execute.c (grub_script_execute_sourcecode): Set flags. --- ChangeLog | 5 +++++ grub-core/script/execute.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 85fcbb02c..b89679741 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-30 Vladimir Serbinenko + + * grub-core/script/execute.c (grub_script_execute_sourcecode): Set + flags. + 2010-09-30 Vladimir Serbinenko * util/grub-setup.c (main) [GRUB_MACHINE_IEEE1275]: Propagate argp diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 2cadb0e1b..d859a13bd 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -513,6 +513,7 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args) new_scope.argv.argc = argc; new_scope.argv.args = args; + new_scope.flags = 0; old_scope = scope; scope = &new_scope; From e6d983ba6d26a9f48707fad5e872375e81392887 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 30 Sep 2010 21:04:09 +0200 Subject: [PATCH 0295/1414] * grub-core/normal/term.c (read_terminal_list): Free in a right order. --- ChangeLog | 4 ++++ grub-core/normal/term.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b89679741..c223a869c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-30 Vladimir Serbinenko + + * grub-core/normal/term.c (read_terminal_list): Free in a right order. + 2010-09-30 Vladimir Serbinenko * grub-core/script/execute.c (grub_script_execute_sourcecode): Set diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index fe6240eb0..00721c447 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -376,8 +376,8 @@ read_terminal_list (const char *prefix) if (! cur->modname) { grub_errno = GRUB_ERR_NONE; - grub_free (cur); grub_free (cur->name); + grub_free (cur); continue; } cur->next = *target; From 6e3c515d5bf4480a38f0b6bb336f4e71a51af347 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 30 Sep 2010 21:07:51 +0200 Subject: [PATCH 0296/1414] * grub-core/gettext/gettext.c (grub_gettext_init_ext): Avoid using mo_file after freeing. --- ChangeLog | 5 +++++ grub-core/gettext/gettext.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c223a869c..0f0b65827 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-09-30 Vladimir Serbinenko + + * grub-core/gettext/gettext.c (grub_gettext_init_ext): Avoid using + mo_file after freeing. + 2010-09-30 Vladimir Serbinenko * grub-core/normal/term.c (read_terminal_list): Free in a right order. diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 2f94ac030..9ab4c3b8d 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -287,8 +287,10 @@ grub_gettext_init_ext (const char *lang) /* Will try adding .gz as well. */ if (fd_mo == NULL) { - grub_free (mo_file); + char *mo_file_old; + mo_file_old = mo_file; mo_file = grub_xasprintf ("%s.gz", mo_file); + grub_free (mo_file_old); if (!mo_file) return; fd_mo = grub_mofile_open (mo_file); From bf26bcc435756008603a7c5bf9a6d3d847a2b731 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 1 Oct 2010 16:24:43 +0200 Subject: [PATCH 0297/1414] * grub-core/loader/i386/linux.c (DEFAULT_VIDEO_MODE) [GRUB_MACHINE_EFI]: Set to "auto". --- ChangeLog | 5 +++++ grub-core/loader/i386/linux.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0f0b65827..3ed524a4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-01 Vladimir Serbinenko + + * grub-core/loader/i386/linux.c (DEFAULT_VIDEO_MODE) [GRUB_MACHINE_EFI]: + Set to "auto". + 2010-09-30 Vladimir Serbinenko * grub-core/gettext/gettext.c (grub_gettext_init_ext): Avoid using diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 4a6b7eafa..d7622dabd 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -41,7 +41,7 @@ #ifdef GRUB_MACHINE_EFI #include #define HAS_VGA_TEXT 0 -#define DEFAULT_VIDEO_MODE "800x600" +#define DEFAULT_VIDEO_MODE "auto" #elif defined (GRUB_MACHINE_IEEE1275) #include #define HAS_VGA_TEXT 0 From 441cfe65c0b6ea1015a457d61563a8a255725fc2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 1 Oct 2010 16:54:38 +0200 Subject: [PATCH 0298/1414] Clear out 0x80 color bit on EFI. Tested by: decoder Reported by: decoder and meta tech. * grub-core/term/efi/console.c (grub_console_standard_color): Removed. (grub_console_setcolorstate): Clear out 0x80 bit. Use GRUB_TERM_DEFAULT_STANDARD_COLOR. (grub_console_output): Use GRUB_TERM_DEFAULT_NORMAL_COLOR. Use GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR. --- ChangeLog | 12 ++++++++++++ grub-core/term/efi/console.c | 17 ++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ed524a4c..9b36f3426 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-10-01 Vladimir Serbinenko + + Clear out 0x80 color bit on EFI. + Tested by: decoder + Reported by: decoder and meta tech. + + * grub-core/term/efi/console.c (grub_console_standard_color): Removed. + (grub_console_setcolorstate): Clear out 0x80 bit. + Use GRUB_TERM_DEFAULT_STANDARD_COLOR. + (grub_console_output): Use GRUB_TERM_DEFAULT_NORMAL_COLOR. + Use GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR. + 2010-10-01 Vladimir Serbinenko * grub-core/loader/i386/linux.c (DEFAULT_VIDEO_MODE) [GRUB_MACHINE_EFI]: diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index 4872a9a3f..8fd89b093 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -24,10 +24,6 @@ #include #include -static const grub_uint8_t -grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW, - GRUB_EFI_BACKGROUND_BLACK); - static grub_uint32_t map_char (grub_uint32_t c) { @@ -208,13 +204,14 @@ grub_console_setcolorstate (struct grub_term_output *term, switch (state) { case GRUB_TERM_COLOR_STANDARD: - efi_call_2 (o->set_attributes, o, grub_console_standard_color); + efi_call_2 (o->set_attributes, o, GRUB_TERM_DEFAULT_STANDARD_COLOR + & 0x7f); break; case GRUB_TERM_COLOR_NORMAL: - efi_call_2 (o->set_attributes, o, term->normal_color); + efi_call_2 (o->set_attributes, o, term->normal_color & 0x7f); break; case GRUB_TERM_COLOR_HIGHLIGHT: - efi_call_2 (o->set_attributes, o, term->highlight_color); + efi_call_2 (o->set_attributes, o, term->highlight_color & 0x7f); break; default: break; @@ -266,10 +263,8 @@ static struct grub_term_output grub_console_term_output = .cls = grub_console_cls, .setcolorstate = grub_console_setcolorstate, .setcursor = grub_console_setcursor, - .normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY, - GRUB_EFI_BACKGROUND_BLACK), - .highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK, - GRUB_EFI_BACKGROUND_LIGHTGRAY), + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS }; From a94551944e90b5c0b6d8c1e6ef5061e2db834a64 Mon Sep 17 00:00:00 2001 From: starous Date: Sat, 2 Oct 2010 20:49:05 +0200 Subject: [PATCH 0299/1414] usbtrans.c - wrong max packet size for bulk transfer --- ChangeLog | 7 +++++++ grub-core/bus/usb/ohci.c | 2 +- grub-core/bus/usb/uhci.c | 11 ++++++----- grub-core/bus/usb/usbtrans.c | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b36f3426..326ce1a44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-10-02 Aleš Nesrsta + + * grub-core/bus/usb/ohci.c, grub-core/bus/usb/uhci.c: + Increased number of TDs. + * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_setup_readwrite): + Corrected endpoint maxpacket size. + 2010-10-01 Vladimir Serbinenko Clear out 0x80 color bit on EFI. diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index bf5aaa7c0..3c3ce4b89 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -150,7 +150,7 @@ typedef enum #define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16) #define GRUB_OHCI_CTRL_EDS 256 #define GRUB_OHCI_BULK_EDS 510 -#define GRUB_OHCI_TDS 256 +#define GRUB_OHCI_TDS 640 #define GRUB_OHCI_ED_ADDR_MASK 0x7ff diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 711d87d86..d082beac4 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -29,6 +29,7 @@ #define GRUB_UHCI_IOMASK (0x7FF << 5) #define N_QH 256 +#define N_TD 640 typedef enum { @@ -105,7 +106,7 @@ struct grub_uhci /* N_QH Queue Heads. */ grub_uhci_qh_t qh; - /* 256 Transfer Descriptors. */ + /* N_TD Transfer Descriptors. */ grub_uhci_td_t td; /* Free Transfer Descriptors. */ @@ -213,7 +214,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, /* The QH pointer of UHCI is only 32 bits, make sure this code works on on 64 bits architectures. */ - u->qh = (grub_uhci_qh_t) grub_memalign (4096, 4096); + u->qh = (grub_uhci_qh_t) grub_memalign (4096, sizeof(struct grub_uhci_qh)*N_QH); if (! u->qh) goto fail; @@ -227,7 +228,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, /* The TD pointer of UHCI is only 32 bits, make sure this code works on on 64 bits architectures. */ - u->td = (grub_uhci_td_t) grub_memalign (4096, 4096*2); + u->td = (grub_uhci_td_t) grub_memalign (4096, sizeof(struct grub_uhci_td)*N_TD); if (! u->td) goto fail; @@ -244,9 +245,9 @@ grub_uhci_pci_iter (grub_pci_device_t dev, /* Link all Transfer Descriptors in a list of available Transfer Descriptors. */ - for (i = 0; i < 256; i++) + for (i = 0; i < N_TD; i++) u->td[i].linkptr = (grub_uint32_t) (grub_addr_t) &u->td[i + 1]; - u->td[255 - 1].linkptr = 0; + u->td[N_TD - 2].linkptr = 0; u->tdfree = u->td; /* Make sure UHCI is disabled! */ diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c index afd2eb0a5..ebb8a2eb6 100644 --- a/grub-core/bus/usb/usbtrans.c +++ b/grub-core/bus/usb/usbtrans.c @@ -228,7 +228,7 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, if (dev->initialized) { struct grub_usb_desc_endp *endpdesc; - endpdesc = grub_usb_get_endpdescriptor (dev, 0); + endpdesc = grub_usb_get_endpdescriptor (dev, endpoint); if (endpdesc) max = endpdesc->maxpacket; From 3ef068df41e64e3922e9adab0653325d44357dcc Mon Sep 17 00:00:00 2001 From: starous Date: Sat, 2 Oct 2010 20:55:10 +0200 Subject: [PATCH 0300/1414] SCSI - cache ID bug --- ChangeLog | 5 +++++ include/grub/scsi.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 326ce1a44..cc3c87445 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-02 Aleš Nesrsta + + * include/grub/scsi.h: + SCSI - cache ID bug + 2010-10-02 Aleš Nesrsta * grub-core/bus/usb/ohci.c, grub-core/bus/usb/uhci.c: diff --git a/include/grub/scsi.h b/include/grub/scsi.h index b3c60f3e8..b30d317c7 100644 --- a/include/grub/scsi.h +++ b/include/grub/scsi.h @@ -40,7 +40,7 @@ static inline grub_uint32_t grub_make_scsi_id (int subsystem, int bus, int lun) { return (subsystem << GRUB_SCSI_ID_SUBSYSTEM_SHIFT) - | (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_BUS_SHIFT); + | (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_LUN_SHIFT); } struct grub_scsi_dev From c7980ad945126e44fb1adce9a6f2624c3aef23ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Oct 2010 19:42:51 +0200 Subject: [PATCH 0301/1414] Correct 2 last Changelog entries --- ChangeLog | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc3c87445..61810897b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,15 @@ 2010-10-02 Aleš Nesrsta - * include/grub/scsi.h: - SCSI - cache ID bug + * include/grub/scsi.h (grub_make_scsi_id): Fix incorrect usgae of + GRUB_SCSI_ID_BUS_SHIFT instead of GRUB_SCSI_ID_LUN_SHIFT. 2010-10-02 Aleš Nesrsta - * grub-core/bus/usb/ohci.c, grub-core/bus/usb/uhci.c: - Increased number of TDs. + * grub-core/bus/usb/ohci.c (GRUB_OHCI_TDS): Increase. + * grub-core/bus/usb/uhci.c (N_TD): New definition. All previous implicit + users updated. * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_setup_readwrite): - Corrected endpoint maxpacket size. + Use right endpoint when querying descriptor. 2010-10-01 Vladimir Serbinenko From 74baff844e41ab6eb8391ba2d02194901e0146a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Oct 2010 19:46:20 +0200 Subject: [PATCH 0302/1414] * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Fix incorrect handling of special keys. --- ChangeLog | 5 +++++ grub-core/kern/i386/pc/startup.S | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61810897b..09b5d5c29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-09 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Fix incorrect + handling of special keys. + 2010-10-02 Aleš Nesrsta * include/grub/scsi.h (grub_make_scsi_id): Fix incorrect usgae of diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index c4abc31b8..31bd86c65 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -615,6 +615,7 @@ LOCAL(bypass_table_end): FUNCTION(grub_console_getkey) pushl %ebp + pushl %edi call prot_to_real .code16 @@ -644,15 +645,16 @@ FUNCTION(grub_console_getkey) jz 1f andl %edx, %eax - cmp %eax, 0x20 + cmpl $0x20, %eax ja 2f movl %edx, %eax - leal LOCAL(bypass_table), %esi + leal LOCAL(bypass_table), %edi movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx - repne cmpsw + repne scasw jz 3f - addl $('a' - 1 | GRUB_TERM_CTRL), %eax + andl $0xff, %eax + addl $(('a' - 1) | GRUB_TERM_CTRL), %eax jmp 2f 3: andl $0xff, %eax @@ -661,7 +663,8 @@ FUNCTION(grub_console_getkey) 1: movl %edx, %eax shrl $8, %eax orl $GRUB_TERM_EXTENDED, %eax -2: +2: + popl %edi popl %ebp ret From c5dc16905aea5bce096c5a2061c236712b6e4686 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Oct 2010 19:57:01 +0200 Subject: [PATCH 0303/1414] Make enable of disk cache statistics code configurable. * configure.ac: --enable-cache-stats added. * config.h.in (DISK_CACHE_STATS): New define. * grub-core/Makefile.core.def (cacheinfo): New command. * include/grub/disk.h(grub_disk_cache_get_performance): New function. * grub-core/commands/cacheinfo.c: New file. * grub-core/commands/minicmd.c (grub_rescue_cmd_info): Updated and moved to cacheinfo.c. * grub-core/kern/disk.c: Use DISK_CACHE_STATS to disable disk cache debug code. * include/grub/disk.h: Likewise. --- ChangeLog | 15 +++++++++ config.h.in | 2 ++ configure.ac | 17 ++++++++++ grub-core/Makefile.core.def | 6 ++++ grub-core/commands/cacheinfo.c | 58 ++++++++++++++++++++++++++++++++++ grub-core/commands/minicmd.c | 20 ------------ grub-core/kern/disk.c | 6 ++-- include/grub/disk.h | 5 +++ 8 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 grub-core/commands/cacheinfo.c diff --git a/ChangeLog b/ChangeLog index cc3c87445..6d54b6301 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-10-05 Szymon Janc + + Make enable of disk cache statistics code configurable. + + * configure.ac: --enable-cache-stats added. + * config.h.in (DISK_CACHE_STATS): New define. + * grub-core/Makefile.core.def (cacheinfo): New command. + * include/grub/disk.h(grub_disk_cache_get_performance): New function. + * grub-core/commands/cacheinfo.c: New file. + * grub-core/commands/minicmd.c (grub_rescue_cmd_info): Updated and + moved to cacheinfo.c. + * grub-core/kern/disk.c: Use DISK_CACHE_STATS to disable disk cache + debug code. + * include/grub/disk.h: Likewise. + 2010-10-02 Aleš Nesrsta * include/grub/scsi.h: diff --git a/config.h.in b/config.h.in index 6d7d95dec..cfe6a94b2 100644 --- a/config.h.in +++ b/config.h.in @@ -32,6 +32,8 @@ #define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@ /* Define to 1 if GCC generates calls to __register_frame_info(). */ #define NEED_REGISTER_FRAME_INFO @NEED_REGISTER_FRAME_INFO@ +/* Define to 1 to enable disk cache statistics. */ +#define DISK_CACHE_STATS @DISK_CACHE_STATS@ #if defined(__i386__) #define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) diff --git a/configure.ac b/configure.ac index 66d4a6877..b3b5652d1 100644 --- a/configure.ac +++ b/configure.ac @@ -669,6 +669,17 @@ AC_ARG_ENABLE([mm-debug], [AC_DEFINE([MM_DEBUG], [1], [Define to 1 if you enable memory manager debugging.])]) +AC_ARG_ENABLE([cache-stats], + AS_HELP_STRING([--enable-cache-stats], + [enable disk cache statistics collection])]) + +if test x$enable_cache_stats = xyes; then + DISK_CACHE_STATS=1 +else + DISK_CACHE_STATS=0 +fi +AC_SUBST([DISK_CACHE_STATS]) + AC_ARG_ENABLE([grub-emu-usb], [AS_HELP_STRING([--enable-grub-emu-usb], [build and install the `grub-emu' debugging utility with USB support (default=guessed)])]) @@ -922,6 +933,7 @@ AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) +AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) @@ -983,6 +995,11 @@ echo With memory debugging: Yes else echo With memory debugging: No fi +if [ x"$enable_cache_stats" = xyes ]; then +echo With disk cache statistics: Yes +else +echo With disk cache statistics: No +fi if [ x"$efiemu_excuse" = x ]; then echo efiemu runtime: Yes else diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8845c26ea..51ae522a6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1502,3 +1502,9 @@ module = { common = commands/keylayouts.c; enable = videomodules; }; + +module = { + name = cacheinfo; + common = commands/cacheinfo.c; + condition = COND_ENABLE_CACHE_STATS; +}; diff --git a/grub-core/commands/cacheinfo.c b/grub-core/commands/cacheinfo.c new file mode 100644 index 000000000..771763c9c --- /dev/null +++ b/grub-core/commands/cacheinfo.c @@ -0,0 +1,58 @@ +/* cacheinfo.c - disk cache statistics */ +/* + * GRUB -- GRand Unified Bootloader + * 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 + * 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 + +static grub_err_t +grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + unsigned long hits, misses; + + grub_disk_cache_get_performance (&hits, &misses); + grub_printf ("Disk cache: hits = %lu, misses = %lu ", hits, misses); + if (hits + misses) + { + unsigned long ratio = hits * 10000 / (hits + misses); + grub_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100); + } + else + grub_printf ("(N/A)\n"); + + return 0; +} + +static grub_command_t cmd_cacheinfo; + +GRUB_MOD_INIT(cacheinfo) +{ + cmd_cacheinfo = + grub_register_command ("cacheinfo", grub_rescue_cmd_info, + 0, N_("Get disk cache info.")); +} + +GRUB_MOD_FINI(cacheinfo) +{ + grub_unregister_command (cmd_cacheinfo); +} diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c index 5cf109fde..5c90e8ac5 100644 --- a/grub-core/commands/minicmd.c +++ b/grub-core/commands/minicmd.c @@ -88,26 +88,6 @@ grub_mini_cmd_help (struct grub_command *cmd __attribute__ ((unused)), return 0; } -#if 0 -static void -grub_rescue_cmd_info (void) -{ - extern void grub_disk_cache_get_performance (unsigned long *, - unsigned long *); - unsigned long hits, misses; - - grub_disk_cache_get_performance (&hits, &misses); - grub_printf ("Disk cache: hits = %u, misses = %u ", hits, misses); - if (hits + misses) - { - unsigned long ratio = hits * 10000 / (hits + misses); - grub_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100); - } - else - grub_printf ("(N/A)\n"); -} -#endif - /* dump ADDRESS [SIZE] */ static grub_err_t grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)), diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 807ee4277..2d50ea60c 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -50,7 +50,7 @@ grub_err_t (* grub_disk_ata_pass_through) (grub_disk_t, struct grub_disk_ata_pass_through_parms *); -#if 0 +#if DISK_CACHE_STATS static unsigned long grub_disk_cache_hits; static unsigned long grub_disk_cache_misses; @@ -123,13 +123,13 @@ grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id, && cache->sector == sector) { cache->lock = 1; -#if 0 +#if DISK_CACHE_STATS grub_disk_cache_hits++; #endif return cache->data; } -#if 0 +#if DISK_CACHE_STATS grub_disk_cache_misses++; #endif diff --git a/include/grub/disk.h b/include/grub/disk.h index 9c5653e00..783640d19 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -160,6 +160,11 @@ grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk, grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk); +#if DISK_CACHE_STATS +void +EXPORT_FUNC(grub_disk_cache_get_performance) (unsigned long *hits, unsigned long *misses); +#endif + extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void); extern int EXPORT_VAR(grub_disk_firmware_is_tainted); From 5d49b1e69c82de6a07195dc39e7e601feeedd44d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Oct 2010 22:09:07 +0200 Subject: [PATCH 0304/1414] Move last changelog entry from ChangeLog to ChangeLog.cacheinfo. --- ChangeLog | 15 --------------- ChangeLog.cacheinfo | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 ChangeLog.cacheinfo diff --git a/ChangeLog b/ChangeLog index 6d54b6301..cc3c87445 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,18 +1,3 @@ -2010-10-05 Szymon Janc - - Make enable of disk cache statistics code configurable. - - * configure.ac: --enable-cache-stats added. - * config.h.in (DISK_CACHE_STATS): New define. - * grub-core/Makefile.core.def (cacheinfo): New command. - * include/grub/disk.h(grub_disk_cache_get_performance): New function. - * grub-core/commands/cacheinfo.c: New file. - * grub-core/commands/minicmd.c (grub_rescue_cmd_info): Updated and - moved to cacheinfo.c. - * grub-core/kern/disk.c: Use DISK_CACHE_STATS to disable disk cache - debug code. - * include/grub/disk.h: Likewise. - 2010-10-02 Aleš Nesrsta * include/grub/scsi.h: diff --git a/ChangeLog.cacheinfo b/ChangeLog.cacheinfo new file mode 100644 index 000000000..a26271cca --- /dev/null +++ b/ChangeLog.cacheinfo @@ -0,0 +1,14 @@ +2010-10-05 Szymon Janc + + Make enable of disk cache statistics code configurable. + + * configure.ac: --enable-cache-stats added. + * config.h.in (DISK_CACHE_STATS): New define. + * grub-core/Makefile.core.def (cacheinfo): New command. + * include/grub/disk.h(grub_disk_cache_get_performance): New function. + * grub-core/commands/cacheinfo.c: New file. + * grub-core/commands/minicmd.c (grub_rescue_cmd_info): Updated and + moved to cacheinfo.c. + * grub-core/kern/disk.c: Use DISK_CACHE_STATS to disable disk cache + debug code. + * include/grub/disk.h: Likewise. From 20c6bb7e9ed66d6d0e7b63999eec5b804d48983a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Oct 2010 23:27:27 +0200 Subject: [PATCH 0305/1414] Correctly distinguish mdraid flavours. * grub-core/disk/raid.c (grub_raid_getname) [GRUB_UTIL]: New function. (insert_array): New argument raid. * include/grub/disk.h (grub_disk_dev) [GRUB_UTIL]: New member raidname. * include/grub/raid.h (grub_raid_array) [GRUB_UTIL]: New member driver. * util/grub-probe.c (probe): PRint raidname instead of plainly "mdraid". --- ChangeLog | 10 ++++++++++ grub-core/disk/raid.c | 18 ++++++++++++++++-- include/grub/disk.h | 1 + include/grub/raid.h | 4 ++++ util/grub-probe.c | 3 ++- 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 09b5d5c29..79030343b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-10-08 Vladimir Serbinenko + + Correctly distinguish mdraid flavours. + + * grub-core/disk/raid.c (grub_raid_getname) [GRUB_UTIL]: New function. + (insert_array): New argument raid. + * include/grub/disk.h (grub_disk_dev) [GRUB_UTIL]: New member raidname. + * include/grub/raid.h (grub_raid_array) [GRUB_UTIL]: New member driver. + * util/grub-probe.c (probe): PRint raidname instead of plainly "mdraid". + 2010-10-09 Vladimir Serbinenko * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Fix incorrect diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 2fd6aa9de..c7c641ebd 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -107,6 +107,14 @@ grub_raid_memberlist (grub_disk_t disk) return list; } + +static const char * +grub_raid_getname (struct grub_disk *disk) +{ + struct grub_raid_array *array = disk->data; + + return array->driver->name; +} #endif static grub_err_t @@ -476,7 +484,8 @@ grub_raid_write (grub_disk_t disk __attribute ((unused)), static grub_err_t insert_array (grub_disk_t disk, struct grub_raid_array *new_array, - grub_disk_addr_t start_sector, const char *scanner_name) + grub_disk_addr_t start_sector, const char *scanner_name, + grub_raid_t raid __attribute__ ((unused))) { struct grub_raid_array *array = 0, *p; @@ -524,6 +533,9 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, *array = *new_array; array->nr_devs = 0; +#ifdef GRUB_UTIL + array->driver = raid; +#endif grub_memset (&array->device, 0, sizeof (array->device)); grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); @@ -662,7 +674,8 @@ grub_raid_register (grub_raid_t raid) if ((disk->total_sectors != GRUB_ULONG_MAX) && (! grub_raid_list->detect (disk, &array, &start_sector)) && - (! insert_array (disk, &array, start_sector, grub_raid_list->name))) + (! insert_array (disk, &array, start_sector, grub_raid_list->name, + grub_raid_list))) return 0; /* This error usually means it's not raid, no need to display @@ -706,6 +719,7 @@ static struct grub_disk_dev grub_raid_dev = .write = grub_raid_write, #ifdef GRUB_UTIL .memberlist = grub_raid_memberlist, + .raidname = grub_raid_getname, #endif .next = 0 }; diff --git a/include/grub/disk.h b/include/grub/disk.h index 9c5653e00..66db1149a 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -78,6 +78,7 @@ struct grub_disk_dev #ifdef GRUB_UTIL struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk); + const char * (*raidname) (struct grub_disk *disk); #endif /* The next disk device. */ diff --git a/include/grub/raid.h b/include/grub/raid.h index 711a7f79c..b7e18b567 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -54,6 +54,10 @@ struct grub_raid_array grub_disk_addr_t start_sector[GRUB_RAID_MAX_DEVICES]; /* Start of each device, in 512 byte sectors. */ struct grub_raid_array *next; + +#ifdef GRUB_UTIL + struct grub_raid *driver; +#endif }; struct grub_raid diff --git a/util/grub-probe.c b/util/grub-probe.c index b92d301f0..1d00a7db3 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -175,7 +175,8 @@ probe (const char *path, char *device_name) printf ("raid5rec "); if (is_raid6) printf ("raid6rec "); - printf ("mdraid "); + if (dev->disk->dev->raidname) + printf ("%s ", dev->disk->dev->raidname (dev->disk)); } if (is_lvm) From 219b35646a0c71fe95d8997a79c474b1ab96bf87 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 12 Oct 2010 14:47:04 +0200 Subject: [PATCH 0306/1414] 2010-10-12 Robert Millan * util/grub-mkconfig.in: Merge `GRUB_DISABLE_LINUX_RECOVERY' and `GRUB_DISABLE_NETBSD_RECOVERY' into a single `GRUB_DISABLE_RECOVERY' variable. All references updated. * util/grub.d/10_kfreebsd.in: Support recovery boot entries. --- ChangeLog | 8 ++++++++ docs/grub.texi | 10 +++------- util/grub-mkconfig.in | 3 +-- util/grub.d/10_kfreebsd.in | 17 ++++++++++++----- util/grub.d/10_linux.in | 2 +- util/grub.d/10_netbsd.in | 2 +- util/grub.d/20_linux_xen.in | 2 +- 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79030343b..b0b3f83b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-10-12 Robert Millan + + * util/grub-mkconfig.in: Merge `GRUB_DISABLE_LINUX_RECOVERY' and + `GRUB_DISABLE_NETBSD_RECOVERY' into a single `GRUB_DISABLE_RECOVERY' + variable. All references updated. + + * util/grub.d/10_kfreebsd.in: Support recovery boot entries. + 2010-10-08 Vladimir Serbinenko Correctly distinguish mdraid flavours. diff --git a/docs/grub.texi b/docs/grub.texi index 3a72bbacb..4995b1df7 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1073,7 +1073,7 @@ A command to configure the serial port when using the serial console. Command-line arguments to add to menu entries for the Linux kernel. @item GRUB_CMDLINE_LINUX_DEFAULT -Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set to @samp{true}, two menu +Unless @samp{GRUB_DISABLE_RECOVERY} is set to @samp{true}, two menu entries will be generated for each Linux kernel: one default entry and one entry for recovery mode. This option lists command-line arguments to add only to the default menu entry, after those listed in @@ -1096,13 +1096,9 @@ the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is usually more reliable, but in some cases it may not be appropriate. To disable the use of UUIDs, set this option to @samp{true}. -@item GRUB_DISABLE_LINUX_RECOVERY +@item GRUB_DISABLE_RECOVERY If this option is set to @samp{true}, disable the generation of recovery -mode menu entries for Linux. - -@item GRUB_DISABLE_NETBSD_RECOVERY -If this option is set to @samp{true}, disable the generation of recovery -mode menu entries for NetBSD. +mode menu entries. @item GRUB_VIDEO_BACKEND If graphical video support is required, either because the @samp{gfxterm} diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 4a06e19bc..b59911cd0 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -257,8 +257,7 @@ export GRUB_DEFAULT \ GRUB_TERMINAL_OUTPUT \ GRUB_SERIAL_COMMAND \ GRUB_DISABLE_LINUX_UUID \ - GRUB_DISABLE_LINUX_RECOVERY \ - GRUB_DISABLE_NETBSD_RECOVERY \ + GRUB_DISABLE_RECOVERY \ GRUB_VIDEO_BACKEND \ GRUB_GFXMODE \ GRUB_BACKGROUND \ diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 591fbc4b1..4d71b5a63 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -68,9 +68,13 @@ kfreebsd_entry () { os="$1" version="$2" - recovery="$3" # not used yet - args="$4" # not used yet - title="$(gettext_quoted "%s, with kFreeBSD %s")" + recovery="$3" + args="$4" + if ${recovery} ; then + title="$(gettext_quoted "%s, with kFreeBSD %s (recovery mode)")" + else + title="$(gettext_quoted "%s, with kFreeBSD %s")" + fi printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then @@ -80,7 +84,7 @@ kfreebsd_entry () printf '%s\n' "${prepare_boot_cache}" cat << EOF echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})' - kfreebsd ${rel_dirname}/${basename} + kfreebsd ${rel_dirname}/${basename} ${args} EOF if test -n "${devices}" ; then @@ -172,7 +176,10 @@ while [ "x$list" != "x" ] ; do module_dir_rel=$(make_system_path_relative_to_its_root $module_dir) fi - kfreebsd_entry "${OS}" "${version}" + kfreebsd_entry "${OS}" "${version}" false + if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then + kfreebsd_entry "${OS}" "${version}" true "-s" + fi list=`echo $list | tr ' ' '\n' | grep -vx $kfreebsd | tr '\n' ' '` done diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 14b85c7f1..6cb6f0be7 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -136,7 +136,7 @@ while [ "x$list" != "x" ] ; do linux_entry "${OS}" "${version}" false \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" - if [ "x${GRUB_DISABLE_LINUX_RECOVERY}" != "xtrue" ]; then + if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" true \ "single ${GRUB_CMDLINE_LINUX}" fi diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index 1a8c4eb36..13f9d923a 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -80,7 +80,7 @@ for k in $(ls -t /netbsd*) ; do echo "Found NetBSD kernel: $k" >&2 netbsd_entry "knetbsd" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}" netbsd_entry "multiboot" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}" - if [ "x${GRUB_DISABLE_NETBSD_RECOVERY}" != "xtrue" ]; then + if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then netbsd_entry "knetbsd" "$k" true "-s" netbsd_entry "multiboot" "$k" true "-s" fi diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 5333d44ec..d5833070d 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -133,7 +133,7 @@ while [ "x${xen_list}" != "x" ] ; do linux_entry "${OS}" "${version}" "${xen_version}" false \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" - if [ "x${GRUB_DISABLE_LINUX_RECOVERY}" != "xtrue" ]; then + if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" "${xen_version}" true \ "single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" fi From d87c681fd4e2a60ead314b35f881e61bad7664c6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 14 Oct 2010 15:35:55 +0200 Subject: [PATCH 0307/1414] * grub-core/kern/i386/pc/startup.S (bypass_table): Use 0x1b explicitly rather than 0x1b. (grub_console_getkey): Use correct jae opcode rather than ja. --- ChangeLog | 6 ++++++ grub-core/kern/i386/pc/startup.S | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0b3f83b0..a0ae8b2a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-10-14 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S (bypass_table): Use 0x1b explicitly + rather than 0x1b. + (grub_console_getkey): Use correct jae opcode rather than ja. + 2010-10-12 Robert Millan * util/grub-mkconfig.in: Merge `GRUB_DISABLE_LINUX_RECOVERY' and diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 31bd86c65..e03fc8301 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -591,7 +591,7 @@ FUNCTION(grub_console_putchar) LOCAL(bypass_table): - .word 0x0100 | '\e',0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r' + .word 0x011b, 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r' .word 0x1c00 | '\n' LOCAL(bypass_table_end): @@ -646,7 +646,7 @@ FUNCTION(grub_console_getkey) andl %edx, %eax cmpl $0x20, %eax - ja 2f + jae 2f movl %edx, %eax leal LOCAL(bypass_table), %edi movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx From d0f4c1ea0f281c1ac081f63da54270030668f37d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 14 Oct 2010 15:44:04 +0200 Subject: [PATCH 0308/1414] * grub-core/efiemu/main.c (grub_efiemu_prepare): Handle errors from grub_efiemu_autocore. --- ChangeLog | 5 +++++ grub-core/efiemu/main.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a0ae8b2a0..5553a991c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-14 Vladimir Serbinenko + + * grub-core/efiemu/main.c (grub_efiemu_prepare): Handle errors from + grub_efiemu_autocore. + 2010-10-14 Vladimir Serbinenko * grub-core/kern/i386/pc/startup.S (bypass_table): Use 0x1b explicitly diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index ee78afe7d..da813b00d 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -266,11 +266,13 @@ grub_efiemu_prepare (void) if (prepared) return GRUB_ERR_NONE; + err = grub_efiemu_autocore (); + if (err) + return err; + grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n", 8 * grub_efiemu_sizeof_uintn_t ()); - err = grub_efiemu_autocore (); - /* Create NVRAM. */ grub_efiemu_pnvram (); From 2d5fed60d0845e5dc339f82659e9d2ebe4e00a86 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 15 Oct 2010 12:06:13 +0200 Subject: [PATCH 0309/1414] 2010-10-15 Robert Millan * util/grub.d/10_linux.in (list): Expand "vmlinu[zx]" instances to guarantee compressed ones are processed first. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5553a991c..a40deb780 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-15 Robert Millan + + * util/grub.d/10_linux.in (list): Expand "vmlinu[zx]" instances to + guarantee compressed ones are processed first. + 2010-10-14 Vladimir Serbinenko * grub-core/efiemu/main.c (grub_efiemu_prepare): Handle errors from diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 6cb6f0be7..e37bab21b 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -102,7 +102,7 @@ EOF EOF } -list=`for i in /boot/vmlinu[zx]-* /vmlinu[zx]-* ; do +list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` prepare_boot_cache= From 1eb01cd2761e472860874579a90c8657338db96f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 16 Oct 2010 02:30:14 +0200 Subject: [PATCH 0310/1414] 2010-10-16 Robert Millan * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Fix premature return when processing non-root ZFS filesystems. --- ChangeLog | 6 ++++++ grub-core/kern/emu/misc.c | 21 +++++---------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index a40deb780..ce683bbb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-10-16 Robert Millan + + * grub-core/kern/emu/misc.c + (grub_make_system_path_relative_to_its_root): Fix premature return + when processing non-root ZFS filesystems. + 2010-10-15 Robert Millan * util/grub.d/10_linux.in (list): Expand "vmlinu[zx]" instances to diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index d8db3be9d..cfc143bf9 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -406,21 +406,7 @@ grub_make_system_path_relative_to_its_root (const char *path) /* buf is another filesystem; we found it. */ if (st.st_dev != num) - { - /* offset == 0 means path given is the mount point. - This works around special-casing of "/" in Un*x. This function never - prints trailing slashes (so that its output can be appended a slash - unconditionally). Each slash in is considered a preceding slash, and - therefore the root directory is an empty string. */ - if (offset == 0) - { - free (buf); - free (buf2); - return xstrdup (""); - } - else - break; - } + break; offset = p - buf; /* offset == 1 means root directory. */ @@ -448,7 +434,10 @@ grub_make_system_path_relative_to_its_root (const char *path) } #endif - /* Remove trailing slashes, return empty string if root directory. */ + /* This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in it is considered a preceding slash, + and therefore the root directory is an empty string. */ len = strlen (buf3); while (len > 0 && buf3[len - 1] == '/') { From 5f8b440b6b24057b29f1692d275a409c18ee35a1 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 16 Oct 2010 02:34:10 +0200 Subject: [PATCH 0311/1414] Mention who reported this bug. --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index ce683bbb0..4b2a7a705 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Fix premature return when processing non-root ZFS filesystems. + Reported by Sergio Talens-Oliag. 2010-10-15 Robert Millan From 24977b4451d626057ac1bf5e813baddc045ec5ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 17:29:12 +0200 Subject: [PATCH 0312/1414] * grub-core/term/ns8250.c (do_real_config): Set port->broken to 0. (serial_hw_put): Wait based on real time rather than port reads. Don't roken ports. * include/grub/serial.h (grub_serial_port): New field broken. --- ChangeLog | 7 +++++++ grub-core/term/ns8250.c | 23 +++++++++++++++++++---- include/grub/serial.h | 6 +++++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b2a7a705..3f9c5a8cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-10-16 Vladimir Serbinenko + + * grub-core/term/ns8250.c (do_real_config): Set port->broken to 0. + (serial_hw_put): Wait based on real time rather than port reads. Don't + roken ports. + * include/grub/serial.h (grub_serial_port): New field broken. + 2010-10-16 Robert Millan * grub-core/kern/emu/misc.c diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c index 550ee6341..4be528df8 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef GRUB_MACHINE_PCBIOS #include @@ -90,6 +91,8 @@ do_real_config (struct grub_serial_port *port) if (port->configured) return; + port->broken = 0; + divisor = serial_get_divisor (port->config.speed); /* Turn off the interrupt. */ @@ -145,18 +148,30 @@ serial_hw_fetch (struct grub_serial_port *port) static void serial_hw_put (struct grub_serial_port *port, const int c) { - unsigned int timeout = 100000; + grub_uint64_t endtime; do_real_config (port); + if (port->broken > 5) + endtime = grub_get_time_ms (); + else if (port->broken > 1) + endtime = grub_get_time_ms () + 50; + else + endtime = grub_get_time_ms () + 200; /* Wait until the transmitter holding register is empty. */ while ((grub_inb (port->port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0) { - if (--timeout == 0) - /* There is something wrong. But what can I do? */ - return; + if (grub_get_time_ms () > endtime) + { + port->broken++; + /* There is something wrong. But what can I do? */ + return; + } } + if (port->broken) + port->broken--; + grub_outb (c, port->port + UART_TX); } diff --git a/include/grub/serial.h b/include/grub/serial.h index 652268b2e..9540bee64 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -72,7 +72,11 @@ struct grub_serial_port */ union { - grub_port_t port; + struct + { + grub_port_t port; + int broken; + }; struct { grub_usb_device_t usbdev; From 65f7ed7c9a61c2bcda5c9845db23b5c06c47a093 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 17:44:35 +0200 Subject: [PATCH 0313/1414] * grub-core/kern/efi/mm.c (BYTES_TO_PAGES): Round up instead of down. (grub_efi_mm_init): Take into account the memory map size increase. --- ChangeLog | 5 +++++ grub-core/kern/efi/mm.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3f9c5a8cd..7292b1d3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-16 Vladimir Serbinenko + + * grub-core/kern/efi/mm.c (BYTES_TO_PAGES): Round up instead of down. + (grub_efi_mm_init): Take into account the memory map size increase. + 2010-10-16 Vladimir Serbinenko * grub-core/term/ns8250.c (do_real_config): Set port->broken to 0. diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index c845d7df1..6205abf9b 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -25,7 +25,7 @@ #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 @@ -447,6 +447,9 @@ grub_efi_mm_init (void) ((grub_efi_physical_address_t) ((grub_addr_t) memory_map), 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + /* Freeing/allocating operations may increase memory map size. */ + map_size += desc_size * 32; + memory_map = grub_efi_allocate_pages (0, 2 * BYTES_TO_PAGES (map_size)); if (! memory_map) grub_fatal ("cannot allocate memory"); From fbfbeb394f45984974dcf97b11141b166b8325c1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 17:50:48 +0200 Subject: [PATCH 0314/1414] Remove dead grub_efi_mm_fini. * grub-core/kern/efi/mm.c (allocated_page): Removed. (ALLOCATED_PAGES_SIZE): Likewise. (MAX_ALLOCATED_PAGES): Likewise. (allocated_pages): Likewise. (grub_efi_allocate_pages): Don't record allocated pages. (grub_efi_free_pages): Likewise. (grub_efi_mm_init): Likewise. (grub_efi_mm_fini): Removed. --- ChangeLog | 13 ++++++++ grub-core/kern/efi/mm.c | 72 ----------------------------------------- 2 files changed, 13 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7292b1d3f..1d72f60f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-10-16 Vladimir Serbinenko + + Remove dead grub_efi_mm_fini. + + * grub-core/kern/efi/mm.c (allocated_page): Removed. + (ALLOCATED_PAGES_SIZE): Likewise. + (MAX_ALLOCATED_PAGES): Likewise. + (allocated_pages): Likewise. + (grub_efi_allocate_pages): Don't record allocated pages. + (grub_efi_free_pages): Likewise. + (grub_efi_mm_init): Likewise. + (grub_efi_mm_fini): Removed. + 2010-10-16 Vladimir Serbinenko * grub-core/kern/efi/mm.c (BYTES_TO_PAGES): Round up instead of down. diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index 6205abf9b..a715da076 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -32,19 +32,6 @@ a multiplier of 4KB. */ #define MEMORY_MAP_SIZE 0x3000 -/* Maintain the list of allocated pages. */ -struct allocated_page -{ - grub_efi_physical_address_t addr; - grub_efi_uint64_t num_pages; -}; - -#define ALLOCATED_PAGES_SIZE 0x1000 -#define MAX_ALLOCATED_PAGES \ - (ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page)) - -static struct allocated_page *allocated_pages = 0; - /* The minimum and maximum heap size for GRUB itself. */ #define MIN_HEAP_SIZE 0x100000 #define MAX_HEAP_SIZE (1600 * 0x100000) @@ -102,22 +89,6 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address, return 0; } - if (allocated_pages) - { - unsigned i; - - for (i = 0; i < MAX_ALLOCATED_PAGES; i++) - if (allocated_pages[i].addr == 0) - { - allocated_pages[i].addr = address; - allocated_pages[i].num_pages = pages; - break; - } - - if (i == MAX_ALLOCATED_PAGES) - grub_fatal ("too many page allocations"); - } - return (void *) ((grub_addr_t) address); } @@ -128,20 +99,6 @@ grub_efi_free_pages (grub_efi_physical_address_t address, { grub_efi_boot_services_t *b; - if (allocated_pages - && ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages) - != address)) - { - unsigned i; - - for (i = 0; i < MAX_ALLOCATED_PAGES; i++) - if (allocated_pages[i].addr == address) - { - allocated_pages[i].addr = 0; - break; - } - } - b = grub_efi_system_table->boot_services; efi_call_2 (b->free_pages, address, pages); } @@ -422,14 +379,6 @@ grub_efi_mm_init (void) grub_efi_uint64_t required_pages; int mm_status; - /* First of all, allocate pages to maintain allocations. */ - allocated_pages - = grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE)); - if (! allocated_pages) - 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)); @@ -502,24 +451,3 @@ grub_efi_mm_init (void) grub_efi_free_pages ((grub_addr_t) memory_map, 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); } - -void -grub_efi_mm_fini (void) -{ - if (allocated_pages) - { - unsigned i; - - for (i = 0; i < MAX_ALLOCATED_PAGES; i++) - { - struct allocated_page *p; - - 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) allocated_pages, - BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE)); - } -} From c32b51c9f97f392605b6b03593b412feaacfac1b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 19:06:55 +0200 Subject: [PATCH 0315/1414] Userspace ACPI parser debugging. * grub-core/commands/acpihalt.c [GRUB_DSDT_TEST]: Include userspace headers and add relevant defines. Don't include standard headers. (main) [GRUB_DSDT_TEST]: New function. * include/grub/acpi.h [GRUB_DSDT_TEST]: Don't include standard headers. Don't declare functions. --- ChangeLog | 10 ++++++ grub-core/commands/acpihalt.c | 61 +++++++++++++++++++++++++++++++++++ include/grub/acpi.h | 4 +++ 3 files changed, 75 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1d72f60f7..052fd1e27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-10-16 Vladimir Serbinenko + + Userspace ACPI parser debugging. + + * grub-core/commands/acpihalt.c [GRUB_DSDT_TEST]: Include userspace + headers and add relevant defines. Don't include standard headers. + (main) [GRUB_DSDT_TEST]: New function. + * include/grub/acpi.h [GRUB_DSDT_TEST]: Don't include standard headers. + Don't declare functions. + 2010-10-16 Vladimir Serbinenko Remove dead grub_efi_mm_fini. diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index a39635677..1e42f447f 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -16,9 +16,28 @@ * along with GRUB. If not, see . */ +#ifdef GRUB_DSDT_TEST +#include +#include +#include +#include +#include + +#define grub_dprintf(cond, args...) printf ( args ) +#define grub_printf printf +typedef uint64_t grub_uint64_t; +typedef uint32_t grub_uint32_t; +typedef uint16_t grub_uint16_t; +typedef uint8_t grub_uint8_t; + +#endif + #include + +#ifndef GRUB_DSDT_TEST #include #include +#endif static inline grub_uint32_t decode_length (const grub_uint8_t *ptr, int *numlen) @@ -208,6 +227,47 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) return sleep_type; } +#ifdef GRUB_DSDT_TEST +int +main (int argc, char **argv) +{ + FILE *f; + size_t len; + unsigned char *buf; + if (argc < 2) + printf ("Usage: %s FILE\n", argv[0]); + f = fopen (argv[1], "rb"); + if (!f) + { + printf ("Couldn't open file\n"); + return 1; + } + fseek (f, 0, SEEK_END); + len = ftell (f); + fseek (f, 0, SEEK_SET); + buf = malloc (len); + if (!buf) + { + printf ("Couldn't malloc buffer\n"); + fclose (f); + return 2; + } + if (fread (buf, 1, len, f) != len) + { + printf ("Read failed\n"); + free (buf); + fclose (f); + return 2; + } + + printf ("Sleep type = %d\n", get_sleep_type (buf, buf + len)); + free (buf); + fclose (f); + return 0; +} + +#else + void grub_acpi_halt (void) { @@ -264,3 +324,4 @@ grub_acpi_halt (void) grub_printf ("ACPI shutdown failed\n"); } +#endif diff --git a/include/grub/acpi.h b/include/grub/acpi.h index aebc8dd4f..c7ab82dad 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -19,8 +19,10 @@ #ifndef GRUB_ACPI_HEADER #define GRUB_ACPI_HEADER 1 +#ifndef GRUB_DSDT_TEST #include #include +#endif struct grub_acpi_rsdp_v10 { @@ -139,6 +141,7 @@ enum GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED = 1 }; +#ifndef GRUB_DSDT_TEST struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void); struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void); struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void); @@ -148,6 +151,7 @@ grub_uint8_t grub_byte_checksum (void *base, grub_size_t size); grub_err_t grub_acpi_create_ebda (void); void grub_acpi_halt (void); +#endif #define GRUB_ACPI_SLP_EN (1 << 13) #define GRUB_ACPI_SLP_TYP_OFFSET 10 From 6c8d300275faaaa4a0e3c48fa9d45dd177528942 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 19:12:18 +0200 Subject: [PATCH 0316/1414] * grub-core/commands/acpihalt.c (get_sleep_type): Accept \_S5_ as synonym to _S5_. Needed for some DSDTs. --- ChangeLog | 5 +++++ grub-core/commands/acpihalt.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 052fd1e27..34a092ca2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-16 Vladimir Serbinenko + + * grub-core/commands/acpihalt.c (get_sleep_type): Accept \_S5_ as + synonym to _S5_. Needed for some DSDTs. + 2010-10-16 Vladimir Serbinenko Userspace ACPI parser debugging. diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 1e42f447f..d28a74323 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -175,11 +175,12 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) break; case GRUB_ACPI_OPCODE_NAME: ptr++; - if (memcmp (ptr, "_S5_", 4) == 0) + if (memcmp (ptr, "_S5_", 4) == 0 || memcmp (ptr, "\\_S5_", 4) == 0) { int ll; grub_uint8_t *ptr2 = ptr; - ptr2 += 4; + grub_dprintf ("acpi", "S5 found\n"); + ptr2 += skip_name_string (ptr, end); if (*ptr2 != 0x12) { grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2); From e19b016b303596747027ac4ddb41caef11fc8fbf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 20:01:30 +0200 Subject: [PATCH 0317/1414] * grub-core/commands/acpihalt.c (skip_ext_op): Skip index field op. * include/grub/acpi.h (GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP): New enum value. --- ChangeLog | 6 ++++++ grub-core/commands/acpihalt.c | 1 + include/grub/acpi.h | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 34a092ca2..1c21262b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-10-16 Vladimir Serbinenko + + * grub-core/commands/acpihalt.c (skip_ext_op): Skip index field op. + * include/grub/acpi.h (GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP): New + enum value. + 2010-10-16 Vladimir Serbinenko * grub-core/commands/acpihalt.c (get_sleep_type): Accept \_S5_ as diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index d28a74323..2789e2eca 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -142,6 +142,7 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) return 0; break; case GRUB_ACPI_EXTOPCODE_FIELD_OP: + case GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP: ptr++; ptr += decode_length (ptr, 0); break; diff --git a/include/grub/acpi.h b/include/grub/acpi.h index c7ab82dad..c843a0621 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -169,7 +169,8 @@ enum { GRUB_ACPI_EXTOPCODE_MUTEX = 0x01, GRUB_ACPI_EXTOPCODE_OPERATION_REGION = 0x80, - GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81 + GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81, + GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP = 0x86, }; #endif /* ! GRUB_ACPI_HEADER */ From 6bdda8f87750cd55d511d433e3299100d34102e4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 16 Oct 2010 22:16:52 +0200 Subject: [PATCH 0318/1414] * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): Set-but-not-used variable ifdef'ed. * grub-core/lib/legacy_parse.c (grub_legacy_parse): Likewise. * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Set-but-not-used variable removed. * grub-core/disk/lvm.c (grub_lvm_scan_device): Likewise. * grub-core/fs/jfs.c (grub_jfs_find_file): Likewise. * grub-core/fs/minix.c (grub_minix_dir): Likewise. * grub-core/fs/sfs.c (grub_sfs_read_extent): Likewise. * grub-core/fs/ufs.c (grub_ufs_dir): Likewise. * grub-core/gfxmenu/gui_list.c (grub_gui_list_new): Likewise. * grub-core/gfxmenu/view.c (redraw_menu_visit): Likewise. * grub-core/gfxmenu/widget-box.c (draw): Likewise. * grub-core/lib/relocator.c (malloc_in_range): Likewise. * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): Likewise. * grub-core/loader/i386/bsd_pagetable.c (fill_bsd64_pagetable): Likewise. --- ChangeLog | 20 ++++++++++++++++++++ grub-core/bus/usb/ohci.c | 2 -- grub-core/commands/legacycfg.c | 4 ++++ grub-core/disk/lvm.c | 4 +--- grub-core/fs/jfs.c | 3 --- grub-core/fs/minix.c | 3 --- grub-core/fs/sfs.c | 3 --- grub-core/fs/ufs.c | 3 --- grub-core/gfxmenu/gui_list.c | 2 -- grub-core/gfxmenu/view.c | 2 -- grub-core/gfxmenu/widget-box.c | 12 ------------ grub-core/lib/legacy_parse.c | 16 ++++++++++------ grub-core/lib/relocator.c | 10 ++-------- grub-core/loader/i386/bsdXX.c | 4 ---- grub-core/loader/i386/bsd_pagetable.c | 3 +-- 15 files changed, 38 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c21262b9..4a06eaefa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-10-16 Szymon Janc + + * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): + Set-but-not-used variable ifdef'ed. + * grub-core/lib/legacy_parse.c (grub_legacy_parse): Likewise. + * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Set-but-not-used + variable removed. + * grub-core/disk/lvm.c (grub_lvm_scan_device): Likewise. + * grub-core/fs/jfs.c (grub_jfs_find_file): Likewise. + * grub-core/fs/minix.c (grub_minix_dir): Likewise. + * grub-core/fs/sfs.c (grub_sfs_read_extent): Likewise. + * grub-core/fs/ufs.c (grub_ufs_dir): Likewise. + * grub-core/gfxmenu/gui_list.c (grub_gui_list_new): Likewise. + * grub-core/gfxmenu/view.c (redraw_menu_visit): Likewise. + * grub-core/gfxmenu/widget-box.c (draw): Likewise. + * grub-core/lib/relocator.c (malloc_in_range): Likewise. + * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): Likewise. + * grub-core/loader/i386/bsd_pagetable.c (fill_bsd64_pagetable): + Likewise. + 2010-10-16 Vladimir Serbinenko * grub-core/commands/acpihalt.c (skip_ext_op): Skip index field op. diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 3c3ce4b89..8adaee6e0 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -220,7 +220,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_address_t addr; struct grub_ohci *o; grub_uint32_t revision; - int cs5536; int j; /* Determine IO base address. */ @@ -230,7 +229,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev, { grub_uint64_t basereg; - cs5536 = 1; basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) { diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 1b0e968c5..d5441db06 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -225,7 +225,9 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), int argc, char **args) { int i; +#ifdef TODO int no_mem_option = 0; +#endif struct grub_command *cmd; char **cutargs; int cutargc; @@ -235,7 +237,9 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), /* FIXME: really support this. */ if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0) { +#ifdef TODO no_mem_option = 1; +#endif argc--; args++; continue; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 94cf9a1aa..d2d2f620b 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -259,7 +259,7 @@ grub_lvm_scan_device (const char *name) { grub_err_t err; grub_disk_t disk; - grub_uint64_t da_offset, da_size, mda_offset, mda_size; + grub_uint64_t mda_offset, mda_size; char buf[GRUB_LVM_LABEL_SIZE]; char vg_id[GRUB_LVM_ID_STRLEN+1]; char pv_id[GRUB_LVM_ID_STRLEN+1]; @@ -319,8 +319,6 @@ grub_lvm_scan_device (const char *name) pv_id[j] = '\0'; dlocn = pvh->disk_areas_xl; - da_offset = grub_le_to_cpu64 (dlocn->offset); - da_size = grub_le_to_cpu64 (dlocn->size); dlocn++; /* Is it possible to have multiple data/metadata areas? I haven't diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index c9839a22f..76ef2e540 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -601,7 +601,6 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path) char fpath[grub_strlen (path)]; char *name = fpath; char *next; - unsigned int pos = 0; struct grub_jfs_diropen *diro; grub_strncpy (fpath, path, grub_strlen (path) + 1); @@ -664,8 +663,6 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path) if (!next) return 0; - pos = 0; - name = next; next = grub_strchr (name, '/'); if (next) diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index aa5b9a0c9..679e1ec51 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -436,7 +436,6 @@ grub_minix_dir (grub_device_t device, const char *path, const struct grub_dirhook_info *info)) { struct grub_minix_data *data = 0; - struct grub_minix_sblock *sblock; unsigned int pos = 0; data = grub_minix_mount (device->disk); @@ -447,8 +446,6 @@ grub_minix_dir (grub_device_t device, const char *path, if (grub_errno) goto fail; - sblock = &data->sblock; - grub_minix_find_file (data, path); if (grub_errno) goto fail; diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 68f8b3a6e..4a5005908 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -149,7 +149,6 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block, struct grub_sfs_btree *tree; int i; int next; - int prev; treeblock = grub_malloc (data->blocksize); if (!block) @@ -161,8 +160,6 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block, /* Handle this level in the btree. */ do { - prev = 0; - grub_disk_read (data->disk, next, 0, data->blocksize, treeblock); if (grub_errno) { diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 40cf068e6..2b1021db6 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -568,7 +568,6 @@ grub_ufs_dir (grub_device_t device, const char *path, const struct grub_dirhook_info *info)) { struct grub_ufs_data *data; - struct grub_ufs_sblock *sblock; unsigned int pos = 0; data = grub_ufs_mount (device->disk); @@ -579,8 +578,6 @@ grub_ufs_dir (grub_device_t device, const char *path, if (grub_errno) return grub_errno; - sblock = &data->sblock; - if (!path || path[0] != '/') { grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index 8058fcc4f..b6b07dfd6 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -563,7 +563,6 @@ grub_gui_list_new (void) list_impl_t self; grub_font_t default_font; grub_gui_color_t default_fg_color; - grub_gui_color_t default_bg_color; self = grub_zalloc (sizeof (*self)); if (! self) @@ -576,7 +575,6 @@ grub_gui_list_new (void) 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); self->icon_width = 32; self->icon_height = 32; diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c index 518c3ba53..901cdc889 100644 --- a/grub-core/gfxmenu/view.c +++ b/grub-core/gfxmenu/view.c @@ -309,10 +309,8 @@ redraw_menu_visit (grub_gui_component_t component, view = userdata; if (component->ops->is_instance (component, "list")) { - grub_gui_list_t list; grub_video_rect_t bounds; - list = (grub_gui_list_t) component; component->ops->get_bounds (component, &bounds); grub_gfxmenu_view_redraw (view, &bounds); } diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c index 079fd66d4..244fe1e6c 100644 --- a/grub-core/gfxmenu/widget-box.c +++ b/grub-core/gfxmenu/widget-box.c @@ -79,21 +79,9 @@ static void draw (grub_gfxmenu_box_t self, int x, int y) { int height_n; - int height_s; - int height_e; - int height_w; - int width_n; - int width_s; - int width_e; int width_w; height_n = get_height (self->scaled_pixmaps[BOX_PIXMAP_N]); - height_s = get_height (self->scaled_pixmaps[BOX_PIXMAP_S]); - height_e = get_height (self->scaled_pixmaps[BOX_PIXMAP_E]); - height_w = get_height (self->scaled_pixmaps[BOX_PIXMAP_W]); - width_n = get_width (self->scaled_pixmaps[BOX_PIXMAP_N]); - width_s = get_width (self->scaled_pixmaps[BOX_PIXMAP_S]); - width_e = get_width (self->scaled_pixmaps[BOX_PIXMAP_E]); width_w = get_width (self->scaled_pixmaps[BOX_PIXMAP_W]); /* Draw sides. */ diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index ae27048a2..cd3bc8d40 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -486,8 +486,12 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) if (legacy_commands[cmdnum].flags & FLAG_TERMINAL) { - int dumb = 0, no_echo = 0, no_edit = 0, lines = 24; - int console = 0, serial = 0, hercules = 0; + int dumb = 0, lines = 24; +#ifdef TODO + int no_echo = 0, no_edit = 0; + int hercules = 0; +#endif + int console = 0, serial = 0; /* Big enough for any possible resulting command. */ char outbuf[256] = ""; char *outptr; @@ -497,13 +501,13 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) " [console] [serial] [hercules]"*/ if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0) dumb = 1; - +#ifdef TODO if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0) no_echo = 1; if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0) no_edit = 1; - +#endif if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0) { lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0); @@ -519,10 +523,10 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0) serial = 1; - +#ifdef TODO if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0) hercules = 1; - +#endif while (*ptr && !grub_isspace (*ptr)) ptr++; while (*ptr && grub_isspace (*ptr)) diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index a0cab55af..b1412e73a 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -579,7 +579,6 @@ malloc_in_range (struct grub_relocator *rel, for (ra = &base_saved, r = *ra; r; ra = &(r->next), r = *ra) { - int pre_added = 0; pa = r->first; p = pa->next; if (p->magic == GRUB_MM_ALLOC_MAGIC) @@ -591,7 +590,6 @@ malloc_in_range (struct grub_relocator *rel, __LINE__, p, p->magic); if (p == (grub_mm_header_t) (r + 1)) { - pre_added = 1; events[N].type = REG_BEG_START; events[N].pos = grub_vtop (r) - r->pre_size; events[N].reg = r; @@ -667,7 +665,6 @@ malloc_in_range (struct grub_relocator *rel, const int nlefto = 0; #endif grub_addr_t starta = 0; - int numstarted; for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1); from_low_priv ? j++ : j--) { @@ -725,11 +722,8 @@ malloc_in_range (struct grub_relocator *rel, isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw) && !nblockfw))); if (!isinsidebefore && isinsideafter) - { - starta = from_low_priv ? ALIGN_UP (events[j].pos, align) - : ALIGN_DOWN (events[j].pos - size, align) + size; - numstarted = j; - } + starta = from_low_priv ? ALIGN_UP (events[j].pos, align) + : ALIGN_DOWN (events[j].pos - size, align) + size; if (isinsidebefore && !isinsideafter && from_low_priv) { target = starta; diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index 073f01da2..29892e5fb 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -396,10 +396,8 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, Elf_Shdr *s, *symsh, *strsh; char *shdr; unsigned symsize, strsize; - Elf_Sym *sym; void *sym_chunk; grub_uint8_t *curload; - const char *str; grub_size_t chunk_size; Elf_Ehdr *e2; struct grub_netbsd_btinfo_symtab symtab; @@ -473,7 +471,6 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, if (grub_file_seek (file, symsh->sh_offset) == (grub_off_t) -1) return grub_errno; - sym = (Elf_Sym *) curload; if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize) { if (! grub_errno) @@ -484,7 +481,6 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, if (grub_file_seek (file, strsh->sh_offset) == (grub_off_t) -1) return grub_errno; - str = (char *) curload; if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize) { if (! grub_errno) diff --git a/grub-core/loader/i386/bsd_pagetable.c b/grub-core/loader/i386/bsd_pagetable.c index 13348cc83..9ec5abffc 100644 --- a/grub-core/loader/i386/bsd_pagetable.c +++ b/grub-core/loader/i386/bsd_pagetable.c @@ -53,7 +53,7 @@ static void fill_bsd64_pagetable (grub_uint8_t *src, grub_addr_t target) { grub_uint64_t *pt2, *pt3, *pt4; - grub_addr_t pt2t, pt3t, pt4t; + grub_addr_t pt2t, pt3t; int i; #define PG_V 0x001 @@ -65,7 +65,6 @@ fill_bsd64_pagetable (grub_uint8_t *src, grub_addr_t target) pt3 = (grub_uint64_t *) (src + 4096); pt2 = (grub_uint64_t *) (src + 8192); - pt4t = target; pt3t = target + 4096; pt2t = target + 8192; From 27d9ee3253f2b9963b091ba14a24ad600f38c42c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Oct 2010 23:38:30 +0200 Subject: [PATCH 0319/1414] * docs/grub.texi (Installation): Document embedding zone. Remove obsolete grub-install example. --- ChangeLog | 5 +++++ docs/grub.texi | 15 ++------------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4a06eaefa..7fa6586d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-16 Vladimir Serbinenko + + * docs/grub.texi (Installation): Document embedding zone. Remove + obsolete grub-install example. + 2010-10-16 Szymon Janc * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): diff --git a/docs/grub.texi b/docs/grub.texi index 4995b1df7..1bf652e15 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -559,6 +559,8 @@ 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. +On BIOS platforms GRUB has to use a so called embedding zone. On msdos partition tables it's the space between MBR and first partition (called MBR gap), on GPT partition it uses a BIOS Boot Partition (a partition having type 21686148-6449-6e6f-744e656564454649). If you use GRUB on BIOS be sure to supply at least 31 KiB of embedding zone (512KiB or more recommended). + If you still do want 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}). @@ -579,18 +581,6 @@ Likewise, under GNU/Hurd, this has the same effect: # @kbd{grub-install /dev/hd0} @end example -If it is the first BIOS drive, this is the same as well: - -@example -# @kbd{grub-install '(hd0)'} -@end example - -Or you can omit the parentheses: - -@example -# @kbd{grub-install 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 @@ -629,7 +619,6 @@ using @command{grub-install}. Don't do that, however, unless you are very familiar with the internals of GRUB. Installing a boot loader on a running OS may be extremely dangerous. - @node Making a GRUB bootable CD-ROM @section Making a GRUB bootable CD-ROM From f77a8c24709523ab1074b6272cf8dafe0f5de7d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 00:25:23 +0200 Subject: [PATCH 0320/1414] * util/grub-setup.c (setup): Don't clean blocklists before readability verfification. --- ChangeLog | 5 +++++ util/grub-setup.c | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7fa6586d1..731abcb0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-17 Vladimir Serbinenko + + * util/grub-setup.c (setup): Don't clean blocklists before readability + verfification. + 2010-10-16 Vladimir Serbinenko * docs/grub.texi (Installation): Document embedding zone. Remove diff --git a/util/grub-setup.c b/util/grub-setup.c index 920d867f2..ab0098468 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -319,18 +319,6 @@ setup (const char *dir, } #endif - /* Clean out the blocklists. */ - block = first_block; - while (block->len) - { - grub_memset (block, 0, sizeof (block)); - - block--; - - if ((char *) block <= core_img) - grub_util_error ("No terminator in the core image"); - } - #ifdef GRUB_MACHINE_PCBIOS { grub_partition_map_t dest_partmap = NULL; @@ -434,6 +422,18 @@ setup (const char *dir, goto unable_to_embed; } + /* Clean out the blocklists. */ + block = first_block; + while (block->len) + { + grub_memset (block, 0, sizeof (block)); + + block--; + + if ((char *) block <= core_img) + grub_util_error ("No terminator in the core image"); + } + save_first_sector (sectors[0] + grub_partition_get_start (container), 0, GRUB_DISK_SECTOR_SIZE); From 861dfd4cb2dcb882ea4a4334172ee7114fd85d6e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 00:28:19 +0200 Subject: [PATCH 0321/1414] * util/grub-install.in: Handle partitionless disks. --- ChangeLog | 4 ++++ util/grub-install.in | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 731abcb0f..b5c091ee1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-10-17 Vladimir Serbinenko + + * util/grub-install.in: Handle partitionless disks. + 2010-10-17 Vladimir Serbinenko * util/grub-setup.c (setup): Don't clean blocklists before readability diff --git a/util/grub-install.in b/util/grub-install.in index cace82593..21ac20f8d 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -512,7 +512,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1 # Strip partition number - grub_partition="`echo ${grub_drive} | sed -e 's/^[^,]*,//; s/)$//'`" + grub_partition="`echo ${grub_drive} | sed -e 's/^[^,]*[,)]//; s/)$//'`" grub_drive="`echo ${grub_drive} | sed -e s/,[a-z0-9,]*//g`" if [ "$disk_module" = ata ] ; then # generic method (used on coreboot and ata mod) @@ -537,7 +537,11 @@ if [ "x${devabstraction_module}" = "x" ] ; then modules="$modules search_fs_uuid" elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ]; then # we need to hardcode the partition number in the core image's prefix. - prefix_drive="(,$grub_partition)" + if [ x"$grub_partition" = x ]; then + prefix_drive="()" + else + prefix_drive="(,$grub_partition)" + fi fi else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 From fdf2ec9c8ceef98d8e4aca6c176f56514f4103ee Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 00:35:14 +0200 Subject: [PATCH 0322/1414] * util/grub-setup.c (setup): New parameter allow_floppy. (arguments): New member allow_floppy. (argp_parser): Handle --allow-floppy. (main): Pass allow_floppy. * util/grub-install.in: New option --allow-floppy passed though to grub-setup. --- ChangeLog | 9 +++++++++ util/grub-install.in | 9 ++++++++- util/grub-setup.c | 18 ++++++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5c091ee1..4e0d4a81e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-10-17 Vladimir Serbinenko + + * util/grub-setup.c (setup): New parameter allow_floppy. + (arguments): New member allow_floppy. + (argp_parser): Handle --allow-floppy. + (main): Pass allow_floppy. + * util/grub-install.in: New option --allow-floppy passed though to + grub-setup. + 2010-10-17 Vladimir Serbinenko * util/grub-install.in: Handle partitionless disks. diff --git a/util/grub-install.in b/util/grub-install.in index 21ac20f8d..8b0f5ebe1 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -107,6 +107,8 @@ Install GRUB on your drive. --grub-mkdevicemap=FILE use FILE as grub-mkdevicemap --grub-probe=FILE use FILE as grub-probe --no-floppy do not probe any floppy drive + --allow-floppy Make the drive also bootable as floppy + (default for fdX devices). May break on some BIOSes. --recheck probe a device map even if it already exists --force install even if problems are detected EOF @@ -148,6 +150,8 @@ argument () { echo $1 } +allow_floppy="" + # Check the arguments. while test $# -gt 0 do @@ -221,6 +225,9 @@ do --removable) removable=yes ;; + --allow-floppy) + allow_floppy="--allow-floppy" ;; + --disk-module) if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then disk_module=`argument $option "$@"`; shift; @@ -576,7 +583,7 @@ fi # Perform the platform-dependent install if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then # Now perform the installation. - $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} \ + $grub_setup ${allow_floppy} ${setup_verbose} ${setup_force} --directory=${grubdir} \ --device-map=${device_map} ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then if [ x"$update_nvram" = xyes ]; then diff --git a/util/grub-setup.c b/util/grub-setup.c index ab0098468..8ab33590b 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -177,7 +177,7 @@ static void setup (const char *dir, const char *boot_file, const char *core_file, const char *root, const char *dest, int must_embed, int force, - int fs_probe) + int fs_probe, int allow_floppy) { char *boot_path, *core_path, *core_path_dev, *core_path_dev_full; char *boot_img, *core_img; @@ -313,7 +313,7 @@ setup (const char *dir, /* If DEST_DRIVE is a hard disk, enable the workaround, which is for buggy BIOSes which don't pass boot drive correctly. Instead, they pass 0x00 or 0x01 even when booted from 0x80. */ - if (!grub_util_biosdisk_is_floppy (dest_dev->disk)) + if (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)) /* Replace the jmp (2 bytes) with double nop's. */ *boot_drive_check = 0x9090; } @@ -678,6 +678,9 @@ static struct argp_option options[] = { N_("Do not probe for filesystems in DEVICE"), 0}, {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0}, + {"allow-floppy", 'a', 0, 0, + N_("Make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0}, + { 0, 0, 0, 0, 0, 0 } }; @@ -712,6 +715,7 @@ struct arguments char *root_dev; int force; int fs_probe; + int allow_floppy; char *device; }; @@ -737,6 +741,10 @@ argp_parser (int key, char *arg, struct argp_state *state) switch (key) { + case 'a': + arguments->allow_floppy = 1; + break; + case 'b': if (arguments->boot_file) free (arguments->boot_file); @@ -950,7 +958,8 @@ main (int argc, char *argv[]) arguments.boot_file ? : DEFAULT_BOOT_FILE, arguments.core_file ? : DEFAULT_CORE_FILE, root_dev, grub_util_get_grub_dev (devicelist[i]), 1, - arguments.force, arguments.fs_probe); + arguments.force, arguments.fs_probe, + arguments.allow_floppy); } } else @@ -959,7 +968,8 @@ main (int argc, char *argv[]) setup (arguments.dir ? : DEFAULT_DIRECTORY, arguments.boot_file ? : DEFAULT_BOOT_FILE, arguments.core_file ? : DEFAULT_CORE_FILE, - root_dev, dest_dev, must_embed, arguments.force, arguments.fs_probe); + root_dev, dest_dev, must_embed, arguments.force, + arguments.fs_probe, arguments.allow_floppy); /* Free resources. */ grub_fini_all (); From ba5f65cfa17f410e6cb61e2b3ad858fcc1d0804a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 00:38:57 +0200 Subject: [PATCH 0323/1414] * docs/grub.texi (Installation): Indent. --- ChangeLog | 4 ++++ docs/grub.texi | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4e0d4a81e..805f8326d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-10-17 Vladimir Serbinenko + + * docs/grub.texi (Installation): Indent. + 2010-10-17 Vladimir Serbinenko * util/grub-setup.c (setup): New parameter allow_floppy. diff --git a/docs/grub.texi b/docs/grub.texi index 1bf652e15..9a457a073 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -559,7 +559,12 @@ 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. -On BIOS platforms GRUB has to use a so called embedding zone. On msdos partition tables it's the space between MBR and first partition (called MBR gap), on GPT partition it uses a BIOS Boot Partition (a partition having type 21686148-6449-6e6f-744e656564454649). If you use GRUB on BIOS be sure to supply at least 31 KiB of embedding zone (512KiB or more recommended). +On BIOS platforms GRUB has to use a so called embedding zone. On msdos +partition tables it's the space between MBR and first partition (called +MBR gap), on GPT partition it uses a BIOS Boot Partition (a partition +having type 21686148-6449-6e6f-744e656564454649). If you use GRUB on +BIOS be sure to supply at least 31 KiB of embedding zone (512KiB or more +recommended). If you still do want to install GRUB under a UNIX-like OS (such as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking From 5b0276902e71aee083eafc8b705b00da704d2498 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 00:46:39 +0200 Subject: [PATCH 0324/1414] * docs/grub.texi (Installation): Document buggy BIOS install. --- ChangeLog | 4 ++++ docs/grub.texi | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/ChangeLog b/ChangeLog index 805f8326d..fbd4b2752 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-10-17 Vladimir Serbinenko + + * docs/grub.texi (Installation): Document buggy BIOS install. + 2010-10-17 Vladimir Serbinenko * docs/grub.texi (Installation): Indent. diff --git a/docs/grub.texi b/docs/grub.texi index 9a457a073..a04e31605 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -617,6 +617,19 @@ 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 first partition of USB pendrive as a floppy +instead of exposing pendrive as a hard disk (they call it ``USB-FDD'' boot) +In such cases you need to install as following: + +@example +# @kbd{losetup /dev/loop0 /dev/sdb1} +# @kbd{mount /dev/loop0 /mnt/usb} +# @kbd{grub-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0} +@end example + +This install doesn't conflict with standard install as long as they are in +separate directories. + Note that @command{grub-install} is actually just a shell script and the real task is done by @command{grub-mkimage} and @command{grub-setup}. Therefore, you may run those commands directly to install GRUB, without From 7bced4583e072271583ba2ee28f054dd025ec152 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 01:49:06 +0200 Subject: [PATCH 0325/1414] * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Check cursor shape for sanity. --- ChangeLog | 5 +++++ grub-core/kern/i386/pc/startup.S | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index fbd4b2752..128c5f959 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-17 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Check + cursor shape for sanity. + 2010-10-17 Vladimir Serbinenko * docs/grub.texi (Installation): Document buggy BIOS install. diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index e03fc8301..6b43d9f14 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -820,6 +820,10 @@ FUNCTION(grub_console_setcursor) DATA32 call real_to_prot .code32 + cmp %cl, %ch + jb 3f + movw $0x0d0e, %cx +3: movw %cx, console_cursor_shape 1: /* set %cx to the designated cursor shape */ From d82df574cda02226b9f0f444cda920a5e613bce4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 17 Oct 2010 02:08:08 +0200 Subject: [PATCH 0326/1414] * docs/grub.texi (GNU/Linux): Document APM unavailability with 32-bit linux protocol. --- ChangeLog | 5 +++++ docs/grub.texi | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index 128c5f959..ddebabefc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-17 Vladimir Serbinenko + + * docs/grub.texi (GNU/Linux): Document APM unavailability with + 32-bit linux protocol. + 2010-10-17 Vladimir Serbinenko * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Check diff --git a/docs/grub.texi b/docs/grub.texi index a04e31605..751dd9dc2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -895,6 +895,14 @@ grub> @kbd{linux /vmlinuz root=/dev/sda1 acpi=off} See the documentation in the Linux source tree for complete information on the available options. +With @command{linux} GRUB uses 32-bit protocol. Some BIOS services like APM +or EDD aren't available with this protocol. In this case you need to use +@command{linux16} + +@example +grub> @kbd{linux16 /vmlinuz root=/dev/sda1 acpi=off} +@end example + @item If you use an initrd, execute the command @command{initrd} (@pxref{initrd}) after @command{linux}: @@ -903,6 +911,12 @@ after @command{linux}: grub> @kbd{initrd /initrd} @end example +If you used @command{linux16} you need to use @command{initrd16}: + +@example +grub> @kbd{initrd16 /initrd} +@end example + @item Finally, run the command @command{boot} (@pxref{boot}). @end enumerate From 800e6a9be56dcf3e0cc496d7edfbc5c68afbd935 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 17 Oct 2010 15:41:54 +0200 Subject: [PATCH 0327/1414] * grub-core/normal/auth.c (grub_auth_check_authentication): Set-but-not-used variable removed. --- ChangeLog | 5 +++++ grub-core/normal/auth.c | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddebabefc..0f75bc762 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-17 Szymon Janc + + * grub-core/normal/auth.c (grub_auth_check_authentication): + Set-but-not-used variable removed. + 2010-10-17 Vladimir Serbinenko * docs/grub.texi (GNU/Linux): Document APM unavailability with diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c index 459d4cdbd..e5d187f0e 100644 --- a/grub-core/normal/auth.c +++ b/grub-core/normal/auth.c @@ -201,7 +201,6 @@ grub_auth_check_authentication (const char *userlist) { char login[1024]; struct grub_auth_user *cur = NULL; - grub_err_t err; static unsigned long punishment_delay = 1; char entered[GRUB_AUTH_MAX_PASSLEN]; struct grub_auth_user *user; @@ -233,7 +232,7 @@ grub_auth_check_authentication (const char *userlist) if (!cur || ! cur->callback) goto access_denied; - err = cur->callback (login, entered, cur->arg); + cur->callback (login, entered, cur->arg); if (is_authenticated (userlist)) { punishment_delay = 1; From 6351c13140046cb9de35f293f6f6f235d1f17bd2 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 18 Oct 2010 13:38:42 +0530 Subject: [PATCH 0328/1414] fix built-in initramfs case --- util/grub.d/10_linux.in | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index e37bab21b..ceee61154 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -127,10 +127,20 @@ while [ "x$list" != "x" ] ; do break fi done + + initramfs= + for i in "config-${version}" "config-${alt_version}"; do + if test -e "${dirname}/${i}" ; then + initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${dirname}/${i}" | cut -f2 -d= | tr -d \"` + break + fi + done + if test -n "${initrd}" ; then echo "Found initrd image: ${dirname}/${initrd}" >&2 - else - # "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here. + elif test -z "${initramfs}" ; then + # "UUID=" magic is parsed by initrd or initramfs. Since there's + # no initrd or builtin initramfs, it can't work here. linux_root_device_thisversion=${GRUB_DEVICE} fi From 05f43cdd03235e140f42bbbbfe293c0a66b79bf4 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 18 Oct 2010 13:41:00 +0530 Subject: [PATCH 0329/1414] add change log entry --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0f75bc762..a41f8563e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-18 BVK Chaitanya + + * util/grub.d/10_linux.in: Fix built-in initramfs image mode for + Linux kernel, reported by Dennis Schridde. + 2010-10-17 Szymon Janc * grub-core/normal/auth.c (grub_auth_check_authentication): From b65ea1551499ec6ed900e57ac1bcdad80ebf3164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 18 Oct 2010 22:50:01 +0200 Subject: [PATCH 0330/1414] Make mktemp invocations portable. --- ChangeLog | 16 ++++++++++++++++ Makefile.am | 16 ++++++++-------- grub-core/genmod.sh.in | 4 ++-- tests/grub_script_blockarg.in | 2 +- tests/partmap_test.in | 4 ++-- tests/util/grub-shell-tester.in | 6 +++--- tests/util/grub-shell.in | 12 ++++++------ util/grub-mkrescue.in | 20 ++++++-------------- util/powerpc/ieee1275/grub-mkrescue.in | 4 ++-- 9 files changed, 46 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index a41f8563e..1ded89247 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-10-18 GrĂ©goire Sutre + + Make mktemp invocations portable. + + * grub-core/genmod.sh.in: Use mktemp with an explicit template, and + exit if mktemp fails. + * tests/grub_script_blockarg.in: Likewise. + * tests/partmap_test.in: Likewise. + * tests/util/grub-shell-tester.in: Likewise. + * tests/util/grub-shell.in: Likewise. + * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. + * Makefile.am: Likewise, and chain shell commands with `&&' + instead of ';'. + * util/grub-mkrescue.in: Use the same explicit template as above, and + exit if mktemp fails. + 2010-10-18 BVK Chaitanya * util/grub.d/10_linux.in: Fix built-in initramfs image mode for diff --git a/Makefile.am b/Makefile.am index 931ea02e8..15dae9642 100644 --- a/Makefile.am +++ b/Makefile.am @@ -189,31 +189,31 @@ kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" linux-initramfs.i386: linux.init.i386 Makefile - TDIR=`mktemp -d`; cp $< $$TDIR/init; (cd $$TDIR; echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@; rm -rf $$TDIR + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR linux-initramfs.x86_64: linux.init.x86_64 Makefile - TDIR=`mktemp -d`; cp $< $$TDIR/init; (cd $$TDIR; echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@; rm -rf $$TDIR + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR kfreebsd-mfsroot.i386.img: kfreebsd.init.i386 Makefile - TDIR=`mktemp -d`; mkdir $$TDIR/dev; mkdir $$TDIR/sbin; cp $< $$TDIR/sbin/init; makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR; rm -rf $$TDIR + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR knetbsd.image.i386: knetbsd.init.i386 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt - TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR kopenbsd.image.i386: kopenbsd.init.i386 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt - TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@ + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@ kopenbsd.image.x86_64: kopenbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt - TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@ + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@ knetbsd.miniroot-image.i386.img: knetbsd.image.i386 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 $(OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 $@ kfreebsd-mfsroot.x86_64.img: kfreebsd.init.x86_64 Makefile - TDIR=`mktemp -d`; mkdir $$TDIR/dev; mkdir $$TDIR/sbin; cp $< $$TDIR/sbin/init; makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR; rm -rf $$TDIR + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR knetbsd.image.x86_64: knetbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt - TDIR=`mktemp -d` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR + TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR knetbsd.miniroot-image.x86_64.img: knetbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 $(OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 $@ diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in index faac2b605..8dfd5d347 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -38,10 +38,10 @@ rm -f $tmpfile $outfile objcopy -R .modname -R .moddeps $infile $tmpfile # Attach .modname and .moddeps sections -t1=`mktemp` +t1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 printf "$modname\0" >$t1 -t2=`mktemp` +t2=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 for dep in $deps; do printf "$dep\0" >> $t2; done if test -n "$deps"; then diff --git a/tests/grub_script_blockarg.in b/tests/grub_script_blockarg.in index 783cee8e0..2765b61ac 100644 --- a/tests/grub_script_blockarg.in +++ b/tests/grub_script_blockarg.in @@ -27,7 +27,7 @@ cmd='test_blockarg { true }' v=`echo "$cmd" | @builddir@/grub-shell` error_if_not "$v" '{ true }' -tmp=`mktemp` +tmp=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 cmd='test_blockarg { test_blockarg { true } }' echo "$cmd" | @builddir@/grub-shell >$tmp error_if_not "`head -n1 $tmp|tail -n1`" '{ test_blockarg { true } }' diff --git a/tests/partmap_test.in b/tests/partmap_test.in index 14897e9da..5a9c1a93d 100644 --- a/tests/partmap_test.in +++ b/tests/partmap_test.in @@ -51,8 +51,8 @@ list_parts () { echo } -imgfile=`mktemp` -outfile=`mktemp` +imgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +outfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 # # MSDOS partition types diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in index ed34a5e17..02e49d3a4 100644 --- a/tests/util/grub-shell-tester.in +++ b/tests/util/grub-shell-tester.in @@ -83,17 +83,17 @@ for option in "$@"; do done if [ "x${source}" = x ] ; then - tmpfile=`mktemp` + tmpfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 while read REPLY; do echo $REPLY >> ${tmpfile} done source=${tmpfile} fi -outfile1=`mktemp` +outfile1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 @builddir@/grub-shell --qemu-opts="${qemuopts}" --modules=${modules} ${source} >${outfile1} -outfile2=`mktemp` +outfile2=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 bash ${source} >${outfile2} if ! diff -q ${outfile1} ${outfile2} >/dev/null diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index c8247d29d..fc14ca7b0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -107,14 +107,14 @@ for option in "$@"; do done if [ "x${source}" = x ] ; then - tmpfile=`mktemp` + tmpfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 while read REPLY; do echo "$REPLY" >> ${tmpfile} done source=${tmpfile} fi -cfgfile=`mktemp` +cfgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 cat <${cfgfile} grubshell=yes insmod serial @@ -123,7 +123,7 @@ terminal_input serial terminal_output serial EOF -rom_directory=`mktemp -d` +rom_directory=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 for mod in ${modules} do @@ -135,7 +135,7 @@ source /boot/grub/testcase.cfg halt EOF -isofile=`mktemp` +isofile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 if [ x$boot != xnet ]; then sh @builddir@/grub-mkrescue --grub-mkimage=${builddir}/grub-mkimage --output=${isofile} --override-directory=${builddir}/grub-core \ --rom-directory="${rom_directory}" \ @@ -161,7 +161,7 @@ if [ x$boot = xqemu ]; then fi if [ x$boot = xcoreboot ]; then - imgfile=`mktemp` + imgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 cp "${GRUB_COREBOOT_ROM}" "${imgfile}" "${GRUB_CBFSTOOL}" "${imgfile}" add-payload "${rom_directory}/coreboot.elf" fallback/payload bootdev="-bios ${imgfile}" @@ -169,7 +169,7 @@ if [ x$boot = xcoreboot ]; then fi if [ x$boot = xnet ]; then - netdir=`mktemp -d` + netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 sh @builddir@/grub-mknetdir --grub-mkimage=${builddir}/grub-mkimage --override-directory=${builddir}/grub-core --net-directory=$netdir cp ${cfgfile} $netdir/boot/grub/grub.cfg cp ${source} $netdir/boot/grub/testcase.cfg diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index f2714c486..690bddb30 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -152,15 +152,7 @@ else exit 1 fi -if test "x$TMP" != x; then - MKTEMP_TEMPLATE="$TMP/grub-mkrescue.XXXXXXXXXX" -elif test "x$TEMP" != x; then - MKTEMP_TEMPLATE="$TEMP/grub-mkrescue.XXXXXXXXXX" -else - MKTEMP_TEMPLATE="/tmp/grub-mkrescue.XXXXXXXXXX" -fi - -iso9660_dir=`mktemp -d "$MKTEMP_TEMPLATE"` +iso9660_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 mkdir -p ${iso9660_dir}/boot/grub process_input_dir () @@ -197,8 +189,8 @@ make_image () echo "Enabling $2 support ..." - memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` - memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + memdisk_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + memdisk_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 mkdir -p ${memdisk_dir}/boot/grub cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg @@ -263,12 +255,12 @@ grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${i # build BIOS core.img if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." - core_img=`mktemp "$MKTEMP_TEMPLATE"` + core_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 $grub_mkimage -O i386-pc -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img - embed_img=`mktemp "$MKTEMP_TEMPLATE"` + embed_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 cat ${pc_dir}/boot.img ${core_img} > ${embed_img} rm -f ${core_img} @@ -287,7 +279,7 @@ fi make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "ata at_keyboard" if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then - efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 mkdir -p "${efi_dir}/efi/boot" # build bootx64.efi diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index aefedff3f..d688431c3 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -121,13 +121,13 @@ if [ "x${modules}" = "x" ] ; then modules=`cd ${input_dir}/ && ls *.mod` fi -map_file=`mktemp` +map_file=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 cat >${map_file} < Date: Tue, 19 Oct 2010 10:44:57 +0530 Subject: [PATCH 0331/1414] netbsd fixes --- Makefile.util.def | 77 ++++++++++++++++++++++++++++---------------- conf/Makefile.common | 6 ++-- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index c1fd077f7..e2101141b 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -1,5 +1,23 @@ AutoGen definitions Makefile.tpl; +library = { + name = libemu.a; + cflags = '$(CFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_GNULIB)'; + + common = util/misc.c; + common = grub-core/kern/err.c; + common = grub-core/kern/env.c; + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/kern/disk.c; + common = grub-core/kern/partition.c; + common = grub-core/kern/emu/mm.c; + common = grub-core/kern/emu/misc.c; + common = grub-core/kern/emu/getroot.c; + common = grub-core/kern/emu/hostdisk.c; +}; + library = { name = libgrub.a; cflags = '$(CFLAGS_GCRY)'; @@ -11,13 +29,6 @@ library = { common_nodist = grub_script.yy.h; common_nodist = grub_script.tab.h; - common = util/misc.c; - common = grub-core/kern/misc.c; - common = grub-core/kern/emu/mm.c; - common = grub-core/kern/emu/misc.c; - common = grub-core/kern/emu/getroot.c; - common = grub-core/kern/emu/hostdisk.c; - common = grub-core/commands/blocklist.c; common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; @@ -57,13 +68,8 @@ library = { common = grub-core/fs/xfs.c; common = grub-core/kern/command.c; common = grub-core/kern/device.c; - common = grub-core/kern/disk.c; - common = grub-core/kern/env.c; - common = grub-core/kern/err.c; common = grub-core/kern/file.c; common = grub-core/kern/fs.c; - common = grub-core/kern/list.c; - common = grub-core/kern/partition.c; common = grub-core/lib/arg.c; common = grub-core/lib/crypto.c; common = grub-core/lib/envblk.c; @@ -94,8 +100,9 @@ program = { name = grub-bin2h; common = util/bin2h.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; mansection = 1; }; @@ -108,9 +115,10 @@ program = { extra_dist = util/grub-mkimagexx.c; ldadd = libgrub.a; + ldadd = libemu.a; + ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBLZMA)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; - ldadd = grub-core/gnulib/libgnu.a; cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"'; }; @@ -121,8 +129,9 @@ program = { common = util/grub-mkrelpath.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; program = { @@ -132,8 +141,9 @@ program = { common = util/grub-script-check.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; program = { @@ -143,8 +153,9 @@ program = { common = util/grub-editenv.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; program = { @@ -154,8 +165,9 @@ program = { common = util/grub-mkpasswd-pbkdf2.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; }; @@ -173,8 +185,9 @@ program = { common = util/grub-pe2elf.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL)'; condition = COND_GRUB_PE2ELF; }; @@ -190,8 +203,9 @@ program = { cppflags = '$(CPPFLAGS_GCRY)'; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; program = { @@ -203,9 +217,10 @@ program = { cflags = '$(freetype_cflags)'; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; condition = COND_GRUB_MKFONT; }; @@ -222,8 +237,9 @@ program = { sparc64_ieee1275 = util/ieee1275/devicemap.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; }; program = { @@ -233,8 +249,9 @@ program = { common = util/grub-probe.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; }; program = { @@ -249,8 +266,9 @@ program = { sparc64_ieee1275 = util/ieee1275/ofpath.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; enable = i386_pc; enable = sparc64_ieee1275; @@ -263,8 +281,10 @@ program = { ieee1275 = util/ieee1275/ofpath.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + enable = sparc64_ieee1275; }; @@ -275,8 +295,9 @@ program = { common = util/grub-mklayout.c; ldadd = libgrub.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; data = { @@ -584,6 +605,7 @@ program = { common = grub-core/tests/lib/test.c; cflags = -Wno-format; ldadd = libgrub.a; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER)'; }; @@ -596,6 +618,7 @@ program = { common = grub-core/lib/i386/pc/vesa_modes_table.c; ldadd = libgrub.a; - ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = libemu.a; ldadd = grub-core/gnulib/libgnu.a; + ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; diff --git a/conf/Makefile.common b/conf/Makefile.common index 81bb3567e..32851e34e 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -67,9 +67,9 @@ LDFLAGS_PROGRAM = CPPFLAGS_PROGRAM = CCASFLAGS_PROGRAM = -CFLAGS_LIBRARY = $(CFLAGS_PROGRAM) -CPPFLAGS_LIBRARY = $(CPPFLAGS_PROGRAM) -CCASFLAGS_LIBRARY = $(CCASFLAGS_PROGRAM) +CFLAGS_LIBRARY = +CPPFLAGS_LIBRARY = +CCASFLAGS_LIBRARY = # Other variables From 0cbcdf0e6fce10e8556b26a5da6385042aa2be0a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 22 Oct 2010 14:17:33 +0100 Subject: [PATCH 0332/1414] * docs/grub.texi (Installing GRUB using grub-install): Proofread. (Supported kernels): Likewise. --- ChangeLog | 5 +++++ docs/grub.texi | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ded89247..00ec9d6a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-22 Colin Watson + + * docs/grub.texi (Installing GRUB using grub-install): Proofread. + (Supported kernels): Likewise. + 2010-10-18 GrĂ©goire Sutre Make mktemp invocations portable. diff --git a/docs/grub.texi b/docs/grub.texi index 751dd9dc2..b37a5bfac 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -559,11 +559,12 @@ 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. -On BIOS platforms GRUB has to use a so called embedding zone. On msdos -partition tables it's the space between MBR and first partition (called -MBR gap), on GPT partition it uses a BIOS Boot Partition (a partition -having type 21686148-6449-6e6f-744e656564454649). If you use GRUB on -BIOS be sure to supply at least 31 KiB of embedding zone (512KiB or more +On BIOS platforms GRUB has to use a so-called embedding zone. On msdos +partition tables, this is the space between the MBR and the first partition +(called the MBR gap or the boot track), while on GPT partition tables it +uses a BIOS Boot Partition (a partition with GUID +21686148-6449-6e6f-744e656564454649). If you use GRUB on a BIOS system, make +sure that the embedding zone is at least 31 KiB (512KiB or more recommended). If you still do want to install GRUB under a UNIX-like OS (such @@ -617,9 +618,9 @@ 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 first partition of USB pendrive as a floppy -instead of exposing pendrive as a hard disk (they call it ``USB-FDD'' boot) -In such cases you need to install as following: +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: @example # @kbd{losetup /dev/loop0 /dev/sdb1} @@ -3295,7 +3296,7 @@ commands. @node Supported kernels @chapter Supported boot targets -X86 support is summarised in following table. ``Yes'' means that kernel works on the given platform, ``crashes'' means an early kernel crash which we hove will be fixed by concerned kernel developpers. ``no'' means GRUB doesn't load given kernel on a given platform. ``headless'' means that the kernel works but lacks console drivers (you can still use serial or network console). In case of ``no'' and ``crashes'' the reason is given in footnote. +X86 support is summarised in the following table. ``Yes'' means that the kernel works on the given platform, ``crashes'' means an early kernel crash which we hope will be fixed by concerned kernel developers. ``no'' means GRUB doesn't load the given kernel on a given platform. ``headless'' means that the kernel works but lacks console drivers (you can still use serial or network console). In case of ``no'' and ``crashes'' the reason is given in footnote. @multitable @columnfractions .50 .22 .22 @item @tab BIOS @tab Coreboot @item BIOS chainloading @tab yes @tab no (1) From e138c4583608b07376f1ce1bdc0aea88875adf3a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Oct 2010 22:49:36 +0200 Subject: [PATCH 0333/1414] * grub-core/lib/relocator.c (grub_relocator_subchunk): Remove now useless field head. All users updated. (free_subchunk): Correct handling of IN_REGION subchunk. --- ChangeLog | 6 ++++++ grub-core/lib/relocator.c | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00ec9d6a5..85ff4d088 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-10-22 Vladimir Serbinenko + + * grub-core/lib/relocator.c (grub_relocator_subchunk): Remove now + useless field head. All users updated. + (free_subchunk): Correct handling of IN_REGION subchunk. + 2010-10-22 Colin Watson * docs/grub.texi (Installing GRUB using grub-install): Proofread. diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index b1412e73a..90f6802d7 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -40,7 +40,6 @@ struct grub_relocator_subchunk #endif } type; grub_mm_region_t reg; - grub_mm_header_t head; grub_phys_addr_t start; grub_size_t size; grub_size_t pre_size; @@ -355,11 +354,11 @@ free_subchunk (const struct grub_relocator_subchunk *subchu) } case CHUNK_TYPE_IN_REGION: { - grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->head, + grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->start, GRUB_MM_ALIGN); h->size = ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN) - - (subchu->start / GRUB_MM_ALIGN); + - (subchu->start / GRUB_MM_ALIGN) - 1; h->next = h; h->magic = GRUB_MM_ALLOC_MAGIC; grub_free (h + 1); @@ -971,7 +970,6 @@ malloc_in_range (struct grub_relocator *rel, || typepre == CHUNK_TYPE_IN_REGION) { curschu->reg = events[last_start].reg; - curschu->head = events[last_start].head; curschu->pre_size = alloc_start - events[j - 1].pos; } if (!oom && (typepre == CHUNK_TYPE_REGION_START From 5c81f8b349e4844d65d5b1717a1ebe61defd6062 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Oct 2010 20:34:50 +0200 Subject: [PATCH 0334/1414] * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Revert r2882. --- ChangeLog | 5 +++++ grub-core/kern/emu/misc.c | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85ff4d088..bdeb62500 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-22 Vladimir Serbinenko + + * grub-core/kern/emu/misc.c + (grub_make_system_path_relative_to_its_root): Revert r2882. + 2010-10-22 Vladimir Serbinenko * grub-core/lib/relocator.c (grub_relocator_subchunk): Remove now diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index cfc143bf9..d8db3be9d 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -406,7 +406,21 @@ grub_make_system_path_relative_to_its_root (const char *path) /* buf is another filesystem; we found it. */ if (st.st_dev != num) - break; + { + /* offset == 0 means path given is the mount point. + This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in is considered a preceding slash, and + therefore the root directory is an empty string. */ + if (offset == 0) + { + free (buf); + free (buf2); + return xstrdup (""); + } + else + break; + } offset = p - buf; /* offset == 1 means root directory. */ @@ -434,10 +448,7 @@ grub_make_system_path_relative_to_its_root (const char *path) } #endif - /* This works around special-casing of "/" in Un*x. This function never - prints trailing slashes (so that its output can be appended a slash - unconditionally). Each slash in it is considered a preceding slash, - and therefore the root directory is an empty string. */ + /* Remove trailing slashes, return empty string if root directory. */ len = strlen (buf3); while (len > 0 && buf3[len - 1] == '/') { From 4f6a2e217510c7fa0fb663418838cbbb632c3634 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Oct 2010 20:39:08 +0200 Subject: [PATCH 0335/1414] * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root) [HAVE_LIBZFS && HAVE_LIBNVPAIR]: Fix mountpoint return on ZFS. --- ChangeLog | 8 +++++++- grub-core/kern/emu/misc.c | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bdeb62500..fe368aa57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ -2010-10-22 Vladimir Serbinenko +2010-10-23 Vladimir Serbinenko + + * grub-core/kern/emu/misc.c + (grub_make_system_path_relative_to_its_root) + [HAVE_LIBZFS && HAVE_LIBNVPAIR]: Fix mountpoint return on ZFS. + +2010-10-23 Vladimir Serbinenko * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Revert r2882. diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index d8db3be9d..c8b95443b 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -416,6 +416,10 @@ grub_make_system_path_relative_to_its_root (const char *path) { free (buf); free (buf2); +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + if (poolfs) + return xasprintf ("/%s/@", poolfs); +#endif return xstrdup (""); } else From 18568d18520b189ef796cdfc1535aad0c6bfac2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 26 Oct 2010 12:29:12 +0200 Subject: [PATCH 0336/1414] * include/grub/types.h (grub_target_off_t): Removed no longer used type. --- ChangeLog | 4 ++++ include/grub/types.h | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe368aa57..7c227ab86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-10-26 Vladimir Serbinenko + + * include/grub/types.h (grub_target_off_t): Removed no longer used type. + 2010-10-23 Vladimir Serbinenko * grub-core/kern/emu/misc.c diff --git a/include/grub/types.h b/include/grub/types.h index 221fef3c0..e57666a10 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -84,12 +84,10 @@ typedef unsigned long long grub_uint64_t; /* Misc types. */ #if GRUB_TARGET_SIZEOF_VOID_P == 8 typedef grub_uint64_t grub_target_addr_t; -typedef grub_uint64_t grub_target_off_t; typedef grub_uint64_t grub_target_size_t; typedef grub_int64_t grub_target_ssize_t; #else typedef grub_uint32_t grub_target_addr_t; -typedef grub_uint32_t grub_target_off_t; typedef grub_uint32_t grub_target_size_t; typedef grub_int32_t grub_target_ssize_t; #endif From 4171b3c5bcbc7654d1da9f6ddf5f562cd4ef7c41 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 26 Oct 2010 12:31:26 +0200 Subject: [PATCH 0337/1414] * util/grub-setup.c (setup): Clarify the error message. --- ChangeLog | 4 ++++ util/grub-setup.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c227ab86..153121d9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-10-26 Vladimir Serbinenko + + * util/grub-setup.c (setup): Clarify the error message. + 2010-10-26 Vladimir Serbinenko * include/grub/types.h (grub_target_off_t): Removed no longer used type. diff --git a/util/grub-setup.c b/util/grub-setup.c index 8ab33590b..588c87526 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -385,7 +385,7 @@ setup (const char *dir, if (! dest_partmap) { - grub_util_warn (_("Attempting to install GRUB to a partitionless disk. This is a BAD idea.")); + grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); goto unable_to_embed; } if (multiple_partmaps || fs) From 26c53dc64c2172604330952713749aa59077f072 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 26 Oct 2010 12:33:57 +0200 Subject: [PATCH 0338/1414] * util/grub-setup.c (argp): Remove misleading example of installing to a partition. --- ChangeLog | 5 +++++ util/grub-setup.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 153121d9a..1f31dbb78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-26 Vladimir Serbinenko + + * util/grub-setup.c (argp): Remove misleading example of installing to + a partition. + 2010-10-26 Vladimir Serbinenko * util/grub-setup.c (setup): Clarify the error message. diff --git a/util/grub-setup.c b/util/grub-setup.c index 588c87526..c3d7dcf43 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -822,7 +822,7 @@ Set up images to boot from DEVICE.\n\ \n\ You should not normally run this program directly. Use grub-install instead.") "\v"N_("\ -DEVICE must be an OS device (e.g. /dev/sda1)."), +DEVICE must be an OS device (e.g. /dev/sda)."), NULL, help_filter, NULL }; From 95b9257e6e47eea622fa219093574ed6636e1195 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 26 Oct 2010 12:40:35 +0200 Subject: [PATCH 0339/1414] * util/grub-setup.c (setup): Refuse to do a cross-disk embeddingless install rather than creating a broken install. --- ChangeLog | 5 +++++ util/grub-setup.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1f31dbb78..a24c9e451 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-10-26 Vladimir Serbinenko + + * util/grub-setup.c (setup): Refuse to do a cross-disk embeddingless + install rather than creating a broken install. + 2010-10-26 Vladimir Serbinenko * util/grub-setup.c (argp): Remove misleading example of installing to diff --git a/util/grub-setup.c b/util/grub-setup.c index c3d7dcf43..fa95f94aa 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -482,6 +482,12 @@ unable_to_embed: grub_util_error (_("embedding is not possible, but this is required when " "the root device is on a RAID array or LVM volume")); +#ifdef GRUB_MACHINE_PCBIOS + if (dest_dev->disk->id != root_dev->disk->id) + grub_util_error (_("embedding is not possible, but this is required for " + "cross-disk install")); +#endif + grub_util_warn (_("Embedding is not possible. GRUB can only be installed in this " "setup by using blocklists. However, blocklists are UNRELIABLE and " "their use is discouraged.")); From 3863137172e811d929624bd5f34c0636051374d7 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 29 Oct 2010 14:44:25 +0530 Subject: [PATCH 0340/1414] renamed libemu and libgrub to libgrubkern and libgrubmods respectively --- Makefile.util.def | 90 +++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index e2101141b..94dfb1044 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -1,25 +1,29 @@ AutoGen definitions Makefile.tpl; library = { - name = libemu.a; + name = libgrubkern.a; cflags = '$(CFLAGS_GNULIB)'; cppflags = '$(CPPFLAGS_GNULIB)'; common = util/misc.c; - common = grub-core/kern/err.c; - common = grub-core/kern/env.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; + common = grub-core/kern/command.c; + common = grub-core/kern/device.c; common = grub-core/kern/disk.c; - common = grub-core/kern/partition.c; - common = grub-core/kern/emu/mm.c; - common = grub-core/kern/emu/misc.c; common = grub-core/kern/emu/getroot.c; common = grub-core/kern/emu/hostdisk.c; + common = grub-core/kern/emu/misc.c; + common = grub-core/kern/emu/mm.c; + common = grub-core/kern/env.c; + common = grub-core/kern/err.c; + common = grub-core/kern/file.c; + common = grub-core/kern/fs.c; + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/kern/partition.c; }; library = { - name = libgrub.a; + name = libgrubmods.a; cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; @@ -66,10 +70,6 @@ library = { common = grub-core/fs/ufs2.c; common = grub-core/fs/ufs.c; common = grub-core/fs/xfs.c; - common = grub-core/kern/command.c; - common = grub-core/kern/device.c; - common = grub-core/kern/file.c; - common = grub-core/kern/fs.c; common = grub-core/lib/arg.c; common = grub-core/lib/crypto.c; common = grub-core/lib/envblk.c; @@ -99,8 +99,8 @@ library = { program = { name = grub-bin2h; common = util/bin2h.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; mansection = 1; @@ -114,8 +114,8 @@ program = { common = util/resolve.c; extra_dist = util/grub-mkimagexx.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBLZMA)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; @@ -128,8 +128,8 @@ program = { common = util/grub-mkrelpath.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -140,8 +140,8 @@ program = { common = util/grub-script-check.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -152,8 +152,8 @@ program = { common = util/grub-editenv.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -164,8 +164,8 @@ program = { common = util/grub-mkpasswd-pbkdf2.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; cflags = '$(CFLAGS_GCRY)'; @@ -184,8 +184,8 @@ program = { mansection = 1; common = util/grub-pe2elf.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL)'; condition = COND_GRUB_PE2ELF; @@ -202,8 +202,8 @@ program = { cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -216,8 +216,8 @@ program = { cflags = '$(freetype_cflags)'; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; @@ -236,8 +236,8 @@ program = { sparc64_ieee1275 = util/ieee1275/ofpath.c; sparc64_ieee1275 = util/ieee1275/devicemap.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -248,8 +248,8 @@ program = { mansection = 8; common = util/grub-probe.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -265,8 +265,8 @@ program = { sparc64_ieee1275 = util/ieee1275/ofpath.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; @@ -280,8 +280,8 @@ program = { ieee1275 = util/ieee1275/grub-ofpathname.c; ieee1275 = util/ieee1275/ofpath.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; @@ -294,8 +294,8 @@ program = { common = util/grub-mklayout.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; @@ -604,8 +604,8 @@ program = { common = grub-core/kern/misc.c; common = grub-core/tests/lib/test.c; cflags = -Wno-format; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER)'; }; @@ -617,8 +617,8 @@ program = { common = grub-core/lib/legacy_parse.c; common = grub-core/lib/i386/pc/vesa_modes_table.c; - ldadd = libgrub.a; - ldadd = libemu.a; + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; From 71574288a4727d4c32ae6bbfe14bbed055a6d7b2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 10:11:44 +0100 Subject: [PATCH 0341/1414] * docs/man/grub-set-default.h2m: Clarify that only saved default entry is modified --- ChangeLog | 5 +++++ docs/man/grub-set-default.h2m | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9401a9801..2e29b4fb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-01 Vladimir Serbinenko + + * docs/man/grub-set-default.h2m: Clarify that only saved default entry + is modified + 2010-10-29 BVK Chaitanya NetBSD build fix for getline function conflict from gnulib. diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m index 3ac13d7ed..dd0793cfd 100644 --- a/docs/man/grub-set-default.h2m +++ b/docs/man/grub-set-default.h2m @@ -1,2 +1,2 @@ [NAME] -grub-set-default \- set the default boot entry for GRUB +grub-set-default \- set the saved default boot entry for GRUB From 3a1197cdb0c8235fa4558b6c809245fcbc536fe6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 10:20:58 +0100 Subject: [PATCH 0342/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Do not put elements with invlid index. * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. * grub-core/disk/raid.c (insert_array): Automatically reallocate members. * include/grub/raid.h (grub_raid_member): New struct. (grub_raid_array): Transform devices and start_sector into usage of grub_raid_member. All users updated (allocated_devs): New member. --- ChangeLog | 12 +++++++ grub-core/disk/mdraid1x_linux.c | 12 ++++--- grub-core/disk/mdraid_linux.c | 3 ++ grub-core/disk/raid.c | 62 ++++++++++++++++++++++++--------- grub-core/disk/raid5_recover.c | 2 +- grub-core/disk/raid6_recover.c | 19 +++++----- include/grub/raid.h | 16 +++++---- 7 files changed, 88 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2e29b4fb2..bd8390286 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-11-01 Vladimir Serbinenko + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Do not put + elements with invlid index. + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. + * grub-core/disk/raid.c (insert_array): Automatically reallocate + members. + * include/grub/raid.h (grub_raid_member): New struct. + (grub_raid_array): Transform devices and start_sector into usage of + grub_raid_member. All users updated + (allocated_devs): New member. + 2010-11-01 Vladimir Serbinenko * docs/man/grub-set-default.h2m: Clarify that only saved default entry diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index 4a0298347..dd60df695 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -188,12 +188,14 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); array->disk_size = grub_le_to_cpu64 (real_sb->size); array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); - if (grub_le_to_cpu32 (real_sb->dev_number) < + + if (grub_le_to_cpu32 (real_sb->dev_number) >= grub_le_to_cpu32 (real_sb->max_dev)) - array->index = grub_le_to_cpu16 - (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); - else - array->index = 0xffff; /* disk will be later not used! */ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "spares aren't implemented"); + + array->index = grub_le_to_cpu16 + (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index 549d48355..f5cad9dbf 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -194,6 +194,9 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, sb.level != 5 && sb.level != 6 && sb.level != 10) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported RAID level: %d", sb.level); + if (sb.this_disk.number == 0xffff || sb.this_disk.number == 0xfffe) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "spares aren't implemented"); array->name = NULL; array->number = sb.md_minor; diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index c7c641ebd..f1b67a859 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -97,10 +97,10 @@ grub_raid_memberlist (grub_disk_t disk) unsigned int i; for (i = 0; i < array->total_devs; i++) - if (array->device[i]) + if (array->members[i].device) { tmp = grub_malloc (sizeof (*tmp)); - tmp->disk = array->device[i]; + tmp->disk = array->members[i].device; tmp->next = list; list = tmp; } @@ -255,13 +255,13 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, k = disknr; for (j = 0; j < far; j++) { - if (array->device[k]) + if (array->members[k].device) { if (grub_errno == GRUB_ERR_READ_ERROR) grub_errno = GRUB_ERR_NONE; - err = grub_disk_read (array->device[k], - array->start_sector[k] + + err = grub_disk_read (array->members[k].device, + array->members[k].start_sector + read_sector + j * far_ofs + b, 0, read_size << GRUB_DISK_SECTOR_BITS, @@ -367,14 +367,14 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, read_size = size; e = 0; - if (array->device[disknr]) + if (array->members[disknr].device) { /* Reset read error. */ if (grub_errno == GRUB_ERR_READ_ERROR) grub_errno = GRUB_ERR_NONE; - err = grub_disk_read (array->device[disknr], - array->start_sector[disknr] + + err = grub_disk_read (array->members[disknr].device, + array->members[disknr].start_sector + read_sector + b, 0, read_size << GRUB_DISK_SECTOR_BITS, buf); @@ -500,6 +500,21 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* Do some checks before adding the device to the array. */ + if (new_array->index >= array->allocated_devs) + { + void *tmp; + unsigned int newnum = 2 * (new_array->index + 1); + tmp = grub_realloc (array->members, newnum + * sizeof (array->members[0])); + if (!tmp) + return grub_errno; + array->members = tmp; + grub_memset (array->members + array->allocated_devs, + 0, (newnum - array->allocated_devs) + * sizeof (array->members[0])); + array->allocated_devs = newnum; + } + /* FIXME: Check whether the update time of the superblocks are the same. */ @@ -510,7 +525,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?", array->total_devs); - if (array->device[new_array->index] != NULL) + if (array->members[new_array->index].device != NULL) /* We found multiple devices with the same number. Again, this shouldn't happen. */ grub_dprintf ("raid", "Found two disks with the number %d?!?", @@ -536,8 +551,18 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, #ifdef GRUB_UTIL array->driver = raid; #endif - grub_memset (&array->device, 0, sizeof (array->device)); - grub_memset (&array->start_sector, 0, sizeof (array->start_sector)); + array->allocated_devs = 32; + if (new_array->index >= array->allocated_devs) + array->allocated_devs = 2 * (new_array->index + 1); + + array->members = grub_zalloc (array->allocated_devs + * sizeof (array->members[0])); + + if (!array->members) + { + grub_free (new_array->uuid); + return grub_errno; + } if (! array->name) { @@ -582,6 +607,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, array->name = grub_xasprintf ("md%d", array->number); if (! array->name) { + grub_free (array->members); grub_free (array->uuid); grub_free (array); @@ -597,6 +623,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, if (! new_name) { + grub_free (array->members); grub_free (array->uuid); grub_free (array); @@ -621,8 +648,8 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } /* Add the device to the array. */ - array->device[new_array->index] = disk; - array->start_sector[new_array->index] = start_sector; + array->members[new_array->index].device = disk; + array->members[new_array->index].start_sector = start_sector; array->nr_devs++; return 0; @@ -639,14 +666,15 @@ free_array (void) while (array) { struct grub_raid_array *p; - int i; + unsigned int i; p = array; array = array->next; - for (i = 0; i < GRUB_RAID_MAX_DEVICES; i++) - if (p->device[i]) - grub_disk_close (p->device[i]); + for (i = 0; i < p->allocated_devs; i++) + if (p->members[i].device) + grub_disk_close (p->members[i].device); + grub_free (p->members); grub_free (p->uuid); grub_free (p->name); diff --git a/grub-core/disk/raid5_recover.c b/grub-core/disk/raid5_recover.c index 31cef88b1..2cda67533 100644 --- a/grub-core/disk/raid5_recover.c +++ b/grub-core/disk/raid5_recover.c @@ -45,7 +45,7 @@ grub_raid5_recover (struct grub_raid_array *array, int disknr, if (i == disknr) continue; - err = grub_disk_read (array->device[i], sector, 0, size, buf2); + err = grub_disk_read (array->members[i].device, sector, 0, size, buf2); if (err) { diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index 550968ceb..01daa2c79 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -118,8 +118,9 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, bad1 = i; else { - if ((array->device[pos]) && - (! grub_disk_read (array->device[pos], sector, 0, size, buf))) + if ((array->members[pos].device) && + (! grub_disk_read (array->members[pos].device, sector, + 0, size, buf))) { grub_raid_block_xor (pbuf, buf, size); grub_raid_block_mul (raid6_table2[i][i], buf, size); @@ -148,21 +149,21 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, if (bad2 < 0) { /* One bad device */ - if ((array->device[p]) && - (! grub_disk_read (array->device[p], sector, 0, size, buf))) + if ((array->members[p].device) && + (! grub_disk_read (array->members[p].device, sector, 0, size, buf))) { grub_raid_block_xor (buf, pbuf, size); goto quit; } - if (! array->device[q]) + if (! array->members[q].device) { grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore"); goto quit; } grub_errno = GRUB_ERR_NONE; - if (grub_disk_read (array->device[q], sector, 0, size, buf)) + if (grub_disk_read (array->members[q].device, sector, 0, size, buf)) goto quit; grub_raid_block_xor (buf, qbuf, size); @@ -174,18 +175,18 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, /* Two bad devices */ grub_uint8_t c; - if ((! array->device[p]) || (! array->device[q])) + if ((! array->members[p].device) || (! array->members[q].device)) { grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore"); goto quit; } - if (grub_disk_read (array->device[p], sector, 0, size, buf)) + if (grub_disk_read (array->members[p].device, sector, 0, size, buf)) goto quit; grub_raid_block_xor (pbuf, buf, size); - if (grub_disk_read (array->device[q], sector, 0, size, buf)) + if (grub_disk_read (array->members[q].device, sector, 0, size, buf)) goto quit; grub_raid_block_xor (qbuf, buf, size); diff --git a/include/grub/raid.h b/include/grub/raid.h index b7e18b567..d5853639d 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -22,8 +22,6 @@ #include -#define GRUB_RAID_MAX_DEVICES 32 - #define GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC 0 #define GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC 1 #define GRUB_RAID_LAYOUT_LEFT_SYMMETRIC 2 @@ -32,6 +30,13 @@ #define GRUB_RAID_LAYOUT_RIGHT_MASK 1 #define GRUB_RAID_LAYOUT_SYMMETRIC_MASK 2 +struct grub_raid_member +{ + grub_disk_t device; /* Array of total_devs devices. */ + grub_disk_addr_t start_sector; + /* Start of each device, in 512 byte sectors. */ +}; + struct grub_raid_array { int number; /* The device number, taken from md_minor so we @@ -43,16 +48,15 @@ struct grub_raid_array grub_size_t chunk_size; /* The size of a chunk, in 512 byte sectors. */ grub_uint64_t disk_size; /* Size of an individual disk, in 512 byte sectors. */ - int index; /* Index of current device. */ + unsigned int index; /* Index of current device. */ int uuid_len; /* The length of uuid. */ char *uuid; /* The UUID of the device. */ /* The following field is setup by the caller. */ char *name; /* That will be "md". */ unsigned int nr_devs; /* The number of devices we've found so far. */ - grub_disk_t device[GRUB_RAID_MAX_DEVICES]; /* Array of total_devs devices. */ - grub_disk_addr_t start_sector[GRUB_RAID_MAX_DEVICES]; - /* Start of each device, in 512 byte sectors. */ + unsigned int allocated_devs; + struct grub_raid_member *members; struct grub_raid_array *next; #ifdef GRUB_UTIL From 89d68fa681a4c8bb367f46386e3c40f8889d5f84 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 12:29:20 +0100 Subject: [PATCH 0343/1414] * Makefile.am (libgrub.pp): Propagate the libgrub.a split. --- ChangeLog | 4 ++++ Makefile.am | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd8390286..d1ea981d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-01 Vladimir Serbinenko + + * Makefile.am (libgrub.pp): Propagate the libgrub.a split. + 2010-11-01 Vladimir Serbinenko * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Do not put diff --git a/Makefile.am b/Makefile.am index 15dae9642..60e041a8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,8 +33,8 @@ grub_script.yy.c: grub_script.yy.h CLEANFILES += grub_script.yy.c grub_script.yy.h # For libgrub.a -libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrub_a_SOURCES) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrub_a_CPPFLAGS) $(CPPFLAGS) \ +libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES) + $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrubmods_a_CPPFLAGS) $(libgrubkern_a_CPPFLAGS) $(CPPFLAGS) \ -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1) CLEANFILES += libgrub.pp From f8729d984a20a0bbd3d29f3cebae9524fe58c746 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 12:36:00 +0100 Subject: [PATCH 0344/1414] * util/grub.d/10_linux.in: Add missing load_video with explicit GRUB_GFXPAYLOAD_LINUX. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index d1ea981d8..96df25ede 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-01 Vladimir Serbinenko + + * util/grub.d/10_linux.in: Add missing load_video with explicit + GRUB_GFXPAYLOAD_LINUX. + 2010-11-01 Vladimir Serbinenko * Makefile.am (libgrub.pp): Propagate the libgrub.a split. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index ceee61154..5e522ba4a 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -78,6 +78,11 @@ EOF EOF fi else + if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then + cat << EOF + load_video +EOF + fi cat << EOF set gfxpayload=$GRUB_GFXPAYLOAD_LINUX EOF From 6428dec358c31142df4e9accb492d51590b99176 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 12:45:51 +0100 Subject: [PATCH 0345/1414] * grub-core/lib/arg.c (grub_arg_parse): Avoid interpreting direct argument as an argument to no-argument option. --- ChangeLog | 5 +++++ grub-core/lib/arg.c | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96df25ede..45e76b68a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-01 Vladimir Serbinenko + + * grub-core/lib/arg.c (grub_arg_parse): Avoid interpreting direct + argument as an argument to no-argument option. + 2010-11-01 Vladimir Serbinenko * util/grub.d/10_linux.in: Add missing load_video with explicit diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c index 1c765f12a..75b1dd53c 100644 --- a/grub-core/lib/arg.c +++ b/grub-core/lib/arg.c @@ -340,17 +340,20 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, } option = grub_strchr (arg, '='); - if (option) { - arglen = option - arg - 2; - option++; - } else { + if (option) + { + arglen = option - arg - 2; + option++; + } + else arglen = grub_strlen (arg) - 2; - if (argv[curarg + 1]) - option = argv[curarg + 1][0] == '-' ? 0 : argv[++curarg]; - } opt = find_long (cmd->options, arg + 2, arglen); + if (!option && argv[curarg + 1] && argv[curarg + 1][0] != '-' + && opt->type != ARG_TYPE_NONE) + option = argv[++curarg]; + if (!opt && (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH)) { if (add_arg (arg) != 0) From 74aaf558ef2f114fdeccc527d2b8d1a202467eba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 12:49:40 +0100 Subject: [PATCH 0346/1414] * util/grub.d/10_hurd.in: Don't call savedefault on recovery entries. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 7 +++++++ util/grub.d/10_hurd.in | 1 - util/grub.d/10_kfreebsd.in | 4 +++- util/grub.d/10_linux.in | 4 +++- util/grub.d/20_linux_xen.in | 4 +++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45e76b68a..20bf05920 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-11-01 Vladimir Serbinenko + + * util/grub.d/10_hurd.in: Don't call savedefault on recovery entries. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + 2010-11-01 Vladimir Serbinenko * grub-core/lib/arg.c (grub_arg_parse): Avoid interpreting direct diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 350eb30a8..6490913ae 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -107,7 +107,6 @@ EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF - save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 4d71b5a63..9cb2788df 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -76,7 +76,9 @@ kfreebsd_entry () title="$(gettext_quoted "%s, with kFreeBSD %s")" fi printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" - save_default_entry | sed -e "s/^/\t/" + if ! ${recovery} ; then + save_default_entry | sed -e "s/^/\t/" + fi if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 5e522ba4a..7650ac9fa 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -63,7 +63,9 @@ linux_entry () title="$(gettext_quoted "%s, with Linux %s")" fi printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" - save_default_entry | sed -e "s/^/\t/" + if ! ${recovery} ; then + save_default_entry | sed -e "s/^/\t/" + fi # Use ELILO's generic "efifb" when it's known to be available. # FIXME: We need an interface to select vesafb in case efifb can't be used. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index d5833070d..649ae85dd 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -65,7 +65,9 @@ linux_entry () title="$(gettext_quoted "%s, with Linux %s and XEN %s")" fi printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" "${xen_version}" - save_default_entry | sed -e "s/^/\t/" + if ! ${recovery} ; then + save_default_entry | sed -e "s/^/\t/" + fi if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" From 2b36fbf49377e4c7faeba2160e395904368d65e1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Nov 2010 13:10:51 +0100 Subject: [PATCH 0347/1414] * grub-core/loader/i386/linux.c (grub_cmd_linux): Autoload vbe.mod if vga= option is supplied. --- ChangeLog | 5 +++++ grub-core/loader/i386/linux.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 20bf05920..6c6f75ba8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-01 Vladimir Serbinenko + + * grub-core/loader/i386/linux.c (grub_cmd_linux): Autoload vbe.mod if + vga= option is supplied. + 2010-11-01 Vladimir Serbinenko * util/grub.d/10_hurd.in: Don't call savedefault on recovery entries. diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index d7622dabd..de4bec106 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -719,6 +719,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_err_t err; char *buf; + grub_dl_load ("vbe"); + if (grub_strcmp (val, "normal") == 0) vid_mode = GRUB_LINUX_VID_MODE_NORMAL; else if (grub_strcmp (val, "ext") == 0) From 33b4b0c61adaece84b4e086583c04d15206f3ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 1 Nov 2010 23:42:53 +0100 Subject: [PATCH 0348/1414] Fix an integer overflow. --- ChangeLog | 4 ++++ grub-core/partmap/bsdlabel.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6c6f75ba8..c92c49562 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-01 GrĂ©goire Sutre + + * grub-core/partmap/bsdlabel.c (iterate_real): Fix an integer overflow. + 2010-11-01 Vladimir Serbinenko * grub-core/loader/i386/linux.c (grub_cmd_linux): Autoload vbe.mod if diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index eff3bbe44..09ecd935a 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -44,7 +44,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, struct grub_partition_bsd_disk_label label; struct grub_partition p; grub_disk_addr_t delta = 0; - unsigned pos; + grub_disk_addr_t pos; /* Read the BSD label. */ if (grub_disk_read (disk, sector, 0, sizeof (label), &label)) From a75f4f62ae0a2142ee3cf49fa0b0d7c31ec1afcb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 2 Nov 2010 22:51:51 +0000 Subject: [PATCH 0349/1414] * util/bin2h.c (main): Fix spelling error in generated output. --- ChangeLog | 4 ++++ util/bin2h.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c92c49562..843056669 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-02 Colin Watson + + * util/bin2h.c (main): Fix spelling error in generated output. + 2010-11-01 GrĂ©goire Sutre * grub-core/partmap/bsdlabel.c (iterate_real): Fix an integer overflow. diff --git a/util/bin2h.c b/util/bin2h.c index e81ede8c6..ee1c7fd32 100644 --- a/util/bin2h.c +++ b/util/bin2h.c @@ -96,7 +96,7 @@ main (int argc, char *argv[]) if (b == EOF) goto abort; - printf ("/* THIS CHUNK OF BYTES IS AUTOMATICALY GENERATED */\n" + printf ("/* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */\n" "unsigned char %s[] =\n{\n", sym); while (1) From 1a3aaff40fb877607809adc26335fde56a7d7925 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 4 Nov 2010 13:58:29 +0100 Subject: [PATCH 0350/1414] 2010-11-04 Robert Millan * util/deviceiter.c (grub_util_iterate_devices): Increase SCSI limit to 48 (to cope with Sun Fire X4500), and IDE limit to 96 (its SATA disks are detected as slaveless IDE master drives on kFreeBSD). Reported by Carsten Aulbert. --- ChangeLog | 8 ++++++++ util/deviceiter.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 843056669..42100ed78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-04 Robert Millan + + * util/deviceiter.c (grub_util_iterate_devices): Increase SCSI + limit to 48 (to cope with Sun Fire X4500), and IDE limit to 96 + (its SATA disks are detected as slaveless IDE master drives on + kFreeBSD). + Reported by Carsten Aulbert. + 2010-11-02 Colin Watson * util/bin2h.c (main): Fix spelling error in generated output. diff --git a/util/deviceiter.c b/util/deviceiter.c index 1cf511934..34d34b7bb 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -601,7 +601,7 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), #endif /* __linux__ */ /* IDE disks. */ - for (i = 0; i < 26; i++) + for (i = 0; i < 96; i++) { char name[16]; @@ -655,7 +655,7 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), #endif /* __linux__ */ /* The rest is SCSI disks. */ - for (i = 0; i < 26; i++) + for (i = 0; i < 48; i++) { char name[16]; From b9b3839f6dcbac86a86472496397b076445b62f9 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 5 Nov 2010 19:48:55 +0100 Subject: [PATCH 0351/1414] 2010-11-05 Robert Millan On Yeeloong, pass machine type information to Linux. * grub-core/loader/mips/linux.c [GRUB_MACHINE_MIPS_YEELOONG] (LOONGSON_MACHTYPE): New macro, set to "machtype=lemote-yeeloong-2f-8.9inches". [LOONGSON_MACHTYPE] (grub_cmd_linux): Pass LOONGSON_MACHTYPE as additional argument to Linux. --- ChangeLog | 10 ++++++++++ grub-core/loader/mips/linux.c | 26 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 42100ed78..d9d2ebbe5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-11-05 Robert Millan + + On Yeeloong, pass machine type information to Linux. + + * grub-core/loader/mips/linux.c [GRUB_MACHINE_MIPS_YEELOONG] + (LOONGSON_MACHTYPE): New macro, set to + "machtype=lemote-yeeloong-2f-8.9inches". + [LOONGSON_MACHTYPE] (grub_cmd_linux): Pass LOONGSON_MACHTYPE as + additional argument to Linux. + 2010-11-04 Robert Millan * util/deviceiter.c (grub_util_iterate_devices): Increase SCSI diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 44ab64eb5..7b1836982 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -32,6 +32,14 @@ #include #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" +#endif + static grub_dl_t my_mod; static int loaded; @@ -214,6 +222,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* For arguments. */ linux_argc = argc; +#ifdef LOONGSON_MACHTYPE + linux_argc++; +#endif /* Main arguments. */ size = (linux_argc) * sizeof (grub_uint32_t); /* Initrd address and size. */ @@ -226,7 +237,10 @@ 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); +#endif + /* rd arguments. */ size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); @@ -263,6 +277,16 @@ 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); +#endif + for (i = 1; i < argc; i++) { grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); From 6c9e4c0c8940cdd5160cd526ca28ab33630f021c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 5 Nov 2010 22:56:14 +0100 Subject: [PATCH 0352/1414] 2010-11-05 Robert Millan * util/grub-mkconfig.in: Remove gfxterm.mod probe (no longer needed). --- ChangeLog | 5 +++++ util/grub-mkconfig.in | 14 -------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d9d2ebbe5..906ebec69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-05 Robert Millan + + * util/grub-mkconfig.in: Remove gfxterm.mod probe (no longer + needed). + 2010-11-05 Robert Millan On Yeeloong, pass machine type information to Linux. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index b59911cd0..73f730131 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -168,20 +168,6 @@ fi for x in ${GRUB_TERMINAL_OUTPUT}; do if [ "x${x}" = "xgfxterm" ]; then - # If this platform supports gfxterm, try to use it. - if ! test -e ${GRUB_PREFIX}/gfxterm.mod ; then - if [ "x$termoutdefault" != "x1" ]; then - echo "gfxterm isn't available on your platform" >&2 ; exit 1 - fi - GRUB_TERMINAL_OUTPUT= - break; - fi - if [ ! -s "${GRUB_PREFIX}/video.lst" ] ; then - if [ "x$termoutdefault" != "x1" ]; then - echo "No suitable backend could be found for gfxterm." >&2 ; exit 1 - fi - GRUB_TERMINAL_OUTPUT= - fi if [ -n "$GRUB_FONT" ] ; then if is_path_readable_by_grub ${GRUB_FONT} > /dev/null ; then GRUB_FONT_PATH=${GRUB_FONT} From 9c693bd66a9546a6000c2b7151f9f62e6074f28b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Nov 2010 20:40:08 +0100 Subject: [PATCH 0353/1414] Properly register serial terminfo. Reported by: Jordan Uggla * grub-core/term/serial.c (grub_serial_terminfo_input_template): New const. (grub_serial_terminfo_output_template): Likewise. (grub_cmd_serial): Register "serial" with terminfo. (GRUB_MOD_INIT(serial)): Fill grub_serial_terminfo_input and grub_serial_terminfo_output. --- ChangeLog | 12 ++++++++++++ grub-core/term/serial.c | 18 ++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 906ebec69..5185bb380 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-11-06 Vladimir Serbinenko + + Properly register serial terminfo. + Reported by: Jordan Uggla + + * grub-core/term/serial.c (grub_serial_terminfo_input_template): New + const. + (grub_serial_terminfo_output_template): Likewise. + (grub_cmd_serial): Register "serial" with terminfo. + (GRUB_MOD_INIT(serial)): Fill grub_serial_terminfo_input and + grub_serial_terminfo_output. + 2010-11-05 Robert Millan * util/grub-mkconfig.in: Remove gfxterm.mod probe (no longer diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 1ef17aa25..d36388359 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -69,7 +69,7 @@ serial_fetch (grub_term_input_t term) return data->port->driver->fetch (data->port); } -struct grub_serial_input_state grub_serial_terminfo_input = +const struct grub_serial_input_state grub_serial_terminfo_input_template = { .tinfo = { @@ -77,7 +77,7 @@ struct grub_serial_input_state grub_serial_terminfo_input = } }; -struct grub_serial_output_state grub_serial_terminfo_output = +const struct grub_serial_output_state grub_serial_terminfo_output_template = { .tinfo = { @@ -87,6 +87,10 @@ struct grub_serial_output_state grub_serial_terminfo_output = } }; +struct grub_serial_input_state grub_serial_terminfo_input; + +struct grub_serial_output_state grub_serial_terminfo_output; + int registered = 0; static struct grub_term_input grub_serial_term_input = @@ -216,6 +220,8 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) { if (!registered) { + grub_terminfo_output_register (&grub_serial_term_output, "vt100"); + grub_term_register_input ("serial", &grub_serial_term_input); grub_term_register_output ("serial", &grub_serial_term_output); } @@ -337,6 +343,14 @@ GRUB_MOD_INIT(serial) cmd = grub_register_extcmd ("serial", grub_cmd_serial, 0, N_("[OPTIONS...]"), N_("Configure serial port."), options); + grub_memcpy (&grub_serial_terminfo_output, + &grub_serial_terminfo_output_template, + sizeof (grub_serial_terminfo_output)); + + grub_memcpy (&grub_serial_terminfo_input, + &grub_serial_terminfo_input_template, + sizeof (grub_serial_terminfo_input)); + #ifndef GRUB_MACHINE_EMU grub_ns8250_init (); #endif From 6972dea93712cacfd20c13a1c7eb7382e574ee36 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Nov 2010 21:37:13 +0100 Subject: [PATCH 0354/1414] * util/grub-install.in: Replace useless recomendation to pass --modules with a recomendation to report a bug. --- ChangeLog | 5 +++++ util/grub-install.in | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5185bb380..8dea7854c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-06 Vladimir Serbinenko + + * util/grub-install.in: Replace useless recomendation to pass + --modules with a recomendation to report a bug. + 2010-11-06 Vladimir Serbinenko Properly register serial terminfo. diff --git a/util/grub-install.in b/util/grub-install.in index 8b0f5ebe1..20b3cab46 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -466,9 +466,9 @@ fi # Create the core image. First, auto-detect the filesystem module. fs_module=`$grub_probe --target=fs --device ${grub_device}` -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 +if test "x$fs_module" = x ; then + echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2 + echo "Please report this together with the output of \"$grub_probe --target=fs -v ${grubdir}\" to " 1>&2 exit 1 fi From 34706ddc061427713d45894d4a54498461df92ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Nov 2010 21:54:24 +0100 Subject: [PATCH 0355/1414] * grub-core/fs/ntfs.c (grub_ntfs_uuid): Make uppercase. --- ChangeLog | 4 ++++ grub-core/fs/ntfs.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8dea7854c..24ef00f8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-06 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (grub_ntfs_uuid): Make uppercase. + 2010-11-06 Vladimir Serbinenko * util/grub-install.in: Replace useless recomendation to pass diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index dd041e23a..414f6513d 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -1072,7 +1072,11 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) data = grub_ntfs_mount (disk); if (data) { + char *ptr; *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid); + if (*uuid) + for (ptr = *uuid; *ptr; ptr++) + *ptr = grub_toupper (*ptr); } else *uuid = NULL; From 4a1a0153c347f378ee9c43527ca8233bcd21ee1c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Nov 2010 23:52:56 +0100 Subject: [PATCH 0356/1414] * include/grub/emu/misc.h: Don't include grub/util/libzfs.h. * include/grub/emu/misc.h (grub_get_libzfs_handle): Move from here ... * include/grub/util/libzfs.h (grub_get_libzfs_handle): ... here. --- ChangeLog | 6 ++++++ include/grub/emu/misc.h | 3 --- include/grub/util/libzfs.h | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24ef00f8d..e7ffe6403 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-06 Vladimir Serbinenko + + * include/grub/emu/misc.h: Don't include grub/util/libzfs.h. + * include/grub/emu/misc.h (grub_get_libzfs_handle): Move from here ... + * include/grub/util/libzfs.h (grub_get_libzfs_handle): ... here. + 2010-11-06 Vladimir Serbinenko * grub-core/fs/ntfs.c (grub_ntfs_uuid): Make uppercase. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 47a80d3d7..ef0d18300 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -24,7 +24,6 @@ #include #include -#include #ifdef __CYGWIN__ # include @@ -79,6 +78,4 @@ extern char * canonicalize_file_name (const char *path); int grub_device_mapper_supported (void); #endif -libzfs_handle_t *grub_get_libzfs_handle (void); - #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/util/libzfs.h b/include/grub/util/libzfs.h index 0500f70d7..a02caa335 100644 --- a/include/grub/util/libzfs.h +++ b/include/grub/util/libzfs.h @@ -42,4 +42,6 @@ extern nvlist_t *zpool_get_config (zpool_handle_t *, nvlist_t **); #endif /* ! HAVE_LIBZFS_H */ +libzfs_handle_t *grub_get_libzfs_handle (void); + #endif From 80c6d25eef6eb48a2c349b19ddb1b33d70333ebe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Nov 2010 00:10:49 +0100 Subject: [PATCH 0357/1414] * grub-core/kern/emu/hostdisk.c (convert_system_partition_to_system_disk): Handle devices like "sdaa1". --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7ffe6403..9faa0121d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-07 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c + (convert_system_partition_to_system_disk): Handle devices like "sdaa1". + 2010-11-06 Vladimir Serbinenko * include/grub/emu/misc.h: Don't include grub/util/libzfs.h. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 08f60ee66..12dbe7469 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1152,16 +1152,22 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) || strncmp ("sd", p, 2) == 0) && p[2] >= 'a' && p[2] <= 'z') { - /* /dev/[hsv]d[a-z][0-9]* */ - p[3] = '\0'; + char *pp = p + 2; + while (*pp >= 'a' && *pp <= 'z') + pp++; + /* /dev/[hsv]d[a-z]+[0-9]* */ + *pp = '\0'; return path; } /* If this is a Xen virtual block device. */ if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z') { - /* /dev/xvd[a-z][0-9]* */ - p[4] = '\0'; + char *pp = p + 3; + while (*pp >= 'a' && *pp <= 'z') + pp++; + /* /dev/xvd[a-z]+[0-9]* */ + *pp = '\0'; return path; } From a8152fedabb1bf042432dcc4a17b473f8a9b3199 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 7 Nov 2010 16:13:14 +0530 Subject: [PATCH 0358/1414] suppress shell expansion inside quoted strings --- grub-core/script/execute.c | 2 +- tests/grub_cmd_echo.in | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index d859a13bd..72d199760 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -374,7 +374,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, case GRUB_SCRIPT_ARG_TYPE_DQSTR: case GRUB_SCRIPT_ARG_TYPE_SQSTR: - if (grub_script_argv_append (&result, arg->str)) + if (append (arg->str, 1)) goto fail; break; } diff --git a/tests/grub_cmd_echo.in b/tests/grub_cmd_echo.in index 6ac33f55e..902696778 100644 --- a/tests/grub_cmd_echo.in +++ b/tests/grub_cmd_echo.in @@ -31,3 +31,11 @@ echo foo -n echo foo -n -e echo ------- + +if test -n "$grubshell"; then insmod regexp; fi + +echo '*' +echo "*" + +foo="*" +echo "$foo" From 898c99a2c35f2d874c14b8e225ed36982e724adb Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 7 Nov 2010 16:18:29 +0530 Subject: [PATCH 0359/1414] add changelog entry --- ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index c92c49562..71f0f9fa2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-11-07 BVK Chaitanya + + Suppress shell expansion on echo '*' and echo "*" like cases, + reported by Jordan Uggla. + + * grub-core/script/execute.c (grub_script_arglist_to_argv): Escape + string arguments before shell expansion. + * tests/grub_cmd_echo.in: New testcases. + 2010-11-01 GrĂ©goire Sutre * grub-core/partmap/bsdlabel.c (iterate_real): Fix an integer overflow. From 4f9b406ae3cd91636e14a9d3c10be1d3f3cfb44f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 7 Nov 2010 15:10:09 +0100 Subject: [PATCH 0360/1414] 2010-11-07 Robert Millan * conf/mips-qemu-mips.rmk: Remove stale file from previous transition. --- ChangeLog | 5 +++++ conf/mips-qemu-mips.rmk | 28 ---------------------------- 2 files changed, 5 insertions(+), 28 deletions(-) delete mode 100644 conf/mips-qemu-mips.rmk diff --git a/ChangeLog b/ChangeLog index 9faa0121d..764dffc4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-07 Robert Millan + + * conf/mips-qemu-mips.rmk: Remove stale file from previous + transition. + 2010-11-07 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk deleted file mode 100644 index be2b9f555..000000000 --- a/conf/mips-qemu-mips.rmk +++ /dev/null @@ -1,28 +0,0 @@ -# -*- makefile -*- -LINK_BASE = 0x80010000 -target_machine=qemu-mips -COMMON_CFLAGS += -march=mips3 -COMMON_ASFLAGS += -march=mips3 -include $(srcdir)/conf/mips.mk - -pkglib_PROGRAMS = kernel.img -kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ - kern/main.c kern/device.c kern/$(target_cpu)/init.c \ - kern/$(target_cpu)/$(target_machine)/init.c \ - kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ - kern/misc.c kern/mm.c kern/term.c \ - kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/command.c kern/corecmd.c \ - kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ - kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ - symlist.c kern/$(target_cpu)/cache.S -kernel_img_CFLAGS = $(COMMON_CFLAGS) -kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic -kernel_img_FORMAT = binary - -# For serial.mod. -pkglib_MODULES += serial.mod -serial_mod_SOURCES = term/serial.c -serial_mod_CFLAGS = $(COMMON_CFLAGS) -serial_mod_LDFLAGS = $(COMMON_LDFLAGS) From d2bf06bf34d094ebbb188930ab468f0a8fcc6913 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 7 Nov 2010 16:29:10 +0100 Subject: [PATCH 0361/1414] 2010-11-07 Robert Millan On mips-yeeloong, build with -march=loongson2f when this flag is available (GCC >= 4.4). * conf/Makefile.common [COND_mips_yeeloong] (CFLAGS_PLATFORM): Remove `-march=mips3'. * configure.ac: For mips-yeeloong, add -march=loongson2f if available, or otherwise add -march=mips3. --- ChangeLog | 9 +++++++++ conf/Makefile.common | 2 +- configure.ac | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a35961641..79138e8c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-11-07 Robert Millan + + On mips-yeeloong, build with -march=loongson2f when this flag is + available (GCC >= 4.4). + * conf/Makefile.common [COND_mips_yeeloong] (CFLAGS_PLATFORM): Remove + `-march=mips3'. + * configure.ac: For mips-yeeloong, add -march=loongson2f if available, + or otherwise add -march=mips3. + 2010-11-07 BVK Chaitanya Suppress shell expansion on echo '*' and echo "*" like cases. diff --git a/conf/Makefile.common b/conf/Makefile.common index 32851e34e..a3ccebcc5 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -22,7 +22,7 @@ if COND_i386_ieee1275 CFLAGS_PLATFORM += -mrtd -mregparm=3 endif if COND_mips_yeeloong - CFLAGS_PLATFORM += -march=mips3 -mexplicit-relocs + CFLAGS_PLATFORM += -mexplicit-relocs CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK CCASFLAGS_PLATFORM = -march=mips3 endif diff --git a/configure.ac b/configure.ac index 66d4a6877..1ad3a8e98 100644 --- a/configure.ac +++ b/configure.ac @@ -401,6 +401,23 @@ 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 + AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [ + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -march=loongson2f" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_march_loongson2f=yes], + [grub_cv_cc_march_loongson2f=no]) + CFLAGS="$SAVE_CFLAGS" + ]) + + if test "x$grub_cv_cc_march_loongson2f" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -march=loongson2f" + else + TARGET_CFLAGS="$TARGET_CFLAGS -march=mips3" + fi +fi + grub_apple_target_cc if test x$grub_cv_apple_target_cc = xyes ; then TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1" From 9c4cf53bfea11d804cceba596257f4a2f2cf0830 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Mon, 8 Nov 2010 11:14:54 -0200 Subject: [PATCH 0362/1414] 2010-11-08 Manoel Rebelo Abranches * include/grub/elfload.h (grub_elf32_size): New parameter. All users updated. Return maximum segments alignment. (grub_elf64_size): Likewise. * kern/elf.c (grub_elf32_size): New parameter. All users updated. Return maximum segments alignment. (grub_elf64_size): Likewise. * grub-core/loader/powerpc/ieee1275/linux.c: (grub_linux_claimmap_iterate): New function. Uses the "available"property in the "memory" node for memory allocation for kernel in the PowerPC loader. (grub_linux_load32): Correctly find linux entry point offset. (grub_linux_load64): Likewise. --- ChangeLog | 14 +++ grub-core/kern/elf.c | 20 ++-- grub-core/loader/mips/linux.c | 4 +- grub-core/loader/powerpc/ieee1275/linux.c | 133 +++++++++++++--------- grub-core/loader/sparc64/ieee1275/linux.c | 2 +- include/grub/elfload.h | 4 +- 6 files changed, 110 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79138e8c7..86b3f30a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-11-08 Manoel Rebelo Abranches + + * include/grub/elfload.h (grub_elf32_size): New parameter. All users updated. + Return maximum segments alignment. + (grub_elf64_size): Likewise. + * kern/elf.c (grub_elf32_size): New parameter. All users updated. + Return maximum segments alignment. + (grub_elf64_size): Likewise. + * grub-core/loader/powerpc/ieee1275/linux.c: + (grub_linux_claimmap_iterate): New function. Uses the "available"property + in the "memory" node for memory allocation for kernel in the PowerPC loader. + (grub_linux_load32): Correctly find linux entry point offset. + (grub_linux_load64): Likewise. + 2010-11-07 Robert Millan On mips-yeeloong, build with -march=loongson2f when this flag is diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c index 4be408c31..56218b4e4 100644 --- a/grub-core/kern/elf.c +++ b/grub-core/kern/elf.c @@ -171,11 +171,12 @@ grub_elf32_phdr_iterate (grub_elf_t elf, /* Calculate the amount of memory spanned by the segments. */ grub_size_t -grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) +grub_elf32_size (grub_elf_t elf, Elf32_Addr *base, grub_uint32_t *max_align) { Elf32_Addr segments_start = (Elf32_Addr) -1; Elf32_Addr segments_end = 0; int nr_phdrs = 0; + grub_uint32_t curr_align = 1; /* Run through the program headers to calculate the total memory size we * should claim. */ @@ -192,6 +193,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) segments_start = phdr->p_paddr; if (phdr->p_paddr + phdr->p_memsz > segments_end) segments_end = phdr->p_paddr + phdr->p_memsz; + if (curr_align < phdr->p_align) + curr_align = phdr->p_align; return 0; } @@ -215,7 +218,8 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) if (base) *base = segments_start; - + if (max_align) + *max_align = curr_align; return segments_end - segments_start; } @@ -290,7 +294,6 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, return err; } - /* 64-bit */ @@ -357,16 +360,17 @@ grub_elf64_phdr_iterate (grub_elf_t elf, /* Calculate the amount of memory spanned by the segments. */ grub_size_t -grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) +grub_elf64_size (grub_elf_t elf, Elf64_Addr *base, grub_uint64_t *max_align) { Elf64_Addr segments_start = (Elf64_Addr) -1; Elf64_Addr segments_end = 0; int nr_phdrs = 0; + grub_uint64_t curr_align = 1; /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), Elf64_Phdr *phdr, void *_arg __attribute__ ((unused))) { @@ -378,6 +382,8 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) segments_start = phdr->p_paddr; if (phdr->p_paddr + phdr->p_memsz > segments_end) segments_end = phdr->p_paddr + phdr->p_memsz; + if (curr_align < phdr->p_align) + curr_align = phdr->p_align; return 0; } @@ -401,11 +407,11 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) if (base) *base = segments_start; - + if (max_align) + *max_align = curr_align; return segments_end - segments_start; } - /* Load every loadable segment into memory specified by `_load_hook'. */ grub_err_t grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook, diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 7b1836982..6ae2a9321 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -91,7 +91,7 @@ grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size) /* Linux's entry point incorrectly contains a virtual address. */ entry_addr = elf->ehdr.ehdr32.e_entry; - linux_size = grub_elf32_size (elf, &base); + linux_size = grub_elf32_size (elf, &base, 0); if (linux_size == 0) return grub_errno; target_addr = base; @@ -146,7 +146,7 @@ grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size) /* Linux's entry point incorrectly contains a virtual address. */ entry_addr = elf->ehdr.ehdr64.e_entry; - linux_size = grub_elf64_size (elf, &base); + linux_size = grub_elf64_size (elf, &base, 0); if (linux_size == 0) return grub_errno; target_addr = base; diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c index 249238d45..231aec1d3 100644 --- a/grub-core/loader/powerpc/ieee1275/linux.c +++ b/grub-core/loader/powerpc/ieee1275/linux.c @@ -26,6 +26,7 @@ #include #include #include +#include #define ELF32_LOADMASK (0xc0000000UL) #define ELF64_LOADMASK (0xc000000000000000ULL) @@ -45,6 +46,51 @@ static char *linux_args; typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), unsigned long, unsigned long); +static grub_addr_t +grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, + grub_size_t align) +{ + grub_addr_t found_addr = (grub_addr_t) -1; + + auto int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type); + int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type) + { + grub_uint64_t end = addr + len; + addr = ALIGN_UP (addr, align); + target = ALIGN_UP (target, align); + + /* Target above the memory chunk. */ + if (type != GRUB_MEMORY_AVAILABLE || target > end) + return 0; + + /* Target inside the memory chunk. */ + if (target >= addr && target < end && size <= end - target) + { + if (grub_claimmap (target, size) == GRUB_ERR_NONE) + { + found_addr = target; + return 1; + } + } + /* Target below the memory chunk. */ + if (target < addr && addr + size <= end) + { + if (grub_claimmap (addr, size) == GRUB_ERR_NONE) + { + found_addr = addr; + return 1; + } + } + return 0; + } + + grub_machine_mmap_iterate (alloc_mem); + + return found_addr; +} + static grub_err_t grub_linux_boot (void) { @@ -102,34 +148,30 @@ grub_linux_unload (void) static grub_err_t grub_linux_load32 (grub_elf_t elf) { - Elf32_Addr entry; - int found_addr = 0; + Elf32_Addr base_addr; + grub_addr_t seg_addr; + grub_uint32_t align; + int offset; - /* Linux's entry point incorrectly contains a virtual address. */ - entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK; - if (entry == 0) - entry = 0x01400000; - - linux_size = grub_elf32_size (elf, 0); + linux_size = grub_elf32_size (elf, &base_addr, &align); if (linux_size == 0) return grub_errno; /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; + offset = elf->ehdr.ehdr32.e_entry - base_addr; + /* Linux's incorrectly contains a virtual address. */ + base_addr &= ~ELF32_LOADMASK; + /* On some systems, firmware occupies the memory we're trying to use. * Happily, Linux can be loaded anywhere (it relocates itself). Iterate * until we find an open area. */ - for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000) - { - grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", - linux_addr, linux_size); - found_addr = grub_claimmap (linux_addr, linux_size); - if (found_addr != -1) - break; - } - if (found_addr == -1) + seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF32_LOADMASK, linux_size, align); + if (seg_addr == (grub_addr_t) -1) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); + linux_addr = seg_addr + offset; + /* Now load the segments into the area we claimed. */ auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load) @@ -141,9 +183,7 @@ grub_linux_load32 (grub_elf_t elf) } *do_load = 1; - /* Linux's program headers incorrectly contain virtual addresses. - * Translate those to physical, and offset to the area we claimed. */ - *addr = (phdr->p_paddr & ~ELF32_LOADMASK) + linux_addr; + *addr = (phdr->p_paddr - base_addr) + seg_addr; return 0; } return grub_elf32_load (elf, offset_phdr, 0, 0); @@ -152,34 +192,30 @@ grub_linux_load32 (grub_elf_t elf) static grub_err_t grub_linux_load64 (grub_elf_t elf) { - Elf64_Addr entry; - int found_addr = 0; + Elf64_Addr base_addr; + grub_addr_t seg_addr; + grub_uint64_t align; + int offset; - /* Linux's entry point incorrectly contains a virtual address. */ - entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK; - if (entry == 0) - entry = 0x01400000; - - linux_size = grub_elf64_size (elf, 0); + linux_size = grub_elf64_size (elf, &base_addr, &align); if (linux_size == 0) return grub_errno; /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; + offset = elf->ehdr.ehdr64.e_entry - base_addr; + /* Linux's incorrectly contains a virtual address. */ + base_addr &= ~ELF64_LOADMASK; + /* On some systems, firmware occupies the memory we're trying to use. * Happily, Linux can be loaded anywhere (it relocates itself). Iterate * until we find an open area. */ - for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000) - { - grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", - linux_addr, linux_size); - found_addr = grub_claimmap (linux_addr, linux_size); - if (found_addr != -1) - break; - } - if (found_addr == -1) + seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF64_LOADMASK, linux_size, align); + if (seg_addr == (grub_addr_t) -1) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); + linux_addr = seg_addr + offset; + /* Now load the segments into the area we claimed. */ auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load) @@ -190,9 +226,8 @@ grub_linux_load64 (grub_elf_t elf) return 0; } *do_load = 1; - /* Linux's program headers incorrectly contain virtual addresses. - * Translate those to physical, and offset to the area we claimed. */ - *addr = (phdr->p_paddr & ~ELF64_LOADMASK) + linux_addr; + + *addr = (phdr->p_paddr - base_addr) + seg_addr; return 0; } return grub_elf64_load (elf, offset_phdr, 0, 0); @@ -287,7 +322,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_ssize_t size; grub_addr_t first_addr; grub_addr_t addr; - int found_addr = 0; if (argc == 0) { @@ -311,20 +345,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), /* Attempt to claim at a series of addresses until successful in the same way that grub_rescue_cmd_linux does. */ - for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000) - { - grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", - addr, size); - found_addr = grub_claimmap (addr, size); - if (found_addr != -1) - break; - } - - if (found_addr == -1) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot claim memory"); - goto fail; - } + addr = grub_linux_claimmap_iterate (first_addr, size, 0x100000); + if (addr == (grub_addr_t) -1) + goto fail; grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c index d4b5f2aea..8ea96f1c9 100644 --- a/grub-core/loader/sparc64/ieee1275/linux.c +++ b/grub-core/loader/sparc64/ieee1275/linux.c @@ -247,7 +247,7 @@ grub_linux_load64 (grub_elf_t elf) linux_entry = elf->ehdr.ehdr64.e_entry; linux_addr = 0x40004000; off = 0x4000; - linux_size = grub_elf64_size (elf, 0); + linux_size = grub_elf64_size (elf, 0, 0); if (linux_size == 0) return grub_errno; diff --git a/include/grub/elfload.h b/include/grub/elfload.h index 83fb9128a..579656f23 100644 --- a/include/grub/elfload.h +++ b/include/grub/elfload.h @@ -46,12 +46,12 @@ grub_elf_t grub_elf_file (grub_file_t); grub_err_t grub_elf_close (grub_elf_t); int grub_elf_is_elf32 (grub_elf_t); -grub_size_t grub_elf32_size (grub_elf_t, Elf32_Addr *); +grub_size_t grub_elf32_size (grub_elf_t, Elf32_Addr *, grub_uint32_t *); grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *, grub_size_t *); int grub_elf_is_elf64 (grub_elf_t); -grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *); +grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *, grub_uint64_t *); grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *, grub_size_t *); grub_err_t From c0e103e4dacffd9d9348cc753eaf89405564df98 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Nov 2010 16:51:50 +0100 Subject: [PATCH 0363/1414] 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 10001ac54bcd246e98a8894f59d40102f286f1a1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 12 Nov 2010 08:45:16 +0100 Subject: [PATCH 0364/1414] * grub-core/kern/i386/pc/startup.S (multiboot_trampoline): Add missing jump. --- ChangeLog | 13 ++++++++++--- grub-core/kern/i386/pc/startup.S | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 86b3f30a3..6120e9e65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,21 @@ +2010-11-12 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S (multiboot_trampoline): Add missing + jump. + 2010-11-08 Manoel Rebelo Abranches - * include/grub/elfload.h (grub_elf32_size): New parameter. All users updated. + * include/grub/elfload.h (grub_elf32_size): New parameter. + All users updated. Return maximum segments alignment. (grub_elf64_size): Likewise. * kern/elf.c (grub_elf32_size): New parameter. All users updated. Return maximum segments alignment. (grub_elf64_size): Likewise. * grub-core/loader/powerpc/ieee1275/linux.c: - (grub_linux_claimmap_iterate): New function. Uses the "available"property - in the "memory" node for memory allocation for kernel in the PowerPC loader. + (grub_linux_claimmap_iterate): New function. Uses the + "available" property in the "memory" node for memory allocation + for kernel in the PowerPC loader. (grub_linux_load32): Correctly find linux entry point offset. (grub_linux_load64): Likewise. diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 6b43d9f14..d089a3e15 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -224,6 +224,7 @@ multiboot_trampoline: movb $0xFF, %dh /* enter the usual booting */ call prot_to_real + jmp LOCAL (codestart) post_reed_solomon: From 7625a68ebb3043a4196031cc9fa16108d141e623 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 15:56:23 +0100 Subject: [PATCH 0365/1414] * docs/grub.texi (menu): Correct the order. Reported by: D. Hugh Redelmeier. --- ChangeLog | 5 +++++ docs/grub.texi | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6120e9e65..227be40ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-13 Vladimir Serbinenko + + * docs/grub.texi (menu): Correct the order. + Reported by: D. Hugh Redelmeier. + 2010-11-12 Vladimir Serbinenko * grub-core/kern/i386/pc/startup.S (multiboot_trampoline): Add missing diff --git a/docs/grub.texi b/docs/grub.texi index b37a5bfac..bdbbb9329 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -109,8 +109,8 @@ This edition documents version @value{VERSION}. @menu * Overview:: What exactly GRUB is and how to use it * History:: From maggot to house fly -* Features:: GRUB features * Changes from GRUB Legacy:: Differences from previous versions +* Features:: GRUB features * Role of a boot loader:: The role of a boot loader @end menu From 4417aae6b76c32d377a86db32f09fdecdf44ec3b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 16:00:39 +0100 Subject: [PATCH 0366/1414] * util/grub-mkconfig.in (grub_script_check): New variable. Use grub_script_check instead of grub-script-check. Reported by: Barry Jackson. --- ChangeLog | 6 ++++++ util/grub-mkconfig.in | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 227be40ce..e6d7b410a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-13 Vladimir Serbinenko + + * util/grub-mkconfig.in (grub_script_check): New variable. + Use grub_script_check instead of grub-script-check. + Reported by: Barry Jackson. + 2010-11-13 Vladimir Serbinenko * docs/grub.texi (menu): Correct the order. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 73f730131..2fcc715c2 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -22,6 +22,7 @@ transform="@program_transform_name@" prefix=@prefix@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ +bindir=@bindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ PACKAGE_NAME=@PACKAGE_NAME@ @@ -35,8 +36,9 @@ grub_mkconfig_dir=${sysconfdir}/grub.d self=`basename $0` -grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` -grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | "sed ${transform}"` +grub_probe=${sbindir}/`echo grub-probe | sed "${transform}"` +grub_script_check="${bindir}/`echo grub-script-check | sed "${transform}"`" GRUB_PREFIX=`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"` @@ -290,7 +292,7 @@ for i in ${grub_mkconfig_dir}/* ; do done if test "x${grub_cfg}" != "x" ; then - if ! grub-script-check ${grub_cfg}.new; then + if ! ${grub_script_check} ${grub_cfg}.new; then echo "Syntax errors are detected in generated GRUB config file." >&2 echo "Ensure that there are no errors in /etc/default/grub" >&2 echo "and /etc/grub.d/* files or please file a bug report with" >&2 From 5f0c02b3d8272ba2cda3dd14060149a05e96e60f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 16:03:29 +0100 Subject: [PATCH 0367/1414] * util/grub-install.in: Handle filenames containing spaces. Reported by: Jordan Uggla. Tested by: Jordan Uggla. --- ChangeLog | 6 ++ util/grub-install.in | 215 +++++++++++++++++++++---------------------- 2 files changed, 112 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index e6d7b410a..03ff87f74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-13 Vladimir Serbinenko + + * util/grub-install.in: Handle filenames containing spaces. + Reported by: Jordan Uggla. + Tested by: Jordan Uggla. + 2010-11-13 Vladimir Serbinenko * util/grub-mkconfig.in (grub_script_check): New variable. diff --git a/util/grub-install.in b/util/grub-install.in index 20b3cab46..52f17bfa2 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -19,32 +19,32 @@ # Initialize some variables. transform="@program_transform_name@" -prefix=@prefix@ -exec_prefix=@exec_prefix@ -sbindir=@sbindir@ -bindir=@bindir@ -libdir=@libdir@ -sysconfdir=@sysconfdir@ +prefix="@prefix@" +exec_prefix="@exec_prefix@" +sbindir="@sbindir@" +bindir="@bindir@" +libdir="@libdir@" +sysconfdir="@sysconfdir@" 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 +pkglibdir="${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`" +localedir="@datadir@/locale" -self=`basename $0` +self="`basename $0`" -grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` -grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` -grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` -grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` +grub_setup="${sbindir}/`echo grub-setup | sed ${transform}`" +grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" +grub_mkdevicemap="${sbindir}/`echo grub-mkdevicemap | sed ${transform}`" +grub_probe="${sbindir}/`echo grub-probe | sed ${transform}`" +grub_editenv="${bindir}/`echo grub-editenv | sed ${transform}`" +grub_mkrelpath="${bindir}/`echo grub-mkrelpath | sed ${transform}`" rootdir= bootdir= -grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` +grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`" modules= install_device= @@ -56,15 +56,15 @@ debug_image= update_nvram=yes -ofpathname=`which ofpathname` -nvsetenv=`which nvsetenv` -efibootmgr=`which efibootmgr 2>/dev/null || true` +ofpathname="`which ofpathname`" +nvsetenv="`which nvsetenv`" +efibootmgr="`which efibootmgr 2>/dev/null || true`" removable=no efi_quiet= # Get GRUB_DISTRIBUTOR. -if test -f ${sysconfdir}/default/grub ; then - . ${sysconfdir}/default/grub +if test -f "${sysconfdir}/default/grub" ; then + . "${sysconfdir}/default/grub" fi bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut -d' ' -f1)" @@ -140,14 +140,14 @@ EOF } argument () { - opt=$1 + opt="$1" shift if test $# -eq 0; then echo "$0: option requires an argument -- '$opt'" 1>&2 exit 1 fi - echo $1 + echo "$1" } allow_floppy="" @@ -179,44 +179,44 @@ do # Accept for compatibility --root-directory) - rootdir=`argument $option "$@"`; shift;; + rootdir="`argument $option "$@"`"; shift;; --root-directory=*) - rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + rootdir="`echo "$option" | sed 's/--root-directory=//'`" ;; --boot-directory) - bootdir=`argument $option "$@"`; shift;; + bootdir="`argument $option "$@"`"; shift;; --boot-directory=*) - bootdir=`echo "$option" | sed 's/--boot-directory=//'` ;; + bootdir="`echo "$option" | sed 's/--boot-directory=//'`" ;; --grub-setup) - grub_setup=`argument $option "$@"`; shift;; + grub_setup="`argument "$option" "$@"`"; shift;; --grub-setup=*) - grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;; + grub_setup="`echo "$option" | sed 's/--grub-setup=//'`" ;; --bootloader-id) - bootloader_id=`argument $option "$@"`; shift;; + bootloader_id="`argument $option "$@"`"; shift;; --bootloader-id=*) - bootloader_id=`echo "$option" | sed 's/--bootloader-id=//'` ;; + bootloader_id="`echo "$option" | sed 's/--bootloader-id=//'`" ;; --grub-mkimage) - grub_mkimage=`argument $option "$@"`; shift;; + grub_mkimage="`argument $option "$@"`"; shift;; --grub-mkimage=*) - grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + grub_mkimage="`echo "$option" | sed 's/--grub-mkimage=//'`" ;; --grub-mkrelpath) - grub_mkrelpath=`argument $option "$@"`; shift;; + grub_mkrelpath="`argument "$option" "$@"`"; shift;; --grub-mkimage=*) - grub_mkrelpath=`echo "$option" | sed 's/--grub-mkrelpath=//'` ;; + grub_mkrelpath="`echo "$option" | sed 's/--grub-mkrelpath=//'`" ;; --grub-mkdevicemap) - grub_mkdevicemap=`argument $option "$@"`; shift;; + grub_mkdevicemap="`argument "$option" "$@"`"; shift;; --grub-mkdevicemap=*) - grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + grub_mkdevicemap="`echo "$option" | sed 's/--grub-mkdevicemap=//'`" ;; --grub-probe) - grub_probe=`argument $option "$@"`; shift;; + grub_probe="`argument "$option" "$@"`"; shift;; --grub-probe=*) - grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + grub_probe="`echo "$option" | sed 's/--grub-probe=//'`" ;; --no-floppy) no_floppy="--no-floppy" ;; @@ -230,11 +230,11 @@ do --disk-module) if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then - disk_module=`argument $option "$@"`; shift; + disk_module="`argument "$option" "$@"`"; shift; fi ;; --disk-module=*) if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then - disk_module=`echo "$option" | sed 's/--disk-module=//'` + disk_module="`echo "$option" | sed 's/--disk-module=//'`" fi ;; --no-nvram) @@ -244,9 +244,9 @@ do --debug) debug=yes ;; --debug-image) - debug_image=`argument $option "$@"`; shift;; + debug_image="`argument "$option" "$@"`"; shift;; --debug-image=*) - debug_image=`echo "$option" | sed 's/--debug-image=//'` ;; + debug_image="`echo "$option" | sed 's/--debug-image=//'`" ;; -f | --force) setup_force="--force" ;; @@ -266,9 +266,6 @@ do esac done -# for make_system_path_relative_to_its_root() -. ${libdir}/grub/grub-mkconfig_lib - if test "x$install_device" = x && ([ "${target_cpu}-${platform}" = "i386-pc" ] \ || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ]); then echo "install_device not specified." 1>&2 @@ -278,7 +275,7 @@ fi # If the debugging feature is enabled, print commands. setup_verbose= -if test $debug = yes; then +if test x"$debug" = xyes; then set -x setup_verbose="--verbose" efi_quiet=-q @@ -286,17 +283,17 @@ fi if [ -z "$bootdir" ]; then # Default bootdir if bootdir not initialized. - bootdir=/@bootdirname@ + bootdir="/@bootdirname@" if [ -n "$rootdir" ] ; then # Initialize bootdir if rootdir was initialized. - bootdir=${rootdir}/@bootdirname@ + bootdir="${rootdir}/@bootdirname@" fi fi -grubdir=`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'` -device_map=${grubdir}/device.map -grub_probe="${grub_probe} --device-map=${device_map}" +grubdir="`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'`" +device_map="${grubdir}/device.map" + # Check if GRUB is installed. if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then @@ -309,7 +306,7 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" fi fi -set $grub_mkimage dummy +set "$grub_mkimage" dummy if test -f "$1"; then : else @@ -317,7 +314,7 @@ else exit 1 fi -set $grub_mkdevicemap dummy +set "$grub_mkdevicemap" dummy if test -f "$1"; then : else @@ -328,24 +325,24 @@ fi if [ x"$platform" = xefi ]; then # Find the EFI System Partition. efidir= - if test -d ${bootdir}/efi; then - install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}/efi` + if test -d "${bootdir}/efi"; then + install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}/efi"`" # Is it a mount point? - if test "x$install_device" != "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}`"; then - efidir=${bootdir}/efi + if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then + efidir="${bootdir}/efi" fi elif test -n "$rootdir" && test "x$rootdir" != "x/"; then # The EFI System Partition may have been given directly using # --root-directory. - install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${rootdir}` + install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${rootdir}"`" # Is it a mount point? - if test "x$install_device" != "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${rootdir}/..`"; then - efidir=${rootdir} + if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${rootdir}/.."`"; then + efidir="${rootdir}" fi fi if test -n "$efidir"; then - efi_fs=`$grub_probe --target=fs --device-map=${device_map} ${efidir}` + efi_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${efidir}"` if test "x$efi_fs" = xfat; then :; else echo "${efidir} doesn't look like an EFI partition." 1>&2 efidir= @@ -411,7 +408,7 @@ mkdir -p "$grubdir" || exit 1 # If --recheck is specified, remove the device map, if present. if test $recheck = yes; then - rm -f $device_map + rm -f "$device_map" fi # Create the device map file if it is not present. @@ -421,11 +418,11 @@ else # Create a safe temporary file. test -n "$mklog" && log_file=`$mklog` - $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 + "$grub_mkdevicemap" "--device-map=$device_map" $no_floppy || exit 1 fi # Make sure that there is no duplicated entry. -tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ +tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' "$device_map" \ | sort | uniq -d | sed -n 1p` if test -n "$tmp"; then echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 @@ -433,42 +430,42 @@ if test -n "$tmp"; then fi # Copy the GRUB images to the GRUB directory. -for file in ${grubdir}/*.mod ${grubdir}/*.lst ${grubdir}/*.img ${grubdir}/efiemu??.o; do - if test -f $file && [ "`basename $file`" != menu.lst ]; then - rm -f $file || exit 1 +for file in "${grubdir}"/*.mod "${grubdir}"/*.lst "${grubdir}"/*.img "${grubdir}"/efiemu??.o; do + if test -f "$file" && [ "`basename $file`" != menu.lst ]; then + rm -f "$file" || exit 1 fi done -for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do - cp -f $file ${grubdir} || exit 1 +for file in "${pkglibdir}"/*.mod "${pkglibdir}"/*.lst; do + cp -f "$file" "${grubdir}" || exit 1 done if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then - for file in ${pkglibdir}/*.img ${pkglibdir}/efiemu??.o; do - if test -f $file; then - cp -f $file ${grubdir} || exit 1 + for file in "${pkglibdir}"/*.img "${pkglibdir}"/efiemu??.o; do + if test -f "$file"; then + cp -f "$file" "${grubdir}" || exit 1 fi done fi # Copy gettext files -mkdir -p ${grubdir}/locale/ -for dir in ${localedir}/*; do +mkdir -p "${grubdir}"/locale/ +for dir in "${localedir}"/*; do if test -f "$dir/LC_MESSAGES/grub.mo"; then cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" fi done # Write device to a variable so we don't have to traverse /dev every time. -grub_device=`$grub_probe --target=device ${grubdir}` || exit 1 +grub_device="`"$grub_probe" --device-map="${device_map}" --target=device "${grubdir}"`" || exit 1 -if ! test -f ${grubdir}/grubenv; then - $grub_editenv ${grubdir}/grubenv create +if ! test -f "${grubdir}"/grubenv; then + "$grub_editenv" "${grubdir}"/grubenv create fi # Create the core image. First, auto-detect the filesystem module. -fs_module=`$grub_probe --target=fs --device ${grub_device}` +fs_module="`"$grub_probe" --device-map="${device_map}" --target=fs --device "${grub_device}"`" if test "x$fs_module" = x ; then echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2 - echo "Please report this together with the output of \"$grub_probe --target=fs -v ${grubdir}\" to " 1>&2 + echo "Please report this together with the output of \"$grub_probe --device-map=\"${device_map}\" --target=fs -v ${grubdir}\" to " 1>&2 exit 1 fi @@ -476,7 +473,7 @@ fi # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). partmap_module= -for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do +for x in "`"$grub_probe" --device-map="${device_map}" --target=partmap --device "${grub_device}" 2> /dev/null`"; do case "$x" in netbsd | openbsd) partmap_module="$partmap_module part_bsd";; @@ -486,13 +483,13 @@ for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do done # Device abstraction module, if any (lvm, raid). -devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` +devabstraction_module="`"$grub_probe" --device-map="${device_map}" --target=abstraction --device "${grub_device}"`" # The order in this list is critical. Be careful when modifying it. modules="$modules $disk_module" modules="$modules $fs_module $partmap_module $devabstraction_module" -relative_grubdir=`make_system_path_relative_to_its_root ${grubdir}` || exit 1 +relative_grubdir="`"$grub_mkrelpath" "${grubdir}"`" || exit 1 if [ "x${relative_grubdir}" = "x" ] ; then relative_grubdir=/ fi @@ -500,10 +497,10 @@ fi prefix_drive= config_opt= -rm -f ${grubdir}/load.cfg +rm -f "${grubdir}/load.cfg" if [ "x${debug_image}" != x ]; then - echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg + echo "set debug='${debug_image}'" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " fi @@ -512,28 +509,28 @@ if [ "x${devabstraction_module}" = "x" ] ; then if echo "${install_device}" | grep -qx "(.*)" ; then install_drive="${install_device}" else - install_drive="`$grub_probe --target=drive --device ${install_device}`" || exit 1 + install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1 fi - install_drive="`echo ${install_drive} | sed -e s/,[a-z0-9,]*//g`" + install_drive="`echo "${install_drive}" | sed -e s/,[a-z0-9,]*//g`" fi - grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1 + grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1 # Strip partition number - grub_partition="`echo ${grub_drive} | sed -e 's/^[^,]*[,)]//; s/)$//'`" - grub_drive="`echo ${grub_drive} | sed -e s/,[a-z0-9,]*//g`" + grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`" + grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`" if [ "$disk_module" = ata ] ; then # generic method (used on coreboot and ata mod) - uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`" + uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" if [ "x${uuid}" = "x" ] ; then echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 exit 1 fi - echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg - echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg + echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg" + echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" elif [ "x${grub_drive}" != "x${install_drive}" ] ; then - uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`" + uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" if [ "x${uuid}" = "x" ] ; then echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 exit 1 @@ -551,7 +548,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then fi fi else - prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 + prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1 fi case "${target_cpu}-${platform}" in @@ -568,33 +565,33 @@ case "${target_cpu}-${platform}" in esac -$grub_mkimage ${config_opt} -d ${pkglibdir} -O ${mkimage_target} --output=${grubdir}/core.${imgext} --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +"$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 - cp ${grubdir}/core.${imgext} ${bootdir}/grub.elf + 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 + cp "${grubdir}/core.${imgext}" "${grubdir}/grub" elif [ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ]; then - $grub_mkimage ${config_opt} -d ${pkglibdir} -O ${mkimage_target} --output=${grubdir}/grub.efi --prefix="" $modules || exit 1 + "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/grub.efi" --prefix="" $modules || exit 1 fi # Perform the platform-dependent install if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then # Now perform the installation. - $grub_setup ${allow_floppy} ${setup_verbose} ${setup_force} --directory=${grubdir} \ - --device-map=${device_map} ${install_device} || exit 1 + "$grub_setup" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}" \ + --device-map="${device_map}" "${install_device}" || exit 1 elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then if [ x"$update_nvram" = xyes ]; then - set $ofpathname dummy + set "$ofpathname" dummy if test -f "$1"; then : else echo "$1: Not found." 1>&2 exit 1 fi - set $nvsetenv dummy + set "$nvsetenv" dummy if test -f "$1"; then : else @@ -602,16 +599,16 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla exit 1 fi # Get the Open Firmware device tree path translation. - dev=`echo $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'` - partno=`echo $grub_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'` - ofpath=`$ofpathname $dev` || { + dev="`echo $grub_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'`" + partno="`echo $grub_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'`" + ofpath="`$ofpathname $dev`" || { echo "Couldn't find Open Firmware device tree path for $dev." echo "You will have to set boot-device manually." exit 1 } # Point boot-device at the new grub install - boot_device="$ofpath:$partno,"`grub-mkrelpath ${grubdir}/core.${imgext} | sed 's,/,\\\\,g'` + boot_device="$ofpath:$partno,"`"$grub_mkrelpath" "${grubdir}/core.${imgext}" | sed 's,/,\\\\,g'` "$nvsetenv" boot-device "$boot_device" || { echo "$nvsetenv failed." echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" @@ -620,7 +617,7 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla } fi elif [ x"$platform" = xefi ]; then - cp ${grubdir}/core.${imgext} ${efidir}/${efi_file} + cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}" # Try to make this image bootable using the EFI Boot Manager, if available. if test "$removable" = no && test -n "$efi_distributor" && \ @@ -643,7 +640,7 @@ elif [ x"$platform" = xefi ]; then # Use fresh device map text to avoid any problems with stale data, since # all we need here is a one-to-one mapping. clean_devmap="$($grub_mkdevicemap --device-map=/dev/stdout)" - efidir_drive="$(echo "$clean_devmap" | $grub_probe --target=drive --device-map=/dev/stdin "$efidir")" + efidir_drive="$(echo "$clean_devmap" | "$grub_probe" --device-map="${device_map}" --target=drive --device-map=/dev/stdin "$efidir")" if test -z "$efidir_drive"; then echo "Can't find GRUB drive for $efidir; unable to create EFI Boot Manager entry." >&2 else From 58c184be7be92761402bcf65e9b803453a0ee99e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 16:11:24 +0100 Subject: [PATCH 0368/1414] Support big ext2 files. * grub-core/fs/ext2.c (grub_ext2_inode): Rename dir_acl to size_high. (grub_ext2_read_block): Support triple indirect blocks. (grub_ext2_read_file): Use 64-bit types and read size_high. (grub_ext2_open): Read size_high. Reported by: Ximin Luo. Tested by: Manoel Rebelo Abranches. --- ChangeLog | 11 +++++++++++ grub-core/fs/ext2.c | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03ff87f74..9fa85cda5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-11-13 Vladimir Serbinenko + + Support big ext2 files. + + * grub-core/fs/ext2.c (grub_ext2_inode): Rename dir_acl to size_high. + (grub_ext2_read_block): Support triple indirect blocks. + (grub_ext2_read_file): Use 64-bit types and read size_high. + (grub_ext2_open): Read size_high. + Reported by: Ximin Luo. + Tested by: Manoel Rebelo Abranches. + 2010-11-13 Vladimir Serbinenko * util/grub-install.in: Handle filenames containing spaces. diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c index dfc75c625..ed5fafd4c 100644 --- a/grub-core/fs/ext2.c +++ b/grub-core/fs/ext2.c @@ -229,7 +229,7 @@ struct grub_ext2_inode }; grub_uint32_t version; grub_uint32_t acl; - grub_uint32_t dir_acl; + grub_uint32_t size_high; grub_uint32_t fragment_addr; grub_uint32_t osd2[3]; }; @@ -470,10 +470,41 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) blknr = grub_le_to_cpu32 (indir[rblock % perblock]); } /* triple indirect. */ + else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1) + + (blksz / 4) * (blksz / 4) * (blksz / 4 + 1)) + { + unsigned int perblock = blksz / 4; + unsigned int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 + * (blksz / 4 + 1)); + grub_uint32_t indir[blksz / 4]; + + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) + grub_le_to_cpu32 (inode->blocks.triple_indir_block)) + << log2_blksz, + 0, blksz, indir)) + return grub_errno; + + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) + grub_le_to_cpu32 (indir[(rblock / perblock) / perblock])) + << log2_blksz, + 0, blksz, indir)) + return grub_errno; + + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) + grub_le_to_cpu32 (indir[(rblock / perblock) % perblock])) + << log2_blksz, + 0, blksz, indir)) + return grub_errno; + + blknr = grub_le_to_cpu32 (indir[rblock % perblock]); + } else { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "ext2fs doesn't support triple indirect blocks"); + "ext2fs doesn't support quadruple indirect blocks"); } return blknr; @@ -485,11 +516,12 @@ static grub_ssize_t grub_ext2_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_ext2_read_block, - node->inode.size, + grub_cpu_to_le32 (node->inode.size) + | (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32), LOG2_EXT2_BLOCK_SIZE (node->data)); } @@ -756,6 +788,7 @@ grub_ext2_open (struct grub_file *file, const char *name) grub_free (fdiro); file->size = grub_le_to_cpu32 (data->inode->size); + file->size |= ((grub_off_t) grub_le_to_cpu32 (data->inode->size_high)) << 32; file->data = data; file->offset = 0; From bc5dd0b9ca5303b4f2bc204b79c4cc9285a87185 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 16:27:29 +0100 Subject: [PATCH 0369/1414] * util/grub-mkconfig.in: Fix quoting. --- ChangeLog | 4 ++++ util/grub-mkconfig.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9fa85cda5..7aa535548 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-13 Vladimir Serbinenko + + * util/grub-mkconfig.in: Fix quoting. + 2010-11-13 Vladimir Serbinenko Support big ext2 files. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 2fcc715c2..b041a38d7 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -36,7 +36,7 @@ grub_mkconfig_dir=${sysconfdir}/grub.d self=`basename $0` -grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | "sed ${transform}"` +grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed "${transform}"` grub_probe=${sbindir}/`echo grub-probe | sed "${transform}"` grub_script_check="${bindir}/`echo grub-script-check | sed "${transform}"`" From a06eb03ad020dd530f635e2936ea29270e222c47 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Nov 2010 21:27:08 +0100 Subject: [PATCH 0370/1414] 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 de1a024fffb224378f20a60afdb73d102e9f3db9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Nov 2010 13:37:59 +0100 Subject: [PATCH 0371/1414] Properly define WORDS_BIGENDIAN in wrapped environments. * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (WORDS_BIGENDIAN): New definition. * grub-core/lib/posix_wrap/sys/types.h (WORDS_BIGENDIAN): Likewise. Reported by: Manoel Rebelo Abranches. Tested by: Manoel Rebelo Abranches. --- ChangeLog | 11 +++++++++++ grub-core/lib/libgcrypt_wrap/cipher_wrap.h | 6 ++++++ grub-core/lib/posix_wrap/sys/types.h | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7aa535548..e87dd9ff4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-11-14 Vladimir Serbinenko + + Properly define WORDS_BIGENDIAN in wrapped environments. + + * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (WORDS_BIGENDIAN): New + definition. + * grub-core/lib/posix_wrap/sys/types.h (WORDS_BIGENDIAN): Likewise. + + Reported by: Manoel Rebelo Abranches. + Tested by: Manoel Rebelo Abranches. + 2010-11-13 Vladimir Serbinenko * util/grub-mkconfig.in: Fix quoting. diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h index b4530c112..59febaeb5 100644 --- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h @@ -25,6 +25,12 @@ #include #include +#ifdef GRUB_CPU_WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#else +#undef WORDS_BIGENDIAN +#endif + #define __GNU_LIBRARY__ #define DIM ARRAY_SIZE diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h index 28e354759..4e8331fdd 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h @@ -32,4 +32,10 @@ typedef grub_uint16_t uint16_t; typedef grub_uint32_t uint32_t; typedef grub_uint64_t uint64_t; +#ifdef GRUB_CPU_WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#else +#undef WORDS_BIGENDIAN +#endif + #endif From 1fd08bf111bcc35177eb0dc411dc052bdec7a058 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Nov 2010 14:13:11 +0100 Subject: [PATCH 0372/1414] * grub-core/disk/lvm.c (GRUB_MOD_FINI): Reset the vg_list. Fixes LVM on RAID support. --- ChangeLog | 5 +++++ grub-core/disk/lvm.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index e87dd9ff4..b0ee0d012 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-14 Vladimir Serbinenko + + * grub-core/disk/lvm.c (GRUB_MOD_FINI): Reset the vg_list. Fixes + LVM on RAID support. + 2010-11-14 Vladimir Serbinenko Properly define WORDS_BIGENDIAN in wrapped environments. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index d2d2f620b..39fa84d91 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -762,5 +762,6 @@ GRUB_MOD_INIT(lvm) GRUB_MOD_FINI(lvm) { grub_disk_dev_unregister (&grub_lvm_dev); + vg_list = NULL; /* FIXME: free the lvm list. */ } From 65e93f6b846c2fa12e10a9000c744b2904ba4713 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Nov 2010 16:15:41 +0100 Subject: [PATCH 0373/1414] * util/grub-install.in: Ignore empty partition table detection instead of trying to include part_ module. --- ChangeLog | 5 +++++ util/grub-install.in | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index b0ee0d012..c56720a15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-14 Vladimir Serbinenko + + * util/grub-install.in: Ignore empty partition table detection + instead of trying to include part_ module. + 2010-11-14 Vladimir Serbinenko * grub-core/disk/lvm.c (GRUB_MOD_FINI): Reset the vg_list. Fixes diff --git a/util/grub-install.in b/util/grub-install.in index 52f17bfa2..00ad3fde4 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -477,6 +477,7 @@ for x in "`"$grub_probe" --device-map="${device_map}" --target=partmap --device case "$x" in netbsd | openbsd) partmap_module="$partmap_module part_bsd";; + "") ;; *) partmap_module="$partmap_module part_$x";; esac From 130da6a74588109c20edc47af40e7c7925b95522 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Nov 2010 16:25:28 +0100 Subject: [PATCH 0374/1414] * docs/grub.texi (Changes from GRUB Legacy): Note when save_env is unavailable. (Simple configuration): Refer to Changes from GRUB Legacy about save_env availability. --- ChangeLog | 7 +++++++ docs/grub.texi | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c56720a15..449218cca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-11-14 Vladimir Serbinenko + + * docs/grub.texi (Changes from GRUB Legacy): Note when save_env is + unavailable. + (Simple configuration): Refer to Changes from GRUB Legacy about + save_env availability. + 2010-11-14 Vladimir Serbinenko * util/grub-install.in: Ignore empty partition table detection diff --git a/docs/grub.texi b/docs/grub.texi index bdbbb9329..54a2d8791 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -227,7 +227,9 @@ scripting language: variables, conditionals, and loops are available. @item A small amount of persistent storage is available across reboots, using the @command{save_env} and @command{load_env} commands in GRUB and the -@command{grub-editenv} utility. +@command{grub-editenv} utility. For safety reasons this storage is only +available when installed on plain disk (no LVM or RAID), using non-checksumming +filesystem (no ZFS) and using BIOS or EFI functions (no ATA, USB or IEEE1275) @item GRUB 2 has more reliable ways to find its own files and those of target @@ -1032,6 +1034,8 @@ it as a new default entry for use by future runs of GRUB. This is only useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because @samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with @command{grub-set-default} or @command{grub-reboot}. Unset by default. +The remarks of @pxref{Changes from GRUB Legacy} on the availability +of @samp{save_env} apply. @item GRUB_TIMEOUT Boot the default entry this many seconds after the menu is displayed, unless From 406858a8a9532cd6204254f0f796d4a0ab299f84 Mon Sep 17 00:00:00 2001 From: Giuseppe Caizzone Date: Sun, 14 Nov 2010 16:48:17 +0100 Subject: [PATCH 0375/1414] Support reading files larger than 2 GiB. * grub-core/fs/udf.c (grub_udf_iterate_dir): Change type of variable "offset" to grub_off_t. (grub_udf_read_file): Likewise for parameter "pos". --- ChangeLog | 8 ++++++++ grub-core/fs/udf.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 449218cca..5cffcfdbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-14 Giuseppe Caizzone + + Support reading files larger than 2 GiB. + + * grub-core/fs/udf.c (grub_udf_iterate_dir): Change type of variable + "offset" to grub_off_t. + (grub_udf_read_file): Likewise for parameter "pos". + 2010-11-14 Vladimir Serbinenko * docs/grub.texi (Changes from GRUB Legacy): Note when save_env is diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index ad109bed9..1600a4cd5 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -471,7 +471,7 @@ grub_udf_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) { @@ -704,7 +704,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, { grub_fshelp_node_t child; struct grub_udf_file_ident dirent; - grub_uint32_t offset = 0; + grub_off_t offset = 0; child = grub_malloc (sizeof (struct grub_fshelp_node)); if (!child) From cb0229c5873daee17491aa9a4b1b3cf9c7dd5a47 Mon Sep 17 00:00:00 2001 From: Giuseppe Caizzone Date: Sun, 14 Nov 2010 16:51:45 +0100 Subject: [PATCH 0376/1414] Properly handle deleted files on UDF. * grub-core/fs/udf.c (grub_udf_iterate_dir): Skip directory entries whose "characteristics" field has the bit GRUB_UDF_FID_CHAR_DELETED set. --- ChangeLog | 8 ++++ grub-core/fs/udf.c | 91 ++++++++++++++++++++++++---------------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5cffcfdbd..d944dc0f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-14 Giuseppe Caizzone + + Properly handle deleted files on UDF. + + * grub-core/fs/udf.c (grub_udf_iterate_dir): Skip directory entries + whose "characteristics" field has the bit GRUB_UDF_FID_CHAR_DELETED + set. + 2010-11-14 Giuseppe Caizzone Support reading files larger than 2 GiB. diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 1600a4cd5..9e729a349 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -729,57 +729,60 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, return 0; } - child = grub_malloc (sizeof (struct grub_fshelp_node)); - if (!child) - return 0; - - if (grub_udf_read_icb (dir->data, &dirent.icb, child)) - return 0; - offset += sizeof (dirent) + U16 (dirent.imp_use_length); - if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) + if (!(dirent.characteristics & GRUB_UDF_FID_CHAR_DELETED)) { - /* This is the parent directory. */ - if (hook ("..", GRUB_FSHELP_DIR, child)) - return 1; - } - else - { - enum grub_fshelp_filetype type; - 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)); - - if ((grub_udf_read_file (dir, 0, offset, - dirent.file_ident_length, - (char *) raw)) - != dirent.file_ident_length) + child = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!child) return 0; - if (raw[0] == 8) + if (grub_udf_read_icb (dir->data, &dirent.icb, child)) + return 0; + + if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) { - unsigned i; - utf16len = dirent.file_ident_length - 1; - for (i = 0; i < utf16len; i++) - utf16[i] = raw[i + 1]; + /* This is the parent directory. */ + if (hook ("..", GRUB_FSHELP_DIR, child)) + return 1; } - if (raw[0] == 16) + else { - 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'; - - if (hook ((char *) filename, type, child)) - return 1; + enum grub_fshelp_filetype type; + 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)); + + if ((grub_udf_read_file (dir, 0, offset, + dirent.file_ident_length, + (char *) raw)) + != 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'; + + if (hook ((char *) filename, type, child)) + return 1; + } } } From e53609331b2fdee08cb4494ddc772785b7ea32e8 Mon Sep 17 00:00:00 2001 From: Giuseppe Caizzone Date: Sun, 14 Nov 2010 16:58:50 +0100 Subject: [PATCH 0377/1414] Add generic logical block size support for UDF. * grub-core/fs/udf.c (GRUB_UDF_LOG2_BLKSIZE): Removed. (GRUB_UDF_BLKSZ): Removed. (struct grub_udf_data): New field "lbshift" to hold the logical block size of the file system in log2 format. All users updated. (sblocklist): Change type to unsigned. (grub_udf_mount): Change type of "sblklist" to unsigned. Move AVDP search before VRS recognition, because the latter requires knowledge of the logical block size, which is detected during the former. Detect and validate logical block size during AVDP search, adding support for block sizes 512, 1024 and 4096. Make VRS recognition independent of block size. --- ChangeLog | 17 ++++++++ grub-core/fs/udf.c | 105 ++++++++++++++++++++++++--------------------- 2 files changed, 74 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index d944dc0f8..9e1da9c60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2010-11-14 Giuseppe Caizzone + + Add generic logical block size support for UDF. + + * grub-core/fs/udf.c (GRUB_UDF_LOG2_BLKSIZE): Removed. + (GRUB_UDF_BLKSZ): Removed. + (struct grub_udf_data): New field "lbshift" to hold the logical block + size of the file system in log2 format. All users updated. + (sblocklist): Change type to unsigned. + (grub_udf_mount): Change type of "sblklist" to unsigned. + Move AVDP search before VRS recognition, because the latter requires + knowledge of the logical block size, which is detected during the + former. + Detect and validate logical block size during AVDP search, adding + support for block sizes 512, 1024 and 4096. + Make VRS recognition independent of block size. + 2010-11-14 Giuseppe Caizzone Properly handle deleted files on UDF. diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 9e729a349..4e54f1775 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -34,9 +34,6 @@ #define U32 grub_le_to_cpu32 #define U64 grub_le_to_cpu64 -#define GRUB_UDF_LOG2_BLKSZ 2 -#define GRUB_UDF_BLKSZ 2048 - #define GRUB_UDF_TAG_IDENT_PVD 0x0001 #define GRUB_UDF_TAG_IDENT_AVDP 0x0002 #define GRUB_UDF_TAG_IDENT_VDP 0x0003 @@ -343,7 +340,7 @@ struct grub_udf_data struct grub_udf_pd pds[GRUB_UDF_MAX_PDS]; struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS]; struct grub_udf_long_ad root_icb; - int npd, npm; + int npd, npm, lbshift; }; struct grub_fshelp_node @@ -389,7 +386,7 @@ grub_udf_read_icb (struct grub_udf_data *data, if (grub_errno) return grub_errno; - if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + if (grub_disk_read (data->disk, block << data->lbshift, 0, sizeof (struct grub_udf_file_entry), &node->fe)) return grub_errno; @@ -427,7 +424,7 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; len /= sizeof (struct grub_udf_short_ad); - filebytes = fileblock * GRUB_UDF_BLKSZ; + filebytes = fileblock * U32 (node->data->lvd.bsize); while (len > 0) { if (filebytes < U32 (ad->length)) @@ -435,7 +432,8 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) (grub_udf_get_block (node->data, node->part_ref, ad->position) - + (filebytes / GRUB_UDF_BLKSZ))); + + (filebytes >> (GRUB_DISK_SECTOR_BITS + + node->data->lbshift)))); filebytes -= U32 (ad->length); ad++; @@ -447,7 +445,7 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; len /= sizeof (struct grub_udf_long_ad); - filebytes = fileblock * GRUB_UDF_BLKSZ; + filebytes = fileblock * U32 (node->data->lvd.bsize); while (len > 0) { if (filebytes < U32 (ad->length)) @@ -455,7 +453,8 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) (grub_udf_get_block (node->data, ad->block.part_ref, ad->block.block_num) - + (filebytes / GRUB_UDF_BLKSZ))); + + (filebytes >> (GRUB_DISK_SECTOR_BITS + + node->data->lbshift)))); filebytes -= U32 (ad->length); ad++; @@ -496,21 +495,21 @@ grub_udf_read_file (grub_fshelp_node_t node, } return grub_fshelp_read_file (node->data->disk, node, read_hook, - pos, len, buf, grub_udf_read_block, - U64 (node->fe.file_size), - GRUB_UDF_LOG2_BLKSZ); + pos, len, buf, grub_udf_read_block, + U64 (node->fe.file_size), + node->data->lbshift); } -static int sblocklist[] = { 256, 512, 0 }; +static unsigned sblocklist[] = { 256, 512, 0 }; static struct grub_udf_data * grub_udf_mount (grub_disk_t disk) { struct grub_udf_data *data = 0; struct grub_udf_fileset root_fs; - int *sblklist = sblocklist; - grub_uint32_t block; - int i; + unsigned *sblklist; + grub_uint32_t block, vblock; + int i, lbshift; data = grub_malloc (sizeof (struct grub_udf_data)); if (!data) @@ -518,12 +517,48 @@ grub_udf_mount (grub_disk_t disk) data->disk = disk; + /* Search for Anchor Volume Descriptor Pointer (AVDP) + * and determine logical block size. */ + block = 0; + for (lbshift = 0; lbshift < 4; lbshift++) + { + for (sblklist = sblocklist; *sblklist; sblklist++) + { + struct grub_udf_avdp avdp; + + if (grub_disk_read (disk, *sblklist << lbshift, 0, + sizeof (struct grub_udf_avdp), &avdp)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + + if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP && + U32 (avdp.tag.tag_location) == *sblklist) + { + block = U32 (avdp.vds.start); + break; + } + } + + if (block) + break; + } + + if (!block) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + data->lbshift = lbshift; + /* Search for Volume Recognition Sequence (VRS). */ - for (block = 16;; block++) + for (vblock = (32767 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1;; + vblock += (2047 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1) { struct grub_udf_vrs vrs; - if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + if (grub_disk_read (disk, vblock << lbshift, 0, sizeof (struct grub_udf_vrs), &vrs)) { grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); @@ -545,39 +580,13 @@ grub_udf_mount (grub_disk_t disk) } } - /* Search for Anchor Volume Descriptor Pointer (AVDP). */ - while (1) - { - struct grub_udf_avdp avdp; - - if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0, - sizeof (struct grub_udf_avdp), &avdp)) - { - grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); - goto fail; - } - - if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP) - { - block = U32 (avdp.vds.start); - break; - } - - sblklist++; - if (*sblklist == 0) - { - grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); - goto fail; - } - } - data->npd = data->npm = 0; /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD). */ while (1) { struct grub_udf_tag tag; - if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + if (grub_disk_read (disk, block << lbshift, 0, sizeof (struct grub_udf_tag), &tag)) { grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); @@ -593,7 +602,7 @@ grub_udf_mount (grub_disk_t disk) goto fail; } - if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + if (grub_disk_read (disk, block << lbshift, 0, sizeof (struct grub_udf_pd), &data->pds[data->npd])) { @@ -609,7 +618,7 @@ grub_udf_mount (grub_disk_t disk) struct grub_udf_partmap *ppm; - if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + if (grub_disk_read (disk, block << lbshift, 0, sizeof (struct grub_udf_lvd), &data->lvd)) { @@ -673,7 +682,7 @@ grub_udf_mount (grub_disk_t disk) if (grub_errno) goto fail; - if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + if (grub_disk_read (disk, block << lbshift, 0, sizeof (struct grub_udf_fileset), &root_fs)) { grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); From 69c4feebb13fa7f0f3cb395216636605d06f6f02 Mon Sep 17 00:00:00 2001 From: Giuseppe Caizzone Date: Sun, 14 Nov 2010 17:03:49 +0100 Subject: [PATCH 0378/1414] Add generic logical block size support for UDF. * grub-core/fs/udf.c (GRUB_UDF_LOG2_BLKSIZE): Removed. (GRUB_UDF_BLKSZ): Removed. (struct grub_udf_data): New field "lbshift" to hold the logical block size of the file system in log2 format. All users updated. (sblocklist): Change type to unsigned. (grub_udf_mount): Change type of "sblklist" to unsigned. Move AVDP search before VRS recognition, because the latter requires knowledge of the logical block size, which is detected during the former. Detect and validate logical block size during AVDP search, adding support for block sizes 512, 1024 and 4096. Make VRS recognition independent of block size. --- grub-core/fs/udf.c | 138 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 111 insertions(+), 27 deletions(-) diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 4e54f1775..7041e619e 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -333,6 +333,13 @@ struct grub_udf_lvd grub_uint8_t part_maps[1608]; } __attribute__ ((packed)); +struct grub_udf_aed +{ + struct grub_udf_tag tag; + grub_uint32_t prev_ae; + grub_uint32_t ae_len; +} __attribute__ ((packed)); + struct grub_udf_data { grub_disk_t disk; @@ -403,19 +410,26 @@ grub_udf_read_icb (struct grub_udf_data *data, static grub_disk_addr_t grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { + char *buf = NULL; char *ptr; - int len; + grub_ssize_t len; grub_disk_addr_t filebytes; - if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) + switch (U16 (node->fe.tag.tag_ident)) { + case GRUB_UDF_TAG_IDENT_FE: ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length); len = U32 (node->fe.alloc_descs_length); - } - else - { + break; + + case GRUB_UDF_TAG_IDENT_EFE: ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length); len = U32 (node->efe.alloc_descs_length); + break; + + default: + grub_error (GRUB_ERR_BAD_FS, "invalid file entry"); + return 0; } if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) @@ -423,45 +437,115 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; - len /= sizeof (struct grub_udf_short_ad); filebytes = fileblock * U32 (node->data->lvd.bsize); - while (len > 0) + while (len >= (grub_ssize_t) sizeof (struct grub_udf_short_ad)) { - if (filebytes < U32 (ad->length)) - return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 : - (grub_udf_get_block (node->data, - node->part_ref, - ad->position) - + (filebytes >> (GRUB_DISK_SECTOR_BITS - + node->data->lbshift)))); + grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff; + grub_uint32_t adtype = U32 (ad->length) >> 30; + if (adtype == 3) + { + struct grub_udf_aed *extension; + grub_disk_addr_t sec = grub_udf_get_block(node->data, + node->part_ref, + ad->position); + if (!buf) + { + buf = grub_malloc (U32 (node->data->lvd.bsize)); + if (!buf) + return 0; + } + if (grub_disk_read (node->data->disk, sec << node->data->lbshift, + 0, adlen, buf)) + goto fail; - filebytes -= U32 (ad->length); + extension = (struct grub_udf_aed *) buf; + if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED) + { + grub_error (GRUB_ERR_BAD_FS, "invalid aed tag"); + goto fail; + } + + len = U32 (extension->ae_len); + ad = (struct grub_udf_short_ad *) + (buf + sizeof (struct grub_udf_aed)); + continue; + } + + if (filebytes < adlen) + { + grub_uint32_t ad_pos = ad->position; + grub_free (buf); + return ((U32 (ad_pos) & GRUB_UDF_EXT_MASK) ? 0 : + (grub_udf_get_block (node->data, node->part_ref, ad_pos) + + (filebytes >> (GRUB_DISK_SECTOR_BITS + + node->data->lbshift)))); + } + + filebytes -= adlen; ad++; - len--; + len -= sizeof (struct grub_udf_short_ad); } } else { struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; - len /= sizeof (struct grub_udf_long_ad); filebytes = fileblock * U32 (node->data->lvd.bsize); - while (len > 0) + while (len >= (grub_ssize_t) sizeof (struct grub_udf_long_ad)) { - if (filebytes < U32 (ad->length)) - return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ? 0 : - (grub_udf_get_block (node->data, - ad->block.part_ref, - ad->block.block_num) - + (filebytes >> (GRUB_DISK_SECTOR_BITS - + node->data->lbshift)))); + grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff; + grub_uint32_t adtype = U32 (ad->length) >> 30; + if (adtype == 3) + { + struct grub_udf_aed *extension; + grub_disk_addr_t sec = grub_udf_get_block(node->data, + ad->block.part_ref, + ad->block.block_num); + if (!buf) + { + buf = grub_malloc (U32 (node->data->lvd.bsize)); + if (!buf) + return 0; + } + if (grub_disk_read (node->data->disk, sec << node->data->lbshift, + 0, adlen, buf)) + goto fail; - filebytes -= U32 (ad->length); + extension = (struct grub_udf_aed *) buf; + if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED) + { + grub_error (GRUB_ERR_BAD_FS, "invalid aed tag"); + goto fail; + } + + len = U32 (extension->ae_len); + ad = (struct grub_udf_long_ad *) + (buf + sizeof (struct grub_udf_aed)); + continue; + } + + if (filebytes < adlen) + { + grub_uint32_t ad_block_num = ad->block.block_num; + grub_uint32_t ad_part_ref = ad->block.part_ref; + grub_free (buf); + return ((U32 (ad_block_num) & GRUB_UDF_EXT_MASK) ? 0 : + (grub_udf_get_block (node->data, ad_part_ref, + ad_block_num) + + (filebytes >> (GRUB_DISK_SECTOR_BITS + + node->data->lbshift)))); + } + + filebytes -= adlen; ad++; - len--; + len -= sizeof (struct grub_udf_long_ad); } } +fail: + if (buf) + grub_free (buf); + return 0; } From d20a3b371c2ffd438e070d9b04b3323cfb94d9c9 Mon Sep 17 00:00:00 2001 From: Modestas Vainius Date: Sun, 14 Nov 2010 17:09:13 +0100 Subject: [PATCH 0379/1414] * grub-core/kern/emu/getroot.c (grub_util_is_dmraid): Recognise ddf1_ fakeraid. --- ChangeLog | 5 +++++ grub-core/kern/emu/getroot.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9e1da9c60..1960277c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-14 Modestas Vainius + + * grub-core/kern/emu/getroot.c (grub_util_is_dmraid): Recognise ddf1_ + fakeraid. + 2010-11-14 Giuseppe Caizzone Add generic logical block size support for UDF. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 0433d49ed..f51dcd770 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -582,6 +582,8 @@ grub_util_is_dmraid (const char *os_dev) return 1; else if (! strncmp (os_dev, "/dev/mapper/sil_", 16)) return 1; + else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17)) + return 1; return 0; } From 779dc15bf63287eeae8184602c018b5120ee411f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Nov 2010 17:13:44 +0100 Subject: [PATCH 0380/1414] * configure.ac: Add -Wno-trampolines when supported. --- ChangeLog | 4 ++++ configure.ac | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1960277c0..c282b309c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-14 Vladimir Serbinenko + + * configure.ac: Add -Wno-trampolines when supported. + 2010-11-14 Modestas Vainius * grub-core/kern/emu/getroot.c (grub_util_is_dmraid): Recognise ddf1_ diff --git a/configure.ac b/configure.ac index 1ad3a8e98..a576d1c83 100644 --- a/configure.ac +++ b/configure.ac @@ -668,6 +668,20 @@ if test x"$grub_cv_cc_isystem" = xyes ; then fi fi +AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_cc_wnotrampolines], [ + SAVED_CFLAGS="$CFLAGS" + CFLAGS="$TARGET_CFLAGS -Wno-trampolines" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_wnotrampolines=yes], + [grub_cv_cc_wnotrampolines=no]) + CFLAGS="$SAVED_CFLAGS" +]) + +if test x"$grub_cv_cc_wnotrampolines" = xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -Wno-trampolines" +fi + # Restore the flags. CC="$tmp_CC" CFLAGS="$tmp_CFLAGS" From 03f80960cfbba5373b6fbecb3fa65387cfc24f25 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Nov 2010 23:36:20 +0100 Subject: [PATCH 0381/1414] Don't add -lgcc on i386 and x86_64. * configure.ac (LIBS): Don't add -lgcc on i386 and x86_64. * conf/Makefile.common (LDADD_KERNEL): Likewise. * grub-core/Makefile.core.def (kernel): Use LDADD_KERNEL. --- ChangeLog | 8 ++++++++ conf/Makefile.common | 19 ++++++++++++++++++- configure.ac | 5 ++++- grub-core/Makefile.core.def | 6 ++---- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c282b309c..19b6631fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-14 Vladimir Serbinenko + + Don't add -lgcc on i386 and x86_64. + + * configure.ac (LIBS): Don't add -lgcc on i386 and x86_64. + * conf/Makefile.common (LDADD_KERNEL): Likewise. + * grub-core/Makefile.core.def (kernel): Use LDADD_KERNEL. + 2010-11-14 Vladimir Serbinenko * configure.ac: Add -Wno-trampolines when supported. diff --git a/conf/Makefile.common b/conf/Makefile.common index a3ccebcc5..73b3d819b 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -45,7 +45,24 @@ CPPFLAGS_DEFAULT += -I$(top_srcdir)/include CPPFLAGS_DEFAULT += -I$(top_builddir)/include CCASFLAGS_DEFAULT = -DASM_FILE=1 -LDADD_KERNEL = -lgcc +LDADD_KERNEL = + +if ! COND_i386_pc +if ! COND_i386_efi +if ! COND_i386_qemu +if ! COND_i386_coreboot +if ! COND_i386_multiboot +if ! COND_i386_ieee1275 +if ! COND_x86_64_efi +LDADD_KERNEL += -lgcc +endif +endif +endif +endif +endif +endif +endif + CFLAGS_KERNEL = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding LDFLAGS_KERNEL = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N -static-libgcc CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) diff --git a/configure.ac b/configure.ac index a576d1c83..2b75883bc 100644 --- a/configure.ac +++ b/configure.ac @@ -579,8 +579,11 @@ else CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error" fi CPPFLAGS="$TARGET_CPPFLAGS" -LDFLAGS="$TARGET_LDFLAGS" +if test x$target_cpu = xi386 || test x$target_cpu = xx86_64 ; then +LIBS= +else LIBS=-lgcc +fi grub_ASM_USCORE if test x$grub_cv_asm_uscore = xyes; then diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8845c26ea..46c65adac 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -27,6 +27,8 @@ kernel = { i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; + ldadd = '$(LDADD_KERNEL)'; + i386_coreboot_ldflags = '-Wl,-Ttext=0x8200'; i386_multiboot_ldflags = '-Wl,-Ttext=0x8200'; i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000'; @@ -39,10 +41,6 @@ kernel = { emu_cflags = '$(CFLAGS_GNULIB)'; emu_cppflags = '$(CPPFLAGS_GNULIB)'; - mips_ldadd = '-lgcc'; - powerpc_ldadd = '-lgcc'; - sparc64_ldadd = '-lgcc'; - i386_pc_startup = kern/i386/pc/startup.S; i386_efi_startup = kern/i386/efi/startup.S; x86_64_efi_startup = kern/x86_64/efi/startup.S; From 22e7dbb2bb81165b847ba21897943d63abdb9a7f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Nov 2010 00:33:28 +0100 Subject: [PATCH 0382/1414] Fix quoting in legacy parser. * grub-core/lib/legacy_parse.c (grub_legacy_escape): Correctly handle single quotes. (grub_legacy_parse): Likewise. Reported by: Jordan Uggla. Tested by: Jordan Uggla. --- ChangeLog | 10 ++++++++++ grub-core/lib/legacy_parse.c | 31 ++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19b6631fd..7c33d8cc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-11-14 Vladimir Serbinenko + + Fix quoting in legacy parser. + + * grub-core/lib/legacy_parse.c (grub_legacy_escape): Correctly handle + single quotes. + (grub_legacy_parse): Likewise. + Reported by: Jordan Uggla. + Tested by: Jordan Uggla. + 2010-11-14 Vladimir Serbinenko Don't add -lgcc on i386 and x86_64. diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index cd3bc8d40..5a359ff1c 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -326,16 +326,22 @@ grub_legacy_escape (const char *in, grub_size_t len) char *ret, *outptr; int overhead = 0; for (ptr = in; ptr < in + len && *ptr; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; + if (*ptr == '\'') + overhead += 3; ret = grub_malloc (ptr - in + overhead + 1); if (!ret) return NULL; outptr = ret; for (ptr = in; ptr < in + len && *ptr; ptr++) { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; + if (*ptr == '\'') + { + *outptr++ = '\''; + *outptr++ = '\\'; + *outptr++ = '\''; + *outptr++ = '\''; + continue; + } *outptr++ = *ptr; } @@ -622,12 +628,13 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) { for (; *ptr && grub_isspace (*ptr); ptr++); for (; *ptr && !grub_isspace (*ptr); ptr++) - if (*ptr == '\\' || *ptr == '\'') - overhead++; + if (*ptr == '\'') + overhead += 3; if (*ptr) ptr++; overhead += 3; } + outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg)); if (!outptr0) return NULL; @@ -641,9 +648,15 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) *outptr++ = '\''; for (; *ptr && !grub_isspace (*ptr); ptr++) { - if (*ptr == '\\' || *ptr == '\'') - *outptr++ = '\\'; - *outptr++ = *ptr; + if (*ptr == '\'') + { + *outptr++ = '\''; + *outptr++ = '\\'; + *outptr++ = '\''; + *outptr++ = '\''; + } + else + *outptr++ = *ptr; } *outptr++ = '\''; if (*ptr) From f6bbabc3732c167464aeb7a165c693c94cbb1195 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Nov 2010 09:50:58 +0100 Subject: [PATCH 0383/1414] * grub-core/lib/relocator.c (malloc_in_range): Take into account that allocate_regbeg may need to create new chunk header. --- ChangeLog | 5 +++++ grub-core/lib/relocator.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c33d8cc6..1c862e1f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-15 Vladimir Serbinenko + + * grub-core/lib/relocator.c (malloc_in_range): Take into account that + allocate_regbeg may need to create new chunk header. + 2010-11-14 Vladimir Serbinenko Fix quoting in legacy parser. diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 90f6802d7..dbd5fe4d0 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -597,7 +597,8 @@ malloc_in_range (struct grub_relocator *rel, events[N].hancestor = pa; N++; events[N].type = REG_BEG_END; - events[N].pos = grub_vtop (p + p->size) - sizeof (*r); + events[N].pos = grub_vtop (p + p->size) - sizeof (*r) + - sizeof (struct grub_mm_header); N++; } else From e98937aaf03c35fb3fe1d23aa38e0935804e7fdf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Nov 2010 10:01:11 +0100 Subject: [PATCH 0384/1414] * grub-core/term/at_keyboard.c (grub_keyboard_controller_read) [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_QEMU]: ifdef-ed out (now unused). (grub_keyboard_controller_init) [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_QEMU]: Don't attempt to read the initial state since controller isn't inited yet. --- ChangeLog | 9 +++++++++ grub-core/term/at_keyboard.c | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1c862e1f0..8f78477e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-11-15 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c (grub_keyboard_controller_read) + [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_QEMU]: ifdef-ed out + (now unused). + (grub_keyboard_controller_init) + [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_QEMU]: Don't attempt to + read the initial state since controller isn't inited yet. + 2010-11-15 Vladimir Serbinenko * grub-core/lib/relocator.c (malloc_in_range): Take into account that diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 1b130bd62..5bc3f578c 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -257,6 +257,8 @@ grub_keyboard_controller_write (grub_uint8_t c) grub_outb (c, KEYBOARD_REG_DATA); } +#if !defined (GRUB_MACHINE_MIPS_YEELOONG) && !defined (GRUB_MACHINE_QEMU) + static grub_uint8_t grub_keyboard_controller_read (void) { @@ -265,6 +267,8 @@ grub_keyboard_controller_read (void) return grub_inb (KEYBOARD_REG_DATA); } +#endif + static int write_mode (int mode) { @@ -558,8 +562,13 @@ 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) + grub_keyboard_controller_orig = 0; + grub_keyboard_orig_set = 2; +#else grub_keyboard_controller_orig = grub_keyboard_controller_read (); grub_keyboard_orig_set = query_mode (); +#endif set_scancodes (); keyboard_controller_led (led_status); From 72b7c7aa36c495d63e6add293733b1de84ddb39d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 16 Nov 2010 15:50:20 +0000 Subject: [PATCH 0385/1414] * configure.ac: Make error messages less confusing by testing for -Wtrampolines rather than -Wno-trampolines (since -Wno-* is always accepted, but produces a diagnostic if something else is wrong). --- ChangeLog | 6 ++++++ configure.ac | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8f78477e9..7eada1d49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-16 Colin Watson + + * configure.ac: Make error messages less confusing by testing for + -Wtrampolines rather than -Wno-trampolines (since -Wno-* is always + accepted, but produces a diagnostic if something else is wrong). + 2010-11-15 Vladimir Serbinenko * grub-core/term/at_keyboard.c (grub_keyboard_controller_read) diff --git a/configure.ac b/configure.ac index 2b75883bc..c013c9022 100644 --- a/configure.ac +++ b/configure.ac @@ -673,7 +673,10 @@ fi AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_cc_wnotrampolines], [ SAVED_CFLAGS="$CFLAGS" - CFLAGS="$TARGET_CFLAGS -Wno-trampolines" + # Test for -Wtrampolines rather than -Wno-trampolines to reduce confusion + # in the event of later failures (since -Wno-* is always accepted, but + # produces a diagnostic if something else is wrong). + CFLAGS="$TARGET_CFLAGS -Wtrampolines" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include int va_arg_func (int fixed, va_list args);]], [[]])], [grub_cv_cc_wnotrampolines=yes], From 24ec575b72d8d5f6505ba1201ad7d5290cec295d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 16 Nov 2010 15:54:18 +0000 Subject: [PATCH 0386/1414] * conf/Makefile.common (CFLAGS_GNULIB): Add -Wno-unused-parameter. (-Wunused implies -Wunused-parameter, but not vice versa). --- ChangeLog | 5 +++++ conf/Makefile.common | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7eada1d49..42489cab7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-16 Colin Watson + + * conf/Makefile.common (CFLAGS_GNULIB): Add -Wno-unused-parameter. + (-Wunused implies -Wunused-parameter, but not vice versa). + 2010-11-16 Colin Watson * configure.ac: Make error messages less confusing by testing for diff --git a/conf/Makefile.common b/conf/Makefile.common index 73b3d819b..2df8465c0 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -97,7 +97,7 @@ platformdir = $(pkglibrootdir)/$(target_cpu)-$(platform) CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap -CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused +CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib CFLAGS_POSIX = -fno-builtin From f18088844f5d5973801bb17f5545e2c9150cd9fa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Nov 2010 08:41:18 +0100 Subject: [PATCH 0387/1414] Make legacy_source behave like source. * grub-core/commands/legacycfg.c (legacy_file): Don't call grub_show_menu. (grub_cmd_legacy_source): Call grub_show_menu if needed. --- ChangeLog | 8 ++++++++ grub-core/commands/legacycfg.c | 18 +++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42489cab7..3dc2e06da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-16 Vladimir Serbinenko + + Make legacy_source behave like source. + + * grub-core/commands/legacycfg.c (legacy_file): Don't call + grub_show_menu. + (grub_cmd_legacy_source): Call grub_show_menu if needed. + 2010-11-16 Colin Watson * conf/Makefile.common (CFLAGS_GNULIB): Add -Wno-unused-parameter. diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index d5441db06..80718196a 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -177,9 +177,6 @@ legacy_file (const char *filename) grub_free (suffix); grub_free (entrysrc); - if (menu && menu->size) - grub_show_menu (menu, 1); - return GRUB_ERR_NONE; } @@ -194,8 +191,8 @@ grub_cmd_legacy_source (struct grub_command *cmd, return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); extractor = (cmd->name[0] == 'e'); - new_env = (cmd->name[extractor ? sizeof ("extract_legacy_entries_") - 1 - : sizeof ("legacy_") - 1] == 'c'); + new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1) + : (sizeof ("legacy_") - 1)] == 'c'); if (new_env) grub_cls (); @@ -207,8 +204,15 @@ grub_cmd_legacy_source (struct grub_command *cmd, ret = legacy_file (args[0]); - if (new_env && !extractor) - grub_env_context_close (); + if (new_env) + { + grub_menu_t menu; + menu = grub_env_get_menu (); + if (menu && menu->size) + grub_show_menu (menu, 1); + if (!extractor) + grub_env_context_close (); + } if (extractor) grub_env_extractor_close (!new_env); From 1afcc914c5c7e45655ebe37646ed499de8d8d2fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Nov 2010 16:13:16 +0100 Subject: [PATCH 0388/1414] Make better UTF compliant. * grub-core/normal/charset.c (grub_utf8_to_utf16): Handle 6- and 7-byte sequences as incorrect. (grub_is_valid_utf8): Likewise. (grub_utf8_to_ucs4): Likewise. (grub_ucs4_to_utf8): Handle codepoints outside of BMP. (grub_ucs4_to_utf8_alloc): Likewise. * include/grub/charset.h (grub_utf16_to_utf8): Likewise. --- ChangeLog | 12 ++++++++++ grub-core/normal/charset.c | 45 +++++++++++--------------------------- include/grub/charset.h | 9 +++++++- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3dc2e06da..e5863f6b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-11-16 Vladimir Serbinenko + + Make better UTF compliant. + + * grub-core/normal/charset.c (grub_utf8_to_utf16): Handle 6- and 7-byte + sequences as incorrect. + (grub_is_valid_utf8): Likewise. + (grub_utf8_to_ucs4): Likewise. + (grub_ucs4_to_utf8): Handle codepoints outside of BMP. + (grub_ucs4_to_utf8_alloc): Likewise. + * include/grub/charset.h (grub_utf16_to_utf8): Likewise. + 2010-11-16 Vladimir Serbinenko Make legacy_source behave like source. diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index b7f775c4f..85ead53c4 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -113,16 +113,6 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, count = 3; code = c & GRUB_UINT8_3_TRAILINGBITS; } - else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS) - { - count = 4; - code = c & GRUB_UINT8_2_TRAILINGBITS; - } - else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS) - { - count = 5; - code = c & GRUB_UINT8_1_TRAILINGBIT; - } else return -1; } @@ -177,7 +167,7 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, /* No surrogates in UCS-4... */ *dest++ = '?'; } - else + else if (code < 0x10000) { if (dest + 2 >= destend) break; @@ -185,6 +175,15 @@ grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size, *dest++ = ((code >> 6) & 0x3F) | 0x80; *dest++ = (code & 0x3F) | 0x80; } + else + { + if (dest + 3 >= destend) + break; + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } } *dest = 0; } @@ -212,8 +211,10 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size) || (code >= 0xD800 && code <= 0xDBFF)) /* No surrogates in UCS-4... */ cnt++; - else + else if (code < 0x10000) cnt += 3; + else + cnt += 4; } cnt++; @@ -273,16 +274,6 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize) count = 3; code = c & 0x07; } - else if ((c & 0xfc) == 0xf8) - { - count = 4; - code = c & 0x03; - } - else if ((c & 0xfe) == 0xfc) - { - count = 5; - code = c & 0x01; - } else return 0; } @@ -375,16 +366,6 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, count = 3; code = c & 0x07; } - else if ((c & 0xfc) == 0xf8) - { - count = 4; - code = c & 0x03; - } - else if ((c & 0xfe) == 0xfc) - { - count = 5; - code = c & 0x01; - } else { /* invalid */ diff --git a/include/grub/charset.h b/include/grub/charset.h index 1d79d5d2c..c8247f78a 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -97,12 +97,19 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, /* Error... */ *dest++ = '?'; } - else + else if (code < 0x10000) { *dest++ = (code >> 12) | 0xE0; *dest++ = ((code >> 6) & 0x3F) | 0x80; *dest++ = (code & 0x3F) | 0x80; } + else + { + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } } } From 41cc919ef716d325ab31905a49fbbe255ddcda79 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 18 Nov 2010 02:08:01 +0100 Subject: [PATCH 0389/1414] * grub-core/normal/menu_entry.c (print_up): Fix displacement of up arrow. Reported by: Jordan Uggla. --- ChangeLog | 6 ++++++ grub-core/normal/menu_entry.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e5863f6b4..d839afb65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-18 Vladimir Serbinenko + + * grub-core/normal/menu_entry.c (print_up): Fix displacement of up + arrow. + Reported by: Jordan Uggla. + 2010-11-16 Vladimir Serbinenko Make better UTF compliant. diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 6cadf81ba..0bb51ca28 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -172,7 +172,7 @@ static void print_up (int flag, struct per_term_screen *term_screen) { grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X - + grub_term_entry_width (term_screen->term), + + grub_term_border_width (term_screen->term), GRUB_TERM_FIRST_ENTRY_Y); if (flag) From 9dfe92d07acd3da80d0a96ca89f036e71e04e553 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 18 Nov 2010 16:52:27 +0100 Subject: [PATCH 0390/1414] 2010-11-18 Robert Millan * grub-core/fs/btrfs.c (grub_btrfs_mount): Replace grub_strncmp() with grub_memcmp(). --- ChangeLog | 5 +++++ grub-core/fs/btrfs.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d839afb65..b78bdcce0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-18 Robert Millan + + * grub-core/fs/btrfs.c (grub_btrfs_mount): Replace grub_strncmp() + with grub_memcmp(). + 2010-11-18 Vladimir Serbinenko * grub-core/normal/menu_entry.c (print_up): Fix displacement of up diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index a50bae000..a2ee485b4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -51,7 +51,7 @@ grub_btrfs_mount (grub_disk_t disk) &data->sblock) != GRUB_ERR_NONE) goto fail; - if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1)) + if (grub_memcmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1)) { grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); goto fail; From 9acdcbf3254277b44d4558cfe73fde272b7d6e91 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 19 Nov 2010 10:15:25 +0530 Subject: [PATCH 0391/1414] use single quotes in menuentry setparams command --- grub-core/commands/menuentry.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 9718d1eab..7a07698d8 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -206,20 +206,6 @@ setparams_prefix (int argc, char **args) char *p; char *result; grub_size_t len = 10; - static const char *escape_characters = "\"\\"; - - auto char *strescpy (char *, const char *, const char *); - char * strescpy (char *d, const char *s, const char *escapes) - { - while (*s) - { - if (grub_strchr (escapes, *s)) - *d++ = '\\'; - *d++ = *s++; - } - *d = '\0'; - return d; - } /* Count resulting string length */ for (i = 0; i < argc; i++) @@ -227,7 +213,7 @@ setparams_prefix (int argc, char **args) len += 3; /* 3 = 1 space + 2 quotes */ p = args[i]; while (*p) - len += grub_strchr (escape_characters, *p++) ? 2 : 1; + len += (*p++ == '\'' ? 3 : 1); } result = grub_malloc (len + 2); @@ -240,9 +226,18 @@ setparams_prefix (int argc, char **args) for (j = 0; j < argc; j++) { result[i++] = ' '; - result[i++] = '"'; - i = strescpy (result + i, args[j], escape_characters) - result; - result[i++] = '"'; + result[i++] = '\''; + p = args[j]; + while (*p) { + result[i++] = *p; + if (*p == '\'') { + result[i++] = '\\'; + result[i++] = '\''; + result[i++] = '\''; + } + p++; + } + result[i++] = '\''; } result[i++] = '\n'; result[i] = '\0'; From 7e623b0d743d2311ee94185995622b3f47eaa322 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 19 Nov 2010 10:17:16 +0530 Subject: [PATCH 0392/1414] add changelog entry --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index d839afb65..b53b396b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-11-19 BVK Chaitanya + + Fix quoting in setparams in handling menuentry command. + + * grub-core/commands/menuentry.c (setparams_prefix): Use single + quotes for arguments. + 2010-11-18 Vladimir Serbinenko * grub-core/normal/menu_entry.c (print_up): Fix displacement of up From f866fe808bc574a9304a2ed184ab5c2f0c4b2eee Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 19 Nov 2010 19:08:44 +0530 Subject: [PATCH 0393/1414] reuse code from legacy parser --- ChangeLog | 7 +++++++ grub-core/commands/menuentry.c | 24 ++++++++---------------- grub-core/lib/legacy_parse.c | 25 ++++++------------------- grub-core/script/script.c | 21 +++++++++++++++++++++ include/grub/script_sh.h | 3 +++ 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index b53b396b5..eb8064188 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,13 @@ * grub-core/commands/menuentry.c (setparams_prefix): Use single quotes for arguments. + * grub-core/lib/legacy_parse.c (grub_legacy_escape): Use + grub_script_escape_squotes function instead. + + * include/grub/script_sh.h (grub_script_escape_squotes): New + prototype. + * grub-core/script/script.c (grub_script_escape_squotes): New + function. 2010-11-18 Vladimir Serbinenko diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 7a07698d8..f64378724 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -24,6 +24,7 @@ #include #include #include +#include static const struct grub_arg_option options[] = { @@ -221,26 +222,17 @@ setparams_prefix (int argc, char **args) return 0; grub_strcpy (result, "setparams"); - i = 9; + p = result + 9; for (j = 0; j < argc; j++) { - result[i++] = ' '; - result[i++] = '\''; - p = args[j]; - while (*p) { - result[i++] = *p; - if (*p == '\'') { - result[i++] = '\\'; - result[i++] = '\''; - result[i++] = '\''; - } - p++; - } - result[i++] = '\''; + *p++ = ' '; + *p++ = '\''; + p = grub_script_escape_squotes (p, args[j], grub_strlen (args[j])); + *p++ = '\''; } - result[i++] = '\n'; - result[i] = '\0'; + *p++ = '\n'; + *p = '\0'; return result; } diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 5a359ff1c..8fe60b03d 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -323,30 +324,16 @@ char * grub_legacy_escape (const char *in, grub_size_t len) { const char *ptr; - char *ret, *outptr; + char *outptr; int overhead = 0; for (ptr = in; ptr < in + len && *ptr; ptr++) if (*ptr == '\'') overhead += 3; - ret = grub_malloc (ptr - in + overhead + 1); - if (!ret) + outptr = grub_malloc (ptr - in + overhead + 1); + if (!outptr) return NULL; - outptr = ret; - for (ptr = in; ptr < in + len && *ptr; ptr++) - { - if (*ptr == '\'') - { - *outptr++ = '\''; - *outptr++ = '\\'; - *outptr++ = '\''; - *outptr++ = '\''; - continue; - } - - *outptr++ = *ptr; - } - *outptr++ = 0; - return ret; + grub_script_escape_squotes (outptr, in, len); + return outptr; } static char * diff --git a/grub-core/script/script.c b/grub-core/script/script.c index ad3018357..45c3222b2 100644 --- a/grub-core/script/script.c +++ b/grub-core/script/script.c @@ -22,6 +22,27 @@ #include #include +/* Escape single quotes in first `len' characters of `in' into a GRUB + script argument form into `out'; return address of the end in + `out'. */ +char * +grub_script_escape_squotes (char *out, const char *in, grub_size_t len) +{ + while (*in && len--) + { + *out++ = *in; + if (*in == '\'') + { + *out++ = '\\'; + *out++ = '\''; + *out++ = '\''; + } + in++; + } + *out = '\0'; + return out; +} + /* It is not possible to deallocate the memory when a syntax error was found. Because of that it is required to keep track of all memory allocations. The memory is freed in case of an error, or assigned diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 6d31fca5a..f5dcd881e 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -382,6 +382,9 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c grub_err_t grub_normal_parse_line (char *line, grub_reader_getline_t getline); +char * +grub_script_escape_squotes (char *out, const char *in, grub_size_t len); + static inline struct grub_script * grub_script_ref (struct grub_script *script) { From 7b61e6096bcb15a0066ed8d33992ed895062ffcd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Nov 2010 22:48:26 +0100 Subject: [PATCH 0394/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Don't try to retrieve the metadat sector if size isn't known. * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/mdraid1x_linux.c | 3 +++ grub-core/disk/mdraid_linux.c | 2 ++ 3 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index b78bdcce0..44e8badf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-19 Vladimir Serbinenko + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Don't try to + retrieve the metadat sector if size isn't known. + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. + 2010-11-18 Robert Millan * grub-core/fs/btrfs.c (grub_btrfs_mount): Replace grub_strncmp() diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index dd60df695..b1fce86a0 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -123,6 +123,9 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, for (minor_version = 0; minor_version < 3; ++minor_version) { + if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0) + continue; + switch (minor_version) { case 0: diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index f5cad9dbf..dc0d80ffd 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -170,6 +170,8 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, /* The sector where the mdraid 0.90 superblock is stored, if available. */ size = grub_disk_get_size (disk); + if (size == GRUB_DISK_SIZE_UNKNOWN) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid"); sector = NEW_SIZE_SECTORS (size); if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb)) From dfd240b122b77fe20219ee1490e8d9290a5c95ea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Nov 2010 22:52:27 +0100 Subject: [PATCH 0395/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Fix spurious warning. --- ChangeLog | 5 +++++ grub-core/disk/mdraid1x_linux.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 44e8badf2..c143eebb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-19 Vladimir Serbinenko + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Fix spurious + warning. + 2010-11-19 Vladimir Serbinenko * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Don't try to diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index b1fce86a0..b6a48b848 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -105,7 +105,7 @@ static grub_err_t grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, grub_disk_addr_t *start_sector) { - grub_disk_addr_t sector; + grub_disk_addr_t sector = 0; grub_uint64_t size; struct grub_raid_super_1x sb; grub_uint8_t minor_version; From 7f8b0fd7f0e08175e3468ad8732aad243d3d141a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Nov 2010 22:58:06 +0100 Subject: [PATCH 0396/1414] * grub-core/loader/i386/linux.c (grub_cmd_linux): Pass correctly the bootloader version instead of 0. --- ChangeLog | 5 +++++ grub-core/loader/i386/linux.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c143eebb8..8b98c1a4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-19 Vladimir Serbinenko + + * grub-core/loader/i386/linux.c (grub_cmd_linux): Pass correctly the + bootloader version instead of 0. + 2010-11-19 Vladimir Serbinenko * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Fix spurious diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index de4bec106..95aa6b456 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -655,7 +655,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4); + params->type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; /* These two are used (instead of cmd_line_ptr) by older versions of Linux, and otherwise ignored. */ From cf8ffc3825cc51eb2eb62a325aaa16f6a951f4c5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 22 Nov 2010 12:20:57 +0000 Subject: [PATCH 0397/1414] * util/grub-install.in: Remove excessive quoting that broke installations to RAID devices. --- ChangeLog | 5 +++++ util/grub-install.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8b98c1a4f..9782c205c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-22 Colin Watson + + * util/grub-install.in: Remove excessive quoting that broke + installations to RAID devices. + 2010-11-19 Vladimir Serbinenko * grub-core/loader/i386/linux.c (grub_cmd_linux): Pass correctly the diff --git a/util/grub-install.in b/util/grub-install.in index 00ad3fde4..ec210b309 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -473,7 +473,7 @@ fi # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). partmap_module= -for x in "`"$grub_probe" --device-map="${device_map}" --target=partmap --device "${grub_device}" 2> /dev/null`"; do +for x in `"$grub_probe" --device-map="${device_map}" --target=partmap --device "${grub_device}" 2> /dev/null`; do case "$x" in netbsd | openbsd) partmap_module="$partmap_module part_bsd";; From 03df09c7c825ad2f2b8a54264ca063dd72085c0c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 22 Nov 2010 13:57:16 +0000 Subject: [PATCH 0398/1414] * util/grub-install.in: Fix parsing of --grub-mkrelpath= option. --- ChangeLog | 4 ++++ util/grub-install.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9782c205c..14fa1a1c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-11-22 Colin Watson + + * util/grub-install.in: Fix parsing of --grub-mkrelpath= option. + 2010-11-22 Colin Watson * util/grub-install.in: Remove excessive quoting that broke diff --git a/util/grub-install.in b/util/grub-install.in index ec210b309..b9e833360 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -205,7 +205,7 @@ do --grub-mkrelpath) grub_mkrelpath="`argument "$option" "$@"`"; shift;; - --grub-mkimage=*) + --grub-mkrelpath=*) grub_mkrelpath="`echo "$option" | sed 's/--grub-mkrelpath=//'`" ;; --grub-mkdevicemap) From e6f63338f70bc9e315cc68d0b1f0af358dd89530 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 22 Nov 2010 18:22:00 +0000 Subject: [PATCH 0399/1414] usual e-mail address --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 14fa1a1c5..7fb54fc99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -2010-11-22 Colin Watson +2010-11-22 Colin Watson * util/grub-install.in: Fix parsing of --grub-mkrelpath= option. From 14e8b279e9789d22106a5ac8fa7630659c7032c5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 22 Nov 2010 18:22:50 +0000 Subject: [PATCH 0400/1414] Fix test program build on GNU/kFreeBSD. * Makefile.util.def (example_unit_test): Add `$(LIBZFS) $(LIBNVPAIR)' library dependencies. --- ChangeLog | 7 +++++++ Makefile.util.def | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7fb54fc99..03f5f5e19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-11-22 Colin Watson + + Fix test program build on GNU/kFreeBSD. + + * Makefile.util.def (example_unit_test): Add `$(LIBZFS) + $(LIBNVPAIR)' library dependencies. + 2010-11-22 Colin Watson * util/grub-install.in: Fix parsing of --grub-mkrelpath= option. diff --git a/Makefile.util.def b/Makefile.util.def index 94dfb1044..748bb1c59 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -607,7 +607,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER)'; + ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; program = { From 7242bab6a496eb28aa469b3f8bf5768b64425f4e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 23 Nov 2010 10:48:46 +0000 Subject: [PATCH 0401/1414] * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): Remove byte-swapping function calls, which are not valid in structure initialisers. * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot): Make non-const. (GRUB_MOD_INIT): Byte-swap data1, data2, and data3 fields of grub_gpt_partition_type_bios_boot. --- ChangeLog | 10 ++++++++++ grub-core/partmap/gpt.c | 10 +++++++++- include/grub/gpt_partition.h | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03f5f5e19..815004080 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-11-23 Colin Watson + + * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): + Remove byte-swapping function calls, which are not valid in + structure initialisers. + * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot): Make + non-const. + (GRUB_MOD_INIT): Byte-swap data1, data2, and data3 fields of + grub_gpt_partition_type_bios_boot. + 2010-11-22 Colin Watson Fix test program build on GNU/kFreeBSD. diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 7f2c36143..13223460b 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -33,7 +33,7 @@ static grub_uint8_t grub_gpt_magic[8] = static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; #ifdef GRUB_UTIL -static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; +static grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; #endif /* 512 << 7 = 65536 byte sectors. */ @@ -198,6 +198,14 @@ static struct grub_partition_map grub_gpt_partition_map = GRUB_MOD_INIT(part_gpt) { grub_partition_map_register (&grub_gpt_partition_map); +#ifdef GRUB_UTIL + grub_gpt_partition_type_bios_boot.data1 = + grub_cpu_to_le32 (grub_gpt_partition_type_bios_boot.data1); + grub_gpt_partition_type_bios_boot.data2 = + grub_cpu_to_le16 (grub_gpt_partition_type_bios_boot.data2); + grub_gpt_partition_type_bios_boot.data3 = + grub_cpu_to_le16 (grub_gpt_partition_type_bios_boot.data3); +#endif } GRUB_MOD_FINI(part_gpt) diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h index 428ceb166..bc3d3f210 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -36,7 +36,7 @@ typedef struct grub_gpt_part_type grub_gpt_part_type_t; } #define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \ - { grub_cpu_to_le32 (0x21686148), grub_cpu_to_le16 (0x6449), grub_cpu_to_le16 (0x6e6f), \ + { 0x21686148, 0x6449, 0x6e6f, \ { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \ } From bf16e98e3c93890c32cea3d612913d9bdf544378 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 23 Nov 2010 12:52:40 +0000 Subject: [PATCH 0402/1414] * grub-core/Makefile.am (command.lst): Adjust sed expression ordering so that extended and priority commands aren't treated as ordinary commands. --- ChangeLog | 6 ++++++ grub-core/Makefile.am | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 815004080..4a09faca4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-23 Colin Watson + + * grub-core/Makefile.am (command.lst): Adjust sed expression + ordering so that extended and priority commands aren't treated as + ordinary commands. + 2010-11-23 Colin Watson * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 9792dd974..131fa5fd7 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -237,9 +237,9 @@ command.lst: $(MARKER_FILES) (for pp in $^; do \ b=`basename $$pp .marker`; \ sed -n \ - -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ - -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" $$pp; \ + -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ done) | sort -u > $@ platform_DATA += command.lst CLEANFILES += command.lst From 038b3ce8dc10e598b95aa8f92a243bdfaa078e84 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 23 Nov 2010 13:00:05 +0000 Subject: [PATCH 0403/1414] * grub-core/Makefile.am (gentrigtables): Put -lm after $<; some linkers are picky about this. --- ChangeLog | 5 +++++ grub-core/Makefile.am | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4a09faca4..5f38faf42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-23 Colin Watson + + * grub-core/Makefile.am (gentrigtables): Put -lm after $<; some + linkers are picky about this. + 2010-11-23 Colin Watson * grub-core/Makefile.am (command.lst): Adjust sed expression diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 131fa5fd7..073ce37f6 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -30,7 +30,7 @@ CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM) # gentrigtables gentrigtables: gentrigtables.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(CPPFLAGS) -lm $< + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(CPPFLAGS) $< -lm CLEANFILES += gentrigtables # trigtables.c From 5225f3288296190e8fa16a34560b1b7bf2ae4a6b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 23 Nov 2010 15:56:18 +0000 Subject: [PATCH 0404/1414] * Makefile.util.def (grub-menulst2cfg): List libraries in ldadd, not ldflags, to fix link line ordering. --- ChangeLog | 5 +++++ Makefile.util.def | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5f38faf42..9b01330d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-23 Colin Watson + + * Makefile.util.def (grub-menulst2cfg): List libraries in ldadd, not + ldflags, to fix link line ordering. + 2010-11-23 Colin Watson * grub-core/Makefile.am (gentrigtables): Put -lm after $<; some diff --git a/Makefile.util.def b/Makefile.util.def index 748bb1c59..3e8ae16f5 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -620,5 +620,5 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldflags = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; From b7fbac1214cfb38fd81f2d2555b34064456a1424 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 23 Nov 2010 17:42:06 +0000 Subject: [PATCH 0405/1414] * util/deviceiter.c (compare_devices): If the by-id link for a device couldn't be resolved, fall back to sorting by the by-id link rather than segfaulting. Reported and tested by: Daniel Mierswa. --- ChangeLog | 7 +++++++ util/deviceiter.c | 15 +++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b01330d5..c6bbffd99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-11-23 Colin Watson + + * util/deviceiter.c (compare_devices): If the by-id link for a + device couldn't be resolved, fall back to sorting by the by-id link + rather than segfaulting. + Reported and tested by: Daniel Mierswa. + 2010-11-23 Colin Watson * Makefile.util.def (grub-menulst2cfg): List libraries in ldadd, not diff --git a/util/deviceiter.c b/util/deviceiter.c index 34d34b7bb..1de8e54df 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -485,12 +485,15 @@ compare_devices (const void *a, const void *b) { const struct device *left = (const struct device *) a; const struct device *right = (const struct device *) b; - int ret; - ret = strcmp (left->kernel, right->kernel); - if (ret) - return ret; - else - return strcmp (left->stable, right->stable); + + if (left->kernel && right->kernel) + { + int ret = strcmp (left->kernel, right->kernel); + if (ret) + return ret; + } + + return strcmp (left->stable, right->stable); } #endif /* __linux__ */ From 3030d8ec490c87a85ac1fd9fbff7b9eecfb8cfec Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 24 Nov 2010 12:07:14 +0000 Subject: [PATCH 0406/1414] * grub-core/Makefile.core.def (kernel): Add kern/emu/cache.S for emu platforms. (grub-emu-lite): Remove kern/emu/cache.S. --- ChangeLog | 6 ++++++ grub-core/Makefile.core.def | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c6bbffd99..39a6b5146 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-24 Colin Watson + + * grub-core/Makefile.core.def (kernel): Add kern/emu/cache.S for emu + platforms. + (grub-emu-lite): Remove kern/emu/cache.S. + 2010-11-23 Colin Watson * util/deviceiter.c (compare_devices): If the by-id link for a diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 46c65adac..098df91dc 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -162,6 +162,7 @@ kernel = { emu = disk/host.c; emu = gnulib/progname.c; emu = gnulib/error.c; + emu = kern/emu/cache.S; emu = kern/emu/console.c; emu = kern/emu/getroot.c; emu = kern/emu/hostdisk.c; @@ -208,7 +209,6 @@ program = { name = grub-emu-lite; emu = kern/emu/lite.c; - emu = kern/emu/cache.S; emu_nodist = symlist.c; ldadd = 'kernel.img$(EXEEXT)'; From 5a4072785bbaec011b37e0d46a3d2bcd0127a150 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 24 Nov 2010 19:32:49 +0000 Subject: [PATCH 0407/1414] * grub-core/Makefile.core.def (xz_decompress): Move -lgcc from ldflags to ldadd, to fix link line ordering. (none_decompress): Likewise. --- ChangeLog | 6 ++++++ grub-core/Makefile.core.def | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39a6b5146..f29ade31c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-24 Colin Watson + + * grub-core/Makefile.core.def (xz_decompress): Move -lgcc from + ldflags to ldadd, to fix link line ordering. + (none_decompress): Likewise. + 2010-11-24 Colin Watson * grub-core/Makefile.core.def (kernel): Add kern/emu/cache.S for emu diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 098df91dc..ce10ba372 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -300,7 +300,8 @@ image = { mips_cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; objcopyflags = '-O binary'; - ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; + ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + ldadd = '-lgcc'; cflags = '-static-libgcc'; enable = mips; }; @@ -313,7 +314,8 @@ image = { mips_cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1 -DGRUB_MACHINE_LINK_ADDR=0x80200000'; objcopyflags = '-O binary'; - ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000'; + ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + ldadd = '-lgcc'; cflags = '-static-libgcc'; enable = mips; }; From 74f72a6415a450219afe51fa0f2c17ffdb085e61 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 24 Nov 2010 19:43:32 +0000 Subject: [PATCH 0408/1414] * util/deviceiter.c (grub_util_iterate_devices): Save a bit of effort by skipping "." and ".." entries up-front. Suggested by: Michael Lazarev. --- ChangeLog | 6 ++++++ util/deviceiter.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index f29ade31c..6bc7f1b9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-24 Colin Watson + + * util/deviceiter.c (grub_util_iterate_devices): Save a bit of + effort by skipping "." and ".." entries up-front. + Suggested by: Michael Lazarev. + 2010-11-24 Colin Watson * grub-core/Makefile.core.def (xz_decompress): Move -lgcc from diff --git a/util/deviceiter.c b/util/deviceiter.c index 1de8e54df..30c18beea 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -536,6 +536,10 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), necessary. */ for (entry = readdir (dir); entry; entry = readdir (dir)) { + /* Skip current and parent directory entries. */ + if (strcmp (entry->d_name, ".") == 0 || + strcmp (entry->d_name, "..") == 0) + continue; /* Skip partition entries. */ if (strstr (entry->d_name, "-part")) continue; From d7647bb6702570b0916e2fe83be980c936b7bb6f Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 25 Nov 2010 18:25:26 +0530 Subject: [PATCH 0409/1414] better changelog message --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eb8064188..29eb61fd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2010-11-19 BVK Chaitanya - Fix quoting in setparams in handling menuentry command. + Fix cmdline argument quotes for setparams command of menuentry + definitions. * grub-core/commands/menuentry.c (setparams_prefix): Use single quotes for arguments. From 5b080620834f8c8df4972d5af761d7d3a768964a Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 25 Nov 2010 18:56:20 +0530 Subject: [PATCH 0410/1414] replaced with grub_strchrsub function --- grub-core/commands/menuentry.c | 2 +- grub-core/lib/legacy_parse.c | 13 ++++++++++--- grub-core/script/script.c | 21 --------------------- include/grub/misc.h | 20 ++++++++++++++++++++ include/grub/script_sh.h | 3 --- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index f64378724..c0743d1ed 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -228,7 +228,7 @@ setparams_prefix (int argc, char **args) { *p++ = ' '; *p++ = '\''; - p = grub_script_escape_squotes (p, args[j], grub_strlen (args[j])); + p = grub_strchrsub (p, args[j], '\'', "'\\''"); *p++ = '\''; } *p++ = '\n'; diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 8fe60b03d..d3a133591 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -323,16 +323,23 @@ struct legacy_command legacy_commands[] = char * grub_legacy_escape (const char *in, grub_size_t len) { - const char *ptr; + char saved; + char *ptr; char *outptr; int overhead = 0; - for (ptr = in; ptr < in + len && *ptr; ptr++) + + for (ptr = (char*)in; ptr < in + len && *ptr; ptr++) if (*ptr == '\'') overhead += 3; outptr = grub_malloc (ptr - in + overhead + 1); if (!outptr) return NULL; - grub_script_escape_squotes (outptr, in, len); + + ptr = (char*)in; + saved = ptr[len]; + ptr[len] = '\0'; + grub_strchrsub (outptr, in, '\'', "'\\''"); + ptr[len] = saved; return outptr; } diff --git a/grub-core/script/script.c b/grub-core/script/script.c index 45c3222b2..ad3018357 100644 --- a/grub-core/script/script.c +++ b/grub-core/script/script.c @@ -22,27 +22,6 @@ #include #include -/* Escape single quotes in first `len' characters of `in' into a GRUB - script argument form into `out'; return address of the end in - `out'. */ -char * -grub_script_escape_squotes (char *out, const char *in, grub_size_t len) -{ - while (*in && len--) - { - *out++ = *in; - if (*in == '\'') - { - *out++ = '\\'; - *out++ = '\''; - *out++ = '\''; - } - in++; - } - *out = '\0'; - return out; -} - /* It is not possible to deallocate the memory when a syntax error was found. Because of that it is required to keep track of all memory allocations. The memory is freed in case of an error, or assigned diff --git a/include/grub/misc.h b/include/grub/misc.h index 27f15e44a..4980281a6 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -193,6 +193,26 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); } +/* Replace all `ch' characters of `input' with `with' and copy the + result into `output'; return address of the end in `output'. */ +static inline char * +grub_strchrsub (char *output, const char *input, char ch, const char *with) +{ + grub_size_t grub_strlen (const char *s); + while (*input) + { + if (*input == ch) + { + grub_strcpy (output, with); + output += grub_strlen (with); + input++; + continue; + } + *output++ = *input++; + } + *output = '\0'; + return output; +} unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index f5dcd881e..6d31fca5a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -382,9 +382,6 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c grub_err_t grub_normal_parse_line (char *line, grub_reader_getline_t getline); -char * -grub_script_escape_squotes (char *out, const char *in, grub_size_t len); - static inline struct grub_script * grub_script_ref (struct grub_script *script) { From 7955bea0d8b7cfff626dbc74496845a4db6cf8cb Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 25 Nov 2010 19:05:16 +0530 Subject: [PATCH 0411/1414] fix changelog and doc --- ChangeLog | 7 ++----- grub-core/commands/menuentry.c | 1 - grub-core/lib/legacy_parse.c | 13 ++++++------- include/grub/misc.h | 2 +- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29eb61fd5..e13489f15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,12 +6,9 @@ * grub-core/commands/menuentry.c (setparams_prefix): Use single quotes for arguments. * grub-core/lib/legacy_parse.c (grub_legacy_escape): Use - grub_script_escape_squotes function instead. + grub_strchrsub function instead. - * include/grub/script_sh.h (grub_script_escape_squotes): New - prototype. - * grub-core/script/script.c (grub_script_escape_squotes): New - function. + * include/grub/misc.h (grub_strchrsub): New function. 2010-11-18 Vladimir Serbinenko diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index c0743d1ed..4dab1783a 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -24,7 +24,6 @@ #include #include #include -#include static const struct grub_arg_option options[] = { diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index d3a133591..f7f86c105 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -323,24 +322,24 @@ struct legacy_command legacy_commands[] = char * grub_legacy_escape (const char *in, grub_size_t len) { - char saved; char *ptr; - char *outptr; + char saved; + char *ret; int overhead = 0; for (ptr = (char*)in; ptr < in + len && *ptr; ptr++) if (*ptr == '\'') overhead += 3; - outptr = grub_malloc (ptr - in + overhead + 1); - if (!outptr) + ret = grub_malloc (ptr - in + overhead + 1); + if (!ret) return NULL; ptr = (char*)in; saved = ptr[len]; ptr[len] = '\0'; - grub_strchrsub (outptr, in, '\'', "'\\''"); + grub_strchrsub (ret, ptr, '\'', "'\\''"); ptr[len] = saved; - return outptr; + return ret; } static char * diff --git a/include/grub/misc.h b/include/grub/misc.h index 4980281a6..6fcaa148b 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -194,7 +194,7 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) } /* Replace all `ch' characters of `input' with `with' and copy the - result into `output'; return address of the end in `output'. */ + result into `output'; return EOS address of `output'. */ static inline char * grub_strchrsub (char *output, const char *input, char ch, const char *with) { From dfda224dd8807fe8ad79356dc354215ed9b9b9e3 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 25 Nov 2010 19:07:02 +0530 Subject: [PATCH 0412/1414] variable ordering --- grub-core/lib/legacy_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index f7f86c105..fe421af35 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -323,8 +323,8 @@ char * grub_legacy_escape (const char *in, grub_size_t len) { char *ptr; - char saved; char *ret; + char saved; int overhead = 0; for (ptr = (char*)in; ptr < in + len && *ptr; ptr++) From 9be57a0dad345ef19b6eeaea68b8b8562116b937 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 26 Nov 2010 12:26:37 +0000 Subject: [PATCH 0413/1414] Fix LVM-on-RAID probing. * util/grub-probe.c (probe): Remember which disk was detected as RAID (perhaps an LVM physical volume). Use that disk's raidname rather than that of the top-level disk. --- ChangeLog | 8 ++++++++ util/grub-probe.c | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05bf3b270..f9e24a808 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-26 Colin Watson + + Fix LVM-on-RAID probing. + + * util/grub-probe.c (probe): Remember which disk was detected as + RAID (perhaps an LVM physical volume). Use that disk's raidname + rather than that of the top-level disk. + 2010-11-25 BVK Chaitanya Fix cmdline argument quotes for setparams command of menuentry diff --git a/util/grub-probe.c b/util/grub-probe.c index 1d00a7db3..0d5dac902 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -142,6 +142,7 @@ probe (const char *path, char *device_name) int is_raid5 = 0; int is_raid6 = 0; int raid_level; + grub_disk_t raid_disk; raid_level = probe_raid_level (dev->disk); if (raid_level >= 0) @@ -149,6 +150,7 @@ probe (const char *path, char *device_name) is_raid = 1; is_raid5 |= (raid_level == 5); is_raid6 |= (raid_level == 6); + raid_disk = dev->disk; } if ((is_lvm) && (dev->disk->dev->memberlist)) @@ -161,6 +163,7 @@ probe (const char *path, char *device_name) is_raid = 1; is_raid5 |= (raid_level == 5); is_raid6 |= (raid_level == 6); + raid_disk = list->disk; } tmp = list->next; @@ -175,8 +178,8 @@ probe (const char *path, char *device_name) printf ("raid5rec "); if (is_raid6) printf ("raid6rec "); - if (dev->disk->dev->raidname) - printf ("%s ", dev->disk->dev->raidname (dev->disk)); + if (raid_disk->dev->raidname) + printf ("%s ", raid_disk->dev->raidname (raid_disk)); } if (is_lvm) From 4e7db17be991b3b00f44d28b08e4552b0b801357 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 26 Nov 2010 15:35:40 +0100 Subject: [PATCH 0414/1414] 2010-11-26 Robert Millan * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN): Beautify. Update all users. --- ChangeLog | 5 +++++ grub-core/term/i386/pc/vga_text.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9e24a808..0cb1628cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-26 Robert Millan + + * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN): Beautify. + Update all users. + 2010-11-26 Colin Watson Fix LVM-on-RAID probing. diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c index 1685b3db0..fbb65ae0c 100644 --- a/grub-core/term/i386/pc/vga_text.c +++ b/grub-core/term/i386/pc/vga_text.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 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 @@ -27,18 +27,18 @@ static int grub_curr_x, grub_curr_y; -#define VGA_TEXT_SCREEN 0xb8000 +#define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb8000) static void screen_write_char (int x, int y, short c) { - ((short *) VGA_TEXT_SCREEN)[y * COLS + x] = c; + VGA_TEXT_SCREEN[y * COLS + x] = c; } static short screen_read_char (int x, int y) { - return ((short *) VGA_TEXT_SCREEN)[y * COLS + x]; + return VGA_TEXT_SCREEN[y * COLS + x]; } static void @@ -120,7 +120,7 @@ grub_vga_text_cls (struct grub_term_output *term) { int i; for (i = 0; i < ROWS * COLS; i++) - ((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8); + VGA_TEXT_SCREEN[i] = ' ' | (grub_console_cur_color << 8); grub_vga_text_gotoxy (term, 0, 0); } From f420a80458c1389c9be96925e5e33541bc73f8a7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Nov 2010 22:03:16 +0100 Subject: [PATCH 0415/1414] * util/grub-setup.c (setup): Stop recommending --force. People who understand the dangers of blocklists are able to find this option anyway and the ones who don't shouldn't use it anyway. --- ChangeLog | 6 ++++++ util/grub-setup.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0cb1628cc..6596421b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-26 Vladimir Serbinenko + + * util/grub-setup.c (setup): Stop recommending --force. People who + understand the dangers of blocklists are able to find this option + anyway and the ones who don't shouldn't use it anyway. + 2010-11-26 Robert Millan * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN): Beautify. diff --git a/util/grub-setup.c b/util/grub-setup.c index fa95f94aa..5f9b29f25 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -492,7 +492,7 @@ unable_to_embed: "setup by using blocklists. However, blocklists are UNRELIABLE and " "their use is discouraged.")); if (! force) - grub_util_error (_("if you really want blocklists, use --force")); + grub_util_error (_("will not proceed with blocklists")); /* The core image must be put on a filesystem unfortunately. */ grub_util_info ("will leave the core image on the filesystem"); From 49d3ab4668fa4f12e714f9d231d8756e17a58ee2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Nov 2010 22:29:19 +0100 Subject: [PATCH 0416/1414] Avoid using tricks for initialising endian variables. * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot): Make const. (GRUB_MOD_INIT): Don't byte-swap. * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): Use grub_cpu_to_le16_compile_time and grub_cpu_to_le32_compile_time. * include/grub/types.h (grub_swap_bytes16_compile_time): New macro. (grub_swap_bytes32_compile_time): Likewise. (grub_cpu_to_le32_compile_time): Likewise. (grub_cpu_to_le16_compile_time): Likewise. --- ChangeLog | 14 ++++++++++++++ grub-core/partmap/gpt.c | 10 +--------- include/grub/gpt_partition.h | 2 +- include/grub/types.h | 7 +++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6596421b2..8627ccc79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-11-26 Vladimir Serbinenko + + Avoid using tricks for initialising endian variables. + + * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot): + Make const. + (GRUB_MOD_INIT): Don't byte-swap. + * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): + Use grub_cpu_to_le16_compile_time and grub_cpu_to_le32_compile_time. + * include/grub/types.h (grub_swap_bytes16_compile_time): New macro. + (grub_swap_bytes32_compile_time): Likewise. + (grub_cpu_to_le32_compile_time): Likewise. + (grub_cpu_to_le16_compile_time): Likewise. + 2010-11-26 Vladimir Serbinenko * util/grub-setup.c (setup): Stop recommending --force. People who diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 13223460b..7f2c36143 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -33,7 +33,7 @@ static grub_uint8_t grub_gpt_magic[8] = static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; #ifdef GRUB_UTIL -static grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; +static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; #endif /* 512 << 7 = 65536 byte sectors. */ @@ -198,14 +198,6 @@ static struct grub_partition_map grub_gpt_partition_map = GRUB_MOD_INIT(part_gpt) { grub_partition_map_register (&grub_gpt_partition_map); -#ifdef GRUB_UTIL - grub_gpt_partition_type_bios_boot.data1 = - grub_cpu_to_le32 (grub_gpt_partition_type_bios_boot.data1); - grub_gpt_partition_type_bios_boot.data2 = - grub_cpu_to_le16 (grub_gpt_partition_type_bios_boot.data2); - grub_gpt_partition_type_bios_boot.data3 = - grub_cpu_to_le16 (grub_gpt_partition_type_bios_boot.data3); -#endif } GRUB_MOD_FINI(part_gpt) diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h index bc3d3f210..5f8ddead7 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -36,7 +36,7 @@ typedef struct grub_gpt_part_type grub_gpt_part_type_t; } #define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \ - { 0x21686148, 0x6449, 0x6e6f, \ + { grub_cpu_to_le32_compile_time (0x21686148), grub_cpu_to_le16_compile_time (0x6449), grub_cpu_to_le16_compile_time (0x6e6f), \ { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \ } diff --git a/include/grub/types.h b/include/grub/types.h index e57666a10..8632eacd0 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -146,6 +146,9 @@ typedef grub_uint64_t grub_disk_addr_t; (grub_uint16_t) ((_x << 8) | (_x >> 8)); \ }) +#define grub_swap_bytes16_compile_time(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define grub_swap_bytes32_compile_time(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000UL) >> 24)) + #if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x) { @@ -193,6 +196,8 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) ((grub_uint16_t) (x)) # define grub_be_to_cpu32(x) ((grub_uint32_t) (x)) # define grub_be_to_cpu64(x) ((grub_uint64_t) (x)) +# define grub_cpu_to_le32_compile_time(x) grub_swap_bytes32_compile_time(x) +# define grub_cpu_to_le16_compile_time(x) grub_swap_bytes16_compile_time(x) #else /* ! WORDS_BIGENDIAN */ # define grub_cpu_to_le16(x) ((grub_uint16_t) (x)) # define grub_cpu_to_le32(x) ((grub_uint32_t) (x)) @@ -206,6 +211,8 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) grub_swap_bytes16(x) # define grub_be_to_cpu32(x) grub_swap_bytes32(x) # define grub_be_to_cpu64(x) grub_swap_bytes64(x) +# define grub_cpu_to_le16_compile_time(x) ((grub_uint16_t) (x)) +# define grub_cpu_to_le32_compile_time(x) ((grub_uint32_t) (x)) #endif /* ! WORDS_BIGENDIAN */ #endif /* ! GRUB_TYPES_HEADER */ From 8c317b270ff609a5a1e4f9776d6ea5ec9ba05ef5 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 30 Nov 2010 15:36:47 +0100 Subject: [PATCH 0417/1414] 2010-11-30 Robert Millan * grub-core/commands/echo.c (grub_cmd_echo): Call grub_refresh() after printing a message. --- ChangeLog | 5 +++++ grub-core/commands/echo.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 815004080..92071f3c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-11-30 Robert Millan + + * grub-core/commands/echo.c (grub_cmd_echo): Call grub_refresh() + after printing a message. + 2010-11-23 Colin Watson * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c index 13bc1c3fd..2842de603 100644 --- a/grub-core/commands/echo.c +++ b/grub-core/commands/echo.c @@ -1,7 +1,7 @@ /* echo.c - Command to display a line of text */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,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 @@ -106,6 +106,8 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) if (newline) grub_printf ("\n"); + grub_refresh (); + return 0; } From c5c9cd3e7de4aa669231f6c18baf08530b54a7ed Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 30 Nov 2010 16:23:41 +0100 Subject: [PATCH 0418/1414] Add missing include --- ChangeLog | 4 ++-- grub-core/commands/echo.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92071f3c5..faa5f31c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 2010-11-30 Robert Millan - * grub-core/commands/echo.c (grub_cmd_echo): Call grub_refresh() - after printing a message. + * grub-core/commands/echo.c: Include `'. + (grub_cmd_echo): Call grub_refresh() after printing a message. 2010-11-23 Colin Watson diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c index 2842de603..7ab9f92c6 100644 --- a/grub-core/commands/echo.c +++ b/grub-core/commands/echo.c @@ -21,6 +21,7 @@ #include #include #include +#include static const struct grub_arg_option options[] = { From 3a4253b2c47c48b561a316068ce652e0e2020715 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 30 Nov 2010 19:33:12 +0100 Subject: [PATCH 0419/1414] 2010-11-30 Robert Millan * grub-core/loader/i386/bsd.c (grub_cmd_freebsd_loadenv, grub_cmd_freebsd_module_elf): Check whether kernel is loaded using grub_loader_is_loaded(), rather than `kernel_type', which may still be `KERNEL_TYPE_NONE' under certain error conditions. --- ChangeLog | 8 ++++++++ grub-core/loader/i386/bsd.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8bcdb549..33004a8c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-11-30 Robert Millan + + * grub-core/loader/i386/bsd.c + (grub_cmd_freebsd_loadenv, grub_cmd_freebsd_module_elf): Check + whether kernel is loaded using grub_loader_is_loaded(), rather + than `kernel_type', which may still be `KERNEL_TYPE_NONE' under + certain error conditions. + 2010-11-30 Robert Millan * grub-core/commands/echo.c: Include `'. diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index b7cf115d9..91cae418c 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -1611,7 +1611,7 @@ grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)), char *buf = 0, *curr, *next; int len; - if (kernel_type == KERNEL_TYPE_NONE) + if (! grub_loader_is_loaded ()) return grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); @@ -1844,7 +1844,7 @@ grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; grub_err_t err; - if (kernel_type == KERNEL_TYPE_NONE) + if (! grub_loader_is_loaded ()) return grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); From 3f0f38317b0ea76c1bdaf288f0a3e2a568476507 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 30 Nov 2010 21:35:59 +0100 Subject: [PATCH 0420/1414] * grub-core/commands/regexp.c (grub_cmd_regexp): Remove unused variable. * grub-core/commands/wildcard.c (match_files): Likewise. --- ChangeLog | 6 ++++++ grub-core/commands/regexp.c | 1 - grub-core/commands/wildcard.c | 3 --- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33004a8c8..4effc2ff4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-30 Szymon Janc + + * grub-core/commands/regexp.c (grub_cmd_regexp): Remove unused + variable. + * grub-core/commands/wildcard.c (match_files): Likewise. + 2010-11-30 Robert Millan * grub-core/loader/i386/bsd.c diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c index f27a147af..83c0d8d43 100644 --- a/grub-core/commands/regexp.c +++ b/grub-core/commands/regexp.c @@ -87,7 +87,6 @@ set_matches (char **varnames, char *str, grub_size_t nmatches, static grub_err_t grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args) { - int argn = 0; regex_t regex; int ret; grub_size_t s; diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 6eab333b3..32561abe6 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -266,7 +266,6 @@ match_files (const char *prefix, const char *suffix, const char *end, const regex_t *regexp) { int i; - int error; char **files; unsigned nfile; char *dir; @@ -440,8 +439,6 @@ wildcard_expand (const char *s, char ***strs) else if (*start == '/') /* no device part */ { - char **r; - unsigned n; char *root; char *prefix; From 3836e89df153ae4063ab55e9ea43e5820949a031 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 01:22:55 +0100 Subject: [PATCH 0421/1414] Add crc32c for btrfs --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 1 + grub-core/lib/crc.c | 75 +++++++++++++++++++++++++++++++++++++ include/grub/lib/crc.h | 25 +++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 grub-core/lib/crc.c create mode 100644 include/grub/lib/crc.h diff --git a/Makefile.util.def b/Makefile.util.def index 3e8ae16f5..4d642a2b6 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -79,6 +79,7 @@ library = { common = grub-core/lib/LzFind.c; common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/pbkdf2.c; + common = grub-core/lib/crc.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; common = grub-core/partmap/acorn.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ce10ba372..c62d7d12f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -905,6 +905,7 @@ module = { module = { name = btrfs; common = fs/btrfs.c; + common = lib/crc.c; }; module = { diff --git a/grub-core/lib/crc.c b/grub-core/lib/crc.c new file mode 100644 index 000000000..ffc3ef3b5 --- /dev/null +++ b/grub-core/lib/crc.c @@ -0,0 +1,75 @@ +/* crc.c - crc function */ +/* + * 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 + +static grub_uint32_t crc32c_table [256]; + +static void +init_crc32c_table (void) +{ + auto grub_uint32_t reflect (grub_uint32_t ref, int len); + grub_uint32_t reflect (grub_uint32_t ref, int len) + { + grub_uint32_t result = 0; + int i; + + for (i = 1; i <= len; i++) + { + if (ref & 1) + result |= 1 << (len - i); + ref >>= 1; + } + + return result; + } + + grub_uint32_t polynomial = 0x1edc6f41; + int i, j; + + for(i = 0; i < 256; i++) + { + crc32c_table[i] = reflect(i, 8) << 24; + for (j = 0; j < 8; j++) + crc32c_table[i] = (crc32c_table[i] << 1) ^ + (crc32c_table[i] & (1 << 31) ? polynomial : 0); + crc32c_table[i] = reflect(crc32c_table[i], 32); + } +} + +grub_uint32_t +grub_getcrc32c (grub_uint32_t crc, const void *buf, int size) +{ + int i; + const grub_uint8_t *data = buf; + + if (! crc32c_table[1]) + init_crc32c_table (); + + crc^= 0xffffffff; + + for (i = 0; i < size; i++) + { + crc = (crc >> 8) ^ crc32c_table[(crc & 0xFF) ^ *data]; + data++; + } + + return crc ^ 0xffffffff; +} diff --git a/include/grub/lib/crc.h b/include/grub/lib/crc.h new file mode 100644 index 000000000..c5098a8c3 --- /dev/null +++ b/include/grub/lib/crc.h @@ -0,0 +1,25 @@ +/* crc.h - prototypes for crc */ +/* + * 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_CRC_H +#define GRUB_CRC_H 1 + +grub_uint32_t grub_getcrc32c (grub_uint32_t crc, const void *buf, int size); + +#endif /* ! GRUB_CRC_H */ From b18610feb5711ec84c10438d7712e63c41d09b50 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 01:23:47 +0100 Subject: [PATCH 0422/1414] partial btrfs support. Now able to list and access files as long as all trees are flat --- grub-core/fs/btrfs.c | 852 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 839 insertions(+), 13 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index a2ee485b4..780327702 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -24,39 +24,491 @@ #include #include #include +#include #define BTRFS_SIGNATURE "_BHRfS_M" +typedef grub_uint8_t btrfs_checksum_t[0x20]; +typedef grub_uint16_t btrfs_uuid_t[8]; + +struct grub_btrfs_device +{ + grub_uint64_t device_id; + grub_uint8_t dummy[0x62 - 8]; +} __attribute__ ((packed)); + struct btrfs_superblock { - grub_uint8_t dummy1[32]; - grub_uint16_t uuid[8]; - grub_uint8_t dummy2[16]; + btrfs_checksum_t checksum; + btrfs_uuid_t uuid; + grub_uint8_t dummy[0x10]; grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1]; + grub_uint64_t generation; + grub_uint64_t root_tree; + grub_uint64_t chunk_tree; + grub_uint8_t dummy2[0x20]; + grub_uint64_t root_dir_objectid; + grub_uint8_t dummy3[0x41]; + struct grub_btrfs_device this_device; + char label[0x100]; + grub_uint8_t dummy4[0x100]; + grub_uint8_t bootstrap_mapping[0x800]; +} __attribute__ ((packed)); + +struct btrfs_header +{ + btrfs_checksum_t checksum; + btrfs_uuid_t uuid; + grub_uint8_t dummy[0x30]; + grub_uint32_t nitems; + grub_uint8_t level; } __attribute__ ((packed)); struct grub_btrfs_data { struct btrfs_superblock sblock; + unsigned int sblock_number; + grub_uint64_t tree; + grub_uint64_t inode; }; +struct grub_btrfs_key +{ + grub_uint64_t object_id; +#define GRUB_BTRFS_ITEM_TYPE_INODE_ITEM 0x01 +#define GRUB_BTRFS_ITEM_TYPE_DIR_ITEM 0x54 +#define GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM 0x6c +#define GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM 0x84 +#define GRUB_BTRFS_ITEM_TYPE_DEVICE 0xd8 +#define GRUB_BTRFS_ITEM_TYPE_CHUNK 0xe4 + grub_uint8_t type; + grub_uint64_t offset; +} __attribute__ ((packed)); + +struct grub_btrfs_chunk_item +{ + grub_uint64_t size; + grub_uint64_t dummy; + grub_uint64_t stripe_length; + grub_uint8_t dummy2[0x14]; + grub_uint16_t nstripes; + grub_uint16_t dummy3; +} __attribute__ ((packed)); + +struct grub_btrfs_chunk_stripe +{ + grub_uint64_t device_id; + grub_uint64_t offset; + btrfs_uuid_t device_uuid; +} __attribute__ ((packed)); + +struct grub_btrfs_leaf_node +{ + struct grub_btrfs_key key; + grub_uint32_t offset; + grub_uint32_t size; +} __attribute__ ((packed)); + +struct grub_btrfs_dir_item +{ + struct grub_btrfs_key key; + grub_uint8_t dummy[8]; + grub_uint16_t m; + grub_uint16_t n; + grub_uint8_t type; + char name[0]; +} __attribute__ ((packed)); + +struct grub_btrfs_leaf_descriptor +{ + unsigned depth; + unsigned allocated; + struct { + grub_disk_addr_t addr; + unsigned iter; + unsigned maxiter; + int leaf; + } *data; +}; + +struct grub_btrfs_root_item +{ + grub_uint8_t dummy[0xb0]; + grub_uint64_t tree; + grub_uint64_t inode; +}; + +struct grub_btrfs_inode +{ + grub_uint8_t dummy[0x10]; + grub_uint64_t size; +} __attribute__ ((packed)); + +struct grub_btrfs_extent_data +{ + grub_uint64_t dummy; + grub_uint64_t size; + grub_uint8_t compression; + grub_uint8_t encryption; + grub_uint16_t encoding; + grub_uint8_t type; + union + { + char inl[0]; + grub_uint64_t laddr; + }; +} __attribute__ ((packed)); + +#define GRUB_BTRFS_EXTENT_INLINE 0 +#define GRUB_BTRFS_EXTENT_REGULAR 1 + + +#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 + +static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, + 256 * 1048576 * 2, + 1048576ULL * 1048576ULL * 2 }; + +static grub_err_t +grub_btrfs_read_logical (struct grub_btrfs_data *data, + grub_disk_t disk, grub_disk_addr_t addr, + void *buf, grub_size_t size); + +static int +key_cmp (const struct grub_btrfs_key *a, const struct grub_btrfs_key *b) +{ + if (grub_cpu_to_le64 (a->object_id) < grub_cpu_to_le64 (b->object_id)) + return -1; + if (grub_cpu_to_le64 (a->object_id) > grub_cpu_to_le64 (b->object_id)) + return +1; + + if (a->type < b->type) + return -1; + if (a->type > b->type) + return +1; + + if (grub_cpu_to_le64 (a->offset) < grub_cpu_to_le64 (b->offset)) + return -1; + if (grub_cpu_to_le64 (a->offset) > grub_cpu_to_le64 (b->offset)) + return +1; + return 0; +} + +static void +free_iterator (struct grub_btrfs_leaf_descriptor *desc) +{ + grub_free (desc->data); +} + +static int +next (struct grub_btrfs_data *data, grub_disk_t disk, + struct grub_btrfs_leaf_descriptor *desc, + grub_disk_addr_t *outaddr, grub_size_t *outsize, + struct grub_btrfs_key *key_out) +{ + int i; + grub_err_t err; + struct grub_btrfs_leaf_node leaf; + + if (desc->depth == 0) + return 0; + for (i = desc->depth - 1; i >= 0; i--) + { + desc->data[i].iter++; + if (desc->data[i].iter + < desc->data[desc->depth - 1].maxiter) + break; + desc->depth--; + } + if (i == -1) + return 0; + while (!desc->data[desc->depth - 1].leaf) + { + grub_printf ("No trees\n"); + return -grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "no trees yet"); + } + err = grub_btrfs_read_logical (data, disk, + desc->data[desc->depth - 1].iter + * sizeof (leaf) + + sizeof (struct btrfs_header) + + desc->data[desc->depth - 1].addr, &leaf, + sizeof (leaf)); + if (err) + return -err; + *outsize = grub_le_to_cpu32 (leaf.size); + *outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header) + + grub_le_to_cpu32 (leaf.offset); + *key_out = leaf.key; + return 1; +} + +static grub_err_t +save_ref (struct grub_btrfs_leaf_descriptor *desc, + grub_disk_addr_t addr, unsigned i, unsigned m, int l) +{ + desc->depth++; + if (desc->allocated > desc->depth) + { + void *newdata; + desc->allocated *= 2; + newdata = grub_realloc (desc->data, sizeof (desc->data[0]) + * desc->allocated); + if (!newdata) + return grub_errno; + } + desc->data[desc->depth - 1].addr = addr; + desc->data[desc->depth - 1].iter = i; + desc->data[desc->depth - 1].maxiter = m; + desc->data[desc->depth - 1].leaf = l; + return GRUB_ERR_NONE; +} + +static grub_err_t +lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, + const struct grub_btrfs_key *key_in, + struct grub_btrfs_key *key_out, + grub_disk_addr_t root, + grub_disk_addr_t *outaddr, grub_size_t *outsize, + struct grub_btrfs_leaf_descriptor *desc) +{ + grub_disk_addr_t addr = root; + struct btrfs_header head; + grub_err_t err; + unsigned i; + struct grub_btrfs_leaf_node leaf, leaf_last; + int have_last = 0; + + if (desc) + { + desc->allocated = 16; + desc->depth = 0; + desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated); + if (!desc->data) + return grub_errno; + } + + while (1) + { + /* FIXME: preread few leafs into buffer. */ + err = grub_btrfs_read_logical (data, disk, addr, &head, sizeof (head)); + if (err) + return err; + if (head.level) + { + grub_printf ("No trees\n"); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "trees aren't implemented yet"); + } + addr += sizeof (head); + for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) + { + err = grub_btrfs_read_logical (data, disk, addr + i * sizeof (leaf), + &leaf, sizeof (leaf)); + if (err) + return err; + + grub_dprintf ("btrfs", + "%" PRIxGRUB_UINT64_T " %x %" PRIxGRUB_UINT64_T "\n", + leaf.key.object_id, leaf.key.type, leaf.key.offset); + + if (key_cmp (&leaf.key, key_in) == 0) + { + grub_memcpy (key_out, &leaf.key, sizeof(*key_out)); + *outsize = grub_le_to_cpu32 (leaf.size); + *outaddr = addr + grub_le_to_cpu32 (leaf.offset); + if (desc) + return save_ref (desc, addr - sizeof (head), i, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + + if (key_cmp (&leaf.key, key_in) > 0) + break; + + have_last = 1; + leaf_last = leaf; + } + + if (have_last) + { + grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out)); + *outsize = grub_le_to_cpu32 (leaf_last.size); + *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); + if (desc) + return save_ref (desc, addr - sizeof (head), i - 1, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + *outsize = 0; + *outaddr = 0; + grub_memset (key_out, 0, sizeof (*key_out)); + if (desc) + return save_ref (desc, addr - sizeof (head), -1, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } +} + +static grub_err_t +grub_btrfs_read_logical (struct grub_btrfs_data *data, + grub_disk_t disk, grub_disk_addr_t addr, + void *buf, grub_size_t size) +{ + while (size > 0) + { + grub_uint8_t *ptr; + struct grub_btrfs_key *key; + struct grub_btrfs_chunk_item *chunk; + struct grub_btrfs_chunk_stripe *stripe; + grub_size_t csize; + grub_err_t err; + grub_disk_addr_t paddr; + grub_uint64_t stripen; + grub_uint32_t stripe_length; + grub_uint32_t stripe_offset; + struct grub_btrfs_key key_out; + int challoc = 0; + for (ptr = data->sblock.bootstrap_mapping; + ptr < data->sblock.bootstrap_mapping + + sizeof (data->sblock.bootstrap_mapping) + - sizeof (struct grub_btrfs_key); + ) + { + key = (struct grub_btrfs_key *) ptr; + if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK) + break; + chunk = (struct grub_btrfs_chunk_item *) (key + 1); + grub_dprintf ("btrfs", "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size)); + if (grub_le_to_cpu64 (key->offset) <= addr + && addr < grub_le_to_cpu64 (key->offset) + + grub_le_to_cpu64 (chunk->size)) + goto chunk_found; + ptr += sizeof (*key) + sizeof (*chunk) + + sizeof (*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; + err = lower_bound (data, disk, + &key_in, &key_out, + grub_le_to_cpu64 (data->sblock.chunk_tree), + &chaddr, &chsize, NULL); + if (err) + return err; + key = &key_out; + if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK + || !(grub_le_to_cpu64 (key->offset) <= addr)) + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + + chunk = grub_malloc (chsize); + if (!chunk) + return grub_errno; + + challoc = 1; + err = grub_btrfs_read_logical (data, disk, chaddr, + chunk, chsize); + if (err) + { + grub_free (chunk); + return err; + } + + if (!(addr < grub_le_to_cpu64 (key->offset) + + grub_le_to_cpu64 (chunk->size))) + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + + chunk_found: + stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + NULL); + stripen = grub_divmod64 (addr - grub_le_to_cpu64 (key->offset), + stripe_length, &stripe_offset); + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + stripe += stripen; + csize = grub_le_to_cpu64 (key->offset) + grub_le_to_cpu64 (chunk->size) + - addr; + if (csize > size) + csize = size; + if (grub_le_to_cpu64 (stripe->device_id) != grub_le_to_cpu64 (data->sblock.this_device.device_id)) + { + if (challoc) + grub_free (chunk); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "multidevice isn't implemented yet"); + } + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T " (%d stripes of %" + 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), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu64 (chunk->stripe_length), + stripen, + stripe->offset); + paddr = stripe->offset + stripe_offset; + + grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T + " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, + addr); + err = grub_disk_read (disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), csize, buf); + size -= csize; + buf = (grub_uint8_t *) buf + csize; + addr += csize; + if (challoc) + grub_free (chunk); + } + return GRUB_ERR_NONE; +} + static struct grub_btrfs_data * grub_btrfs_mount (grub_disk_t disk) { struct grub_btrfs_data *data = grub_malloc (sizeof (*data)); + unsigned i; + grub_err_t err = GRUB_ERR_NONE; + if (! data) return NULL; - if (grub_disk_read (disk, 128, 0, sizeof (data->sblock), - &data->sblock) != GRUB_ERR_NONE) - goto fail; + for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) + { + struct btrfs_superblock sblock; + err = grub_disk_read (disk, superblock_sectors[i], 0, + sizeof (sblock), &sblock); + if (err == GRUB_ERR_OUT_OF_RANGE) + break; - if (grub_memcmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1)) + if (grub_memcmp ((char *) sblock.signature, BTRFS_SIGNATURE, + sizeof (BTRFS_SIGNATURE) - 1)) + break; + if (i == 0 || grub_le_to_cpu64 (sblock.generation) + > grub_le_to_cpu64 (data->sblock.generation)) + { + grub_memcpy (&data->sblock, &sblock, sizeof (sblock)); + data->sblock_number = i; + } + } + + if ((err == GRUB_ERR_OUT_OF_RANGE || !err) && i == 0) { grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); goto fail; } + if (err == GRUB_ERR_OUT_OF_RANGE) + grub_errno = err = GRUB_ERR_NONE; + + grub_dprintf ("btrfs", "using superblock %d\n", data->sblock_number); + return data; fail: @@ -65,28 +517,381 @@ grub_btrfs_mount (grub_disk_t disk) } static grub_err_t -grub_btrfs_open (struct grub_file *file __attribute__ ((unused)), - const char *name __attribute__ ((unused))) +find_path (struct grub_btrfs_data *data, + grub_disk_t disk, + const char *path, struct grub_btrfs_key *key, + grub_uint64_t *tree) { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "only detection is supported for Btrfs"); + const char *slash; + grub_err_t err; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_size_t allocated = 0; + struct grub_btrfs_dir_item *direl = NULL; + struct grub_btrfs_key key_out; + + *tree = data->sblock.root_tree; + key->object_id = data->sblock.root_dir_objectid; + + while (1) + { + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; + while (path[0] == '/') + path++; + if (!path[0]) + break; + slash = grub_strchr (path, '/'); + if (!slash) + slash = path + grub_strlen (path); + key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, path, slash - path)); + + err = lower_bound (data, disk, key, &key_out, *tree, + &elemaddr, &elemsize, NULL); + if (err) + { + grub_free (direl); + return err; + } + if (key_cmp (key, &key_out) != 0) + { + grub_free (direl); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + } + + struct grub_btrfs_dir_item *cdirel; + if (elemsize > allocated) + { + allocated = 2 * elemsize; + grub_free (direl); + direl = grub_malloc (allocated + 1); + if (!direl) + return grub_errno; + } + + err = grub_btrfs_read_logical (data, disk, elemaddr, + direl, elemsize); + if (err) + { + grub_free (direl); + return err; + } + + for (cdirel = direl; + (grub_uint8_t *) cdirel - (grub_uint8_t *) direl + < (grub_ssize_t) elemsize; + cdirel = (void *) ((grub_uint8_t *) (direl + 1) + + grub_le_to_cpu16 (cdirel->n) + + grub_le_to_cpu16 (cdirel->m))) + { + char c; + c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; + if (grub_strncmp (cdirel->name, path, slash - path) == 0) + break; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; + } + if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl + >= (grub_ssize_t) elemsize) + { + grub_free (direl); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + } + + path = slash; + + switch (cdirel->key.type) + { + case GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM: + { + struct grub_btrfs_root_item ri; + err = lower_bound (data, disk, &cdirel->key, &key_out, *tree, + &elemaddr, &elemsize, NULL); + if (err) + return err; + if (cdirel->key.object_id != key_out.object_id + || cdirel->key.type != key_out.type) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + err = grub_btrfs_read_logical (data, disk, elemaddr, + &ri, sizeof (ri)); + if (err) + return err; + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; + key->object_id = GRUB_BTRFS_OBJECT_ID_CHUNK; + *tree = grub_le_to_cpu64 (ri.tree); + break; + } + case GRUB_BTRFS_ITEM_TYPE_INODE_ITEM: + if (*slash) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + *key = cdirel->key; + break; + default: + return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", + cdirel->key.type); + } + } + + grub_free (direl); + + return GRUB_ERR_NONE; } static grub_err_t grub_btrfs_dir (grub_device_t device, const char *path __attribute__ ((unused)), int (*hook) (const char *filename, - const struct grub_dirhook_info *info) - __attribute__ ((unused))) + const struct grub_dirhook_info *info)) { struct grub_btrfs_data *data = grub_btrfs_mount (device->disk); - if (grub_errno) + struct grub_btrfs_key key_in, key_out; + grub_err_t err; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_size_t allocated = 0; + struct grub_btrfs_dir_item *direl = NULL; + struct grub_btrfs_leaf_descriptor desc; + int r; + grub_uint64_t tree; + + if (!data) return grub_errno; + err = find_path (data, device->disk, path, &key_in, &tree); + if (err) + return err; + + err = lower_bound (data, device->disk, &key_in, &key_out, + tree, + &elemaddr, &elemsize, &desc); + if (err) + return err; + if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM + || key_out.object_id != key_in.object_id) + { + r = next (data, device->disk, &desc, &elemaddr, &elemsize, &key_out); + if (r <= 0) + { + free_iterator (&desc); + return -r; + } + } + do + { + struct grub_dirhook_info info; + struct grub_btrfs_dir_item *cdirel; + if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM + || key_out.object_id != key_in.object_id) + { + r = 0; + break; + } + if (elemsize > allocated) + { + allocated = 2 * elemsize; + grub_free (direl); + direl = grub_malloc (allocated + 1); + if (!direl) + { + free_iterator (&desc); + return grub_errno; + } + } + + err = grub_btrfs_read_logical (data, device->disk, elemaddr, + direl, elemsize); + if (err) + return err; + + for (cdirel = direl; + (grub_uint8_t *) cdirel - (grub_uint8_t *) direl + < (grub_ssize_t) elemsize; + cdirel = (void *) ((grub_uint8_t *) (direl + 1) + + grub_le_to_cpu16 (cdirel->n) + + grub_le_to_cpu16 (cdirel->m))) + { + char c; + c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; + grub_memset (&info, 0, sizeof (info)); + info.dir = (cdirel->type == 2); + if (hook (cdirel->name, &info)) + goto out; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; + } + r = next (data, device->disk, &desc, &elemaddr, &elemsize, &key_out); + } + while (r > 0); + + out: + grub_free (direl); + + free_iterator (&desc); grub_free (data); + return -r; +} + +static grub_err_t +grub_btrfs_open (struct grub_file *file, const char *name) +{ + struct grub_btrfs_data *data = grub_btrfs_mount (file->device->disk); + struct grub_btrfs_key key_in, key_out; + grub_err_t err; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + struct grub_btrfs_inode inode; + + if (!data) + return grub_errno; + + err = find_path (data, file->device->disk, name, &key_in, &data->tree); + if (err) + { + grub_free (data); + return err; + } + data->inode = key_in.object_id; + key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; + + err = lower_bound (data, file->device->disk, &key_in, &key_out, + data->tree, + &elemaddr, &elemsize, NULL); + if (err) + return err; + if (data->inode != key_out.object_id + || key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_ITEM) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); + + err = grub_btrfs_read_logical (data, file->device->disk, elemaddr, + &inode, sizeof (inode)); + if (err) + return err; + + file->data = data; + file->size = grub_le_to_cpu64 (inode.size); + return GRUB_ERR_NONE; } +static grub_err_t +grub_btrfs_close (grub_file_t file) +{ + grub_free (file->data); + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_btrfs_data *data = file->data; + grub_off_t pos = file->offset; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + struct grub_btrfs_key key_in, key_out; + + while (len) + { + grub_size_t csize; + struct grub_btrfs_extent_data *extent; + grub_err_t err; + key_in.object_id = data->inode; + key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; + key_in.offset = grub_cpu_to_le64 (pos); + err = lower_bound (data, file->device->disk, &key_in, &key_out, + data->tree, + &elemaddr, &elemsize, NULL); + if (err) + return -1; + if (key_out.object_id != data->inode + || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) + { + grub_error (GRUB_ERR_BAD_FS, "extent not found"); + grub_printf ("no extent\n"); + return -1; + } + extent = grub_malloc (elemsize); + if (!extent) + return grub_errno; + + err = grub_btrfs_read_logical (data, file->device->disk, elemaddr, + extent, elemsize); + if (err) + { + grub_free (extent); + return err; + } + if (grub_le_to_cpu64 (extent->size) + grub_le_to_cpu64 (key_out.offset) + <= pos) + { + grub_free (extent); + return grub_error (GRUB_ERR_BAD_FS, "extent not found"); + } + grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" + PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (key_out.offset), + grub_le_to_cpu64 (extent->size)); + csize = grub_le_to_cpu64 (extent->size) + + grub_le_to_cpu64 (key_out.offset) - pos; + if (csize > len) + csize = len; + + if (extent->encryption) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "encryption not supported"); + return -1; + } + + if (extent->compression) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "compression not supported"); + return -1; + } + + + if (extent->encoding) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "encoding not supported"); + return -1; + } + + switch (extent->type) + { + case GRUB_BTRFS_EXTENT_INLINE: + grub_memcpy (buf, extent->inl, csize); + grub_free (extent); + break; + case GRUB_BTRFS_EXTENT_REGULAR: + if (!extent->laddr) + { + grub_memset (buf, 0, csize); + break; + } + err = grub_btrfs_read_logical (data, file->device->disk, + grub_le_to_cpu64 (extent->laddr), + buf, csize); + grub_free (extent); + if (err) + return -1; + break; + default: + grub_free (extent); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported extent type 0x%x\n", extent->type); + return -1; + } + buf += csize; + pos += csize; + len -= csize; + } + return pos - file->offset; +} + static grub_err_t grub_btrfs_uuid (grub_device_t device, char **uuid) { @@ -113,12 +918,33 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) return grub_errno; } +static grub_err_t +grub_btrfs_label (grub_device_t device, char **label) +{ + struct grub_btrfs_data *data; + + *label = NULL; + + data = grub_btrfs_mount (device->disk); + if (! data) + return grub_errno; + + *label = grub_strndup (data->sblock.label, sizeof (data->sblock.label)); + + grub_free (data); + + return grub_errno; +} + static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .dir = grub_btrfs_dir, .open = grub_btrfs_open, + .read = grub_btrfs_read, + .close = grub_btrfs_close, .uuid = grub_btrfs_uuid, + .label = grub_btrfs_label, }; GRUB_MOD_INIT(btrfs) From 355b3eed0ff8a8e90fb5f52c4e77809f6c0da922 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 16:22:51 +0100 Subject: [PATCH 0423/1414] support trees --- grub-core/fs/btrfs.c | 238 +++++++++++++++++++++++++++++-------------- 1 file changed, 161 insertions(+), 77 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 780327702..ff169e8c4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -109,6 +109,13 @@ struct grub_btrfs_leaf_node grub_uint32_t size; } __attribute__ ((packed)); +struct grub_btrfs_internal_node +{ + struct grub_btrfs_key key; + grub_uint64_t blockn; + grub_uint64_t dummy; +} __attribute__ ((packed)); + struct grub_btrfs_dir_item { struct grub_btrfs_key key; @@ -200,6 +207,28 @@ free_iterator (struct grub_btrfs_leaf_descriptor *desc) grub_free (desc->data); } +static grub_err_t +save_ref (struct grub_btrfs_leaf_descriptor *desc, + grub_disk_addr_t addr, unsigned i, unsigned m, int l) +{ + desc->depth++; + if (desc->allocated > desc->depth) + { + void *newdata; + desc->allocated *= 2; + newdata = grub_realloc (desc->data, sizeof (desc->data[0]) + * desc->allocated); + if (!newdata) + return grub_errno; + desc->data = newdata; + } + desc->data[desc->depth - 1].addr = addr; + desc->data[desc->depth - 1].iter = i; + desc->data[desc->depth - 1].maxiter = m; + desc->data[desc->depth - 1].leaf = l; + return GRUB_ERR_NONE; +} + static int next (struct grub_btrfs_data *data, grub_disk_t disk, struct grub_btrfs_leaf_descriptor *desc, @@ -224,8 +253,26 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, return 0; while (!desc->data[desc->depth - 1].leaf) { - grub_printf ("No trees\n"); - return -grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "no trees yet"); + struct grub_btrfs_internal_node node; + struct btrfs_header head; + + err = grub_btrfs_read_logical (data, disk, + desc->data[desc->depth - 1].iter + * sizeof (node) + + sizeof (struct btrfs_header) + + desc->data[desc->depth - 1].addr, &node, + sizeof (node)); + if (err) + return -err; + + err = grub_btrfs_read_logical (data, disk, + grub_le_to_cpu64 (node.blockn), &head, + sizeof (head)); + if (err) + return -err; + + save_ref (desc, grub_le_to_cpu64 (node.blockn), 0, + grub_le_to_cpu32 (head.nitems), !head.level); } err = grub_btrfs_read_logical (data, disk, desc->data[desc->depth - 1].iter @@ -242,27 +289,6 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, return 1; } -static grub_err_t -save_ref (struct grub_btrfs_leaf_descriptor *desc, - grub_disk_addr_t addr, unsigned i, unsigned m, int l) -{ - desc->depth++; - if (desc->allocated > desc->depth) - { - void *newdata; - desc->allocated *= 2; - newdata = grub_realloc (desc->data, sizeof (desc->data[0]) - * desc->allocated); - if (!newdata) - return grub_errno; - } - desc->data[desc->depth - 1].addr = addr; - desc->data[desc->depth - 1].iter = i; - desc->data[desc->depth - 1].maxiter = m; - desc->data[desc->depth - 1].leaf = l; - return GRUB_ERR_NONE; -} - static grub_err_t lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, const struct grub_btrfs_key *key_in, @@ -272,11 +298,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, struct grub_btrfs_leaf_descriptor *desc) { grub_disk_addr_t addr = root; - struct btrfs_header head; - grub_err_t err; - unsigned i; - struct grub_btrfs_leaf_node leaf, leaf_last; - int have_last = 0; + int depth = -1; if (desc) { @@ -287,65 +309,128 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, return grub_errno; } + grub_dprintf ("btrfs", + "retrieving %" PRIxGRUB_UINT64_T + " %x %" PRIxGRUB_UINT64_T "\n", + key_in->object_id, key_in->type, key_in->offset); + while (1) { - /* FIXME: preread few leafs into buffer. */ + grub_err_t err; + struct btrfs_header head; + + reiter: + depth++; + /* FIXME: preread few nodes into buffer. */ err = grub_btrfs_read_logical (data, disk, addr, &head, sizeof (head)); if (err) return err; + addr += sizeof (head); if (head.level) { - grub_printf ("No trees\n"); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "trees aren't implemented yet"); - } - addr += sizeof (head); - for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) - { - err = grub_btrfs_read_logical (data, disk, addr + i * sizeof (leaf), - &leaf, sizeof (leaf)); - if (err) - return err; - - grub_dprintf ("btrfs", - "%" PRIxGRUB_UINT64_T " %x %" PRIxGRUB_UINT64_T "\n", - leaf.key.object_id, leaf.key.type, leaf.key.offset); - - if (key_cmp (&leaf.key, key_in) == 0) + unsigned i; + struct grub_btrfs_internal_node node, node_last; + int have_last = 0; + for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) { - grub_memcpy (key_out, &leaf.key, sizeof(*key_out)); - *outsize = grub_le_to_cpu32 (leaf.size); - *outaddr = addr + grub_le_to_cpu32 (leaf.offset); - if (desc) - return save_ref (desc, addr - sizeof (head), i, - grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + err = grub_btrfs_read_logical (data, disk, addr + + i * sizeof (node), + &node, sizeof (node)); + if (err) + return err; + + grub_dprintf ("btrfs", + "internal node (depth %d) %" PRIxGRUB_UINT64_T + " %x %" PRIxGRUB_UINT64_T "\n", depth, + node.key.object_id, node.key.type, node.key.offset); + + if (key_cmp (&node.key, key_in) == 0) + { + err = GRUB_ERR_NONE; + if (desc) + err = save_ref (desc, addr - sizeof (head), i, + grub_le_to_cpu32 (head.nitems), 0); + if (err) + return err; + addr = grub_le_to_cpu64 (node.blockn); + goto reiter; + } + if (key_cmp (&node.key, key_in) > 0) + break; + node_last = node; + have_last = 1; } - - if (key_cmp (&leaf.key, key_in) > 0) - break; - - have_last = 1; - leaf_last = leaf; - } - - if (have_last) - { - grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out)); - *outsize = grub_le_to_cpu32 (leaf_last.size); - *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); + if (have_last) + { + addr = grub_le_to_cpu64 (node_last.blockn); + err = GRUB_ERR_NONE; + if (desc) + err = save_ref (desc, addr - sizeof (head), i - 1, + grub_le_to_cpu32 (head.nitems), 0); + if (err) + return err; + goto reiter; + } + *outsize = 0; + *outaddr = 0; + grub_memset (key_out, 0, sizeof (*key_out)); if (desc) - return save_ref (desc, addr - sizeof (head), i - 1, - grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + return save_ref (desc, addr - sizeof (head), -1, + grub_le_to_cpu32 (head.nitems), 0); + return GRUB_ERR_NONE; } - *outsize = 0; - *outaddr = 0; - grub_memset (key_out, 0, sizeof (*key_out)); - if (desc) - return save_ref (desc, addr - sizeof (head), -1, - grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + { + unsigned i; + struct grub_btrfs_leaf_node leaf, leaf_last; + int have_last = 0; + for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) + { + err = grub_btrfs_read_logical (data, disk, addr + i * sizeof (leaf), + &leaf, sizeof (leaf)); + if (err) + return err; + + grub_dprintf ("btrfs", + "leaf (depth %d) %" PRIxGRUB_UINT64_T + " %x %" PRIxGRUB_UINT64_T "\n", depth, + leaf.key.object_id, leaf.key.type, leaf.key.offset); + + if (key_cmp (&leaf.key, key_in) == 0) + { + grub_memcpy (key_out, &leaf.key, sizeof(*key_out)); + *outsize = grub_le_to_cpu32 (leaf.size); + *outaddr = addr + grub_le_to_cpu32 (leaf.offset); + if (desc) + return save_ref (desc, addr - sizeof (head), i, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + + if (key_cmp (&leaf.key, key_in) > 0) + break; + + have_last = 1; + leaf_last = leaf; + } + + if (have_last) + { + grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out)); + *outsize = grub_le_to_cpu32 (leaf_last.size); + *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); + if (desc) + return save_ref (desc, addr - sizeof (head), i - 1, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } + *outsize = 0; + *outaddr = 0; + grub_memset (key_out, 0, sizeof (*key_out)); + if (desc) + return save_ref (desc, addr - sizeof (head), -1, + grub_le_to_cpu32 (head.nitems), 1); + return GRUB_ERR_NONE; + } } } @@ -809,7 +894,6 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) { grub_error (GRUB_ERR_BAD_FS, "extent not found"); - grub_printf ("no extent\n"); return -1; } extent = grub_malloc (elemsize); From df80cd06fb4308717d92186d9dbe7cd59bc6cbf0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 16:36:05 +0100 Subject: [PATCH 0424/1414] Check file type --- grub-core/fs/btrfs.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ff169e8c4..58639ff5d 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -122,6 +122,9 @@ struct grub_btrfs_dir_item grub_uint8_t dummy[8]; grub_uint16_t m; grub_uint16_t n; +#define GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR 1 +#define GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY 2 +#define GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK 7 grub_uint8_t type; char name[0]; } __attribute__ ((packed)); @@ -605,7 +608,7 @@ static grub_err_t find_path (struct grub_btrfs_data *data, grub_disk_t disk, const char *path, struct grub_btrfs_key *key, - grub_uint64_t *tree) + grub_uint64_t *tree, grub_uint8_t *type) { const char *slash; grub_err_t err; @@ -615,17 +618,22 @@ find_path (struct grub_btrfs_data *data, struct grub_btrfs_dir_item *direl = NULL; struct grub_btrfs_key key_out; + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; *tree = data->sblock.root_tree; key->object_id = data->sblock.root_dir_objectid; while (1) { - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; - key->offset = 0; while (path[0] == '/') path++; if (!path[0]) break; + + if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; slash = grub_strchr (path, '/'); if (!slash) slash = path + grub_strlen (path); @@ -684,6 +692,13 @@ find_path (struct grub_btrfs_data *data, } path = slash; + *type = cdirel->type; + if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) + { + grub_free (direl); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "symlinks not supported"); + } switch (cdirel->key.type) { @@ -739,13 +754,16 @@ grub_btrfs_dir (grub_device_t device, struct grub_btrfs_leaf_descriptor desc; int r; grub_uint64_t tree; + grub_uint8_t type; if (!data) return grub_errno; - err = find_path (data, device->disk, path, &key_in, &tree); + err = find_path (data, device->disk, path, &key_in, &tree, &type); if (err) return err; + if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); err = lower_bound (data, device->disk, &key_in, &key_out, tree, @@ -800,7 +818,7 @@ grub_btrfs_dir (grub_device_t device, c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; grub_memset (&info, 0, sizeof (info)); - info.dir = (cdirel->type == 2); + info.dir = (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY); if (hook (cdirel->name, &info)) goto out; cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; @@ -827,16 +845,19 @@ grub_btrfs_open (struct grub_file *file, const char *name) grub_disk_addr_t elemaddr; grub_size_t elemsize; struct grub_btrfs_inode inode; + grub_uint8_t type; if (!data) return grub_errno; - err = find_path (data, file->device->disk, name, &key_in, &data->tree); + err = find_path (data, file->device->disk, name, &key_in, &data->tree, &type); if (err) { grub_free (data); return err; } + if (type != GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); data->inode = key_in.object_id; key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; From d980826df2d5214eb3ee9092739b0766d7d822b7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 16:45:12 +0100 Subject: [PATCH 0425/1414] Remove \n from error message --- grub-core/fs/btrfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 58639ff5d..65d298e74 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -987,7 +987,7 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) default: grub_free (extent); grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported extent type 0x%x\n", extent->type); + "unsupported extent type 0x%x", extent->type); return -1; } buf += csize; From bf78d5b2512b462519c546cc9a7afa6804fb3b19 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 1 Dec 2010 22:42:11 +0100 Subject: [PATCH 0426/1414] 2010-12-01 Robert Millan * grub-core/fs/zfs/zfs.c: New file. * grub-core/fs/zfs/zfs_fletcher.c: Likewise. * grub-core/fs/zfs/zfs_lzjb.c: Likewise. * grub-core/fs/zfs/zfs_sha256.c: Likewise. * grub-core/fs/zfs/zfsinfo.c: Likewise. * include/grub/zfs/dmu.h: Likewise. * include/grub/zfs/dmu_objset.h: Likewise. * include/grub/zfs/dnode.h: Likewise. * include/grub/zfs/dsl_dataset.h: Likewise. * include/grub/zfs/dsl_dir.h: Likewise. * include/grub/zfs/sa_impl.h: Likewise. * include/grub/zfs/spa.h: Likewise. * include/grub/zfs/uberblock_impl.h: Likewise. * include/grub/zfs/vdev_impl.h: Likewise. * include/grub/zfs/zap_impl.h: Likewise. * include/grub/zfs/zap_leaf.h: Likewise. * include/grub/zfs/zfs.h: Likewise. * include/grub/zfs/zfs_acl.h: Likewise. * include/grub/zfs/zfs_znode.h: Likewise. * include/grub/zfs/zil.h: Likewise. * include/grub/zfs/zio.h: Likewise. * include/grub/zfs/zio_checksum.h: Likewise. * Makefile.util.def: Build ZFS into libgrubmods. * grub-core/Makefile.core.def: Build zfs.mod. --- ChangeLog | 29 + Makefile.util.def | 4 + grub-core/Makefile.core.def | 13 + grub-core/fs/zfs/zfs.c | 2546 +++++++++++++++++++++++++++++ grub-core/fs/zfs/zfs_fletcher.c | 86 + grub-core/fs/zfs/zfs_lzjb.c | 95 ++ grub-core/fs/zfs/zfs_sha256.c | 145 ++ grub-core/fs/zfs/zfsinfo.c | 414 +++++ include/grub/zfs/dmu.h | 120 ++ include/grub/zfs/dmu_objset.h | 44 + include/grub/zfs/dnode.h | 81 + include/grub/zfs/dsl_dataset.h | 53 + include/grub/zfs/dsl_dir.h | 49 + include/grub/zfs/sa_impl.h | 35 + include/grub/zfs/spa.h | 312 ++++ include/grub/zfs/uberblock_impl.h | 61 + include/grub/zfs/vdev_impl.h | 70 + include/grub/zfs/zap_impl.h | 112 ++ include/grub/zfs/zap_leaf.h | 104 ++ include/grub/zfs/zfs.h | 125 ++ include/grub/zfs/zfs_acl.h | 60 + include/grub/zfs/zfs_znode.h | 71 + include/grub/zfs/zil.h | 57 + include/grub/zfs/zio.h | 85 + include/grub/zfs/zio_checksum.h | 50 + 25 files changed, 4821 insertions(+) create mode 100644 grub-core/fs/zfs/zfs.c create mode 100644 grub-core/fs/zfs/zfs_fletcher.c create mode 100644 grub-core/fs/zfs/zfs_lzjb.c create mode 100644 grub-core/fs/zfs/zfs_sha256.c create mode 100644 grub-core/fs/zfs/zfsinfo.c create mode 100644 include/grub/zfs/dmu.h create mode 100644 include/grub/zfs/dmu_objset.h create mode 100644 include/grub/zfs/dnode.h create mode 100644 include/grub/zfs/dsl_dataset.h create mode 100644 include/grub/zfs/dsl_dir.h create mode 100644 include/grub/zfs/sa_impl.h create mode 100644 include/grub/zfs/spa.h create mode 100644 include/grub/zfs/uberblock_impl.h create mode 100644 include/grub/zfs/vdev_impl.h create mode 100644 include/grub/zfs/zap_impl.h create mode 100644 include/grub/zfs/zap_leaf.h create mode 100644 include/grub/zfs/zfs.h create mode 100644 include/grub/zfs/zfs_acl.h create mode 100644 include/grub/zfs/zfs_znode.h create mode 100644 include/grub/zfs/zil.h create mode 100644 include/grub/zfs/zio.h create mode 100644 include/grub/zfs/zio_checksum.h diff --git a/ChangeLog b/ChangeLog index 4effc2ff4..e35f9876d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-12-01 Robert Millan + + * grub-core/fs/zfs/zfs.c: New file. + * grub-core/fs/zfs/zfs_fletcher.c: Likewise. + * grub-core/fs/zfs/zfs_lzjb.c: Likewise. + * grub-core/fs/zfs/zfs_sha256.c: Likewise. + * grub-core/fs/zfs/zfsinfo.c: Likewise. + + * include/grub/zfs/dmu.h: Likewise. + * include/grub/zfs/dmu_objset.h: Likewise. + * include/grub/zfs/dnode.h: Likewise. + * include/grub/zfs/dsl_dataset.h: Likewise. + * include/grub/zfs/dsl_dir.h: Likewise. + * include/grub/zfs/sa_impl.h: Likewise. + * include/grub/zfs/spa.h: Likewise. + * include/grub/zfs/uberblock_impl.h: Likewise. + * include/grub/zfs/vdev_impl.h: Likewise. + * include/grub/zfs/zap_impl.h: Likewise. + * include/grub/zfs/zap_leaf.h: Likewise. + * include/grub/zfs/zfs.h: Likewise. + * include/grub/zfs/zfs_acl.h: Likewise. + * include/grub/zfs/zfs_znode.h: Likewise. + * include/grub/zfs/zil.h: Likewise. + * include/grub/zfs/zio.h: Likewise. + * include/grub/zfs/zio_checksum.h: Likewise. + + * Makefile.util.def: Build ZFS into libgrubmods. + * grub-core/Makefile.core.def: Build zfs.mod. + 2010-11-30 Szymon Janc * grub-core/commands/regexp.c (grub_cmd_regexp): Remove unused diff --git a/Makefile.util.def b/Makefile.util.def index 3e8ae16f5..74984e2e9 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -70,6 +70,10 @@ library = { common = grub-core/fs/ufs2.c; common = grub-core/fs/ufs.c; common = grub-core/fs/xfs.c; + common = grub-core/fs/zfs/zfs.c; + common = grub-core/fs/zfs/zfs_lzjb.c; + common = grub-core/fs/zfs/zfs_sha256.c; + common = grub-core/fs/zfs/zfs_fletcher.c; common = grub-core/lib/arg.c; common = grub-core/lib/crypto.c; common = grub-core/lib/envblk.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ce10ba372..37c0ce970 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1007,6 +1007,19 @@ module = { common = fs/xfs.c; }; +module = { + name = zfs; + common = fs/zfs/zfs.c; + common = fs/zfs/zfs_lzjb.c; + common = fs/zfs/zfs_sha256.c; + common = fs/zfs/zfs_fletcher.c; +}; + +module = { + name = zfsinfo; + common = fs/zfs/zfsinfo.c; +}; + module = { name = pxe; i386_pc = fs/i386/pc/pxe.c; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c new file mode 100644 index 000000000..ce735a311 --- /dev/null +++ b/grub-core/fs/zfs/zfs.c @@ -0,0 +1,2546 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright 2010 Sun Microsystems, Inc. + * Copyright (C) 2009 Vladimir Serbinenko + * Copyright (C) 2010 Robert Millan + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * The zfs plug-in routines for GRUB are: + * + * zfs_mount() - locates a valid uberblock of the root pool and reads + * in its MOS at the memory address MOS. + * + * zfs_open() - locates a plain file object by following the MOS + * and places its dnode at the memory address DNODE. + * + * zfs_read() - read in the data blocks pointed by the DNODE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ZPOOL_PROP_BOOTFS "bootfs" + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/* + * For nvlist manipulation. (from nvpair.h) + */ +#define NV_ENCODE_NATIVE 0 +#define NV_ENCODE_XDR 1 +#define NV_BIG_ENDIAN 0 +#define NV_LITTLE_ENDIAN 1 +#define DATA_TYPE_UINT64 8 +#define DATA_TYPE_STRING 9 +#define DATA_TYPE_NVLIST 19 +#define DATA_TYPE_NVLIST_ARRAY 20 + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +#define P2PHASE(x, align) ((x) & ((align) - 1)) +#define DVA_OFFSET_TO_PHYS_SECTOR(offset) \ + ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT) + +/* + * FAT ZAP data structures + */ +#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */ +#define ZAP_HASH_IDX(hash, n) (((n) == 0) ? 0 : ((hash) >> (64 - (n)))) +#define CHAIN_END 0xffff /* end of the chunk chain */ + +/* + * The amount of space within the chunk available for the array is: + * chunk size - space for type (1) - space for next pointer (2) + */ +#define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) + +#define ZAP_LEAF_HASH_SHIFT(bs) (bs - 5) +#define ZAP_LEAF_HASH_NUMENTRIES(bs) (1 << ZAP_LEAF_HASH_SHIFT(bs)) +#define LEAF_HASH(bs, h) \ + ((ZAP_LEAF_HASH_NUMENTRIES(bs)-1) & \ + ((h) >> (64 - ZAP_LEAF_HASH_SHIFT(bs)-l->l_hdr.lh_prefix_len))) + +/* + * The amount of space available for chunks is: + * block size shift - hash entry size (2) * number of hash + * entries - header space (2*chunksize) + */ +#define ZAP_LEAF_NUMCHUNKS(bs) \ + (((1<l_hash + ZAP_LEAF_HASH_NUMENTRIES(bs)))[idx] +#define ZAP_LEAF_ENTRY(l, bs, idx) (&ZAP_LEAF_CHUNK(l, bs, idx).l_entry) + + +/* + * Decompression Entry - lzjb + */ +#ifndef NBBY +#define NBBY 8 +#endif + +extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); + +typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, + grub_size_t s_len, grub_size_t d_len); +typedef struct decomp_entry +{ + char *name; + zfs_decomp_func_t *decomp_func; +} decomp_entry_t; + +typedef struct dnode_end +{ + dnode_phys_t dn; + grub_zfs_endian_t endian; +} dnode_end_t; + +struct grub_zfs_data +{ + /* cache for a file block of the currently zfs_open()-ed file */ + char *file_buf; + grub_uint64_t file_start; + grub_uint64_t file_end; + + /* cache for a dnode block */ + dnode_phys_t *dnode_buf; + dnode_phys_t *dnode_mdn; + grub_uint64_t dnode_start; + grub_uint64_t dnode_end; + grub_zfs_endian_t dnode_endian; + + uberblock_t current_uberblock; + grub_disk_t disk; + + dnode_end_t mos; + dnode_end_t mdn; + dnode_end_t dnode; + + grub_disk_addr_t vdev_phys_sector; +}; + +decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { + {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ + {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ + {"off", NULL}, /* ZIO_COMPRESS_OFF */ + {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */ + {"empty", NULL}, /* ZIO_COMPRESS_EMPTY */ + {"gzip", NULL}, /* ZIO_COMPRESS_GZIP */ +}; + +static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, + void *buf, struct grub_zfs_data *data); + +/* + * Our own version of log2(). Same thing as highbit()-1. + */ +static int +zfs_log2 (grub_uint64_t num) +{ + int i = 0; + + while (num > 1) + { + i++; + num = num >> 1; + } + + return (i); +} + +/* Checksum Functions */ +static void +zio_checksum_off (const void *buf __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_zfs_endian_t endian __attribute__ ((unused)), + zio_cksum_t * zcp) +{ + ZIO_SET_CHECKSUM (zcp, 0, 0, 0, 0); +} + +/* Checksum Table and Values */ +zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { + {NULL, 0, 0, "inherit"}, + {NULL, 0, 0, "on"}, + {zio_checksum_off, 0, 0, "off"}, + {zio_checksum_SHA256, 1, 1, "label"}, + {zio_checksum_SHA256, 1, 1, "gang_header"}, + {NULL, 0, 0, "zilog"}, + {fletcher_2, 0, 0, "fletcher2"}, + {fletcher_4, 1, 0, "fletcher4"}, + {zio_checksum_SHA256, 1, 0, "SHA256"}, + {NULL, 0, 0, "zilog2"}, +}; + +/* + * zio_checksum_verify: Provides support for checksum verification. + * + * Fletcher2, Fletcher4, and SHA256 are supported. + * + */ +static grub_err_t +zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, + grub_zfs_endian_t endian, char *buf, int size) +{ + zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; + zio_checksum_info_t *ci = &zio_checksum_table[checksum]; + zio_cksum_t actual_cksum, expected_cksum; + + if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func == NULL) + { + grub_dprintf ("zfs", "unknown checksum function %d\n", checksum); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unknown checksum function %d", checksum); + } + + if (ci->ci_eck) + { + expected_cksum = zec->zec_cksum; + zec->zec_cksum = zc; + ci->ci_func (buf, size, endian, &actual_cksum); + zec->zec_cksum = expected_cksum; + zc = expected_cksum; + } + else + ci->ci_func (buf, size, endian, &actual_cksum); + + if ((actual_cksum.zc_word[0] != zc.zc_word[0]) + || (actual_cksum.zc_word[1] != zc.zc_word[1]) + || (actual_cksum.zc_word[2] != zc.zc_word[2]) + || (actual_cksum.zc_word[3] != zc.zc_word[3])) + { + grub_dprintf ("zfs", "checksum %d verification failed\n", checksum); + grub_dprintf ("zfs", "actual checksum %16llx %16llx %16llx %16llx\n", + (unsigned long long) actual_cksum.zc_word[0], + (unsigned long long) actual_cksum.zc_word[1], + (unsigned long long) actual_cksum.zc_word[2], + (unsigned long long) actual_cksum.zc_word[3]); + grub_dprintf ("zfs", "expected checksum %16llx %16llx %16llx %16llx\n", + (unsigned long long) zc.zc_word[0], + (unsigned long long) zc.zc_word[1], + (unsigned long long) zc.zc_word[2], + (unsigned long long) zc.zc_word[3]); + return grub_error (GRUB_ERR_BAD_FS, "checksum verification failed"); + } + + return GRUB_ERR_NONE; +} + +/* + * vdev_uberblock_compare takes two uberblock structures and returns an integer + * indicating the more recent of the two. + * Return Value = 1 if ub2 is more recent + * Return Value = -1 if ub1 is more recent + * The most recent uberblock is determined using its transaction number and + * timestamp. The uberblock with the highest transaction number is + * considered "newer". If the transaction numbers of the two blocks match, the + * timestamps are compared to determine the "newer" of the two. + */ +static int +vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) +{ + grub_zfs_endian_t ub1_endian, ub2_endian; + if (grub_zfs_to_cpu64 (ub1->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) + ub1_endian = LITTLE_ENDIAN; + else + ub1_endian = BIG_ENDIAN; + if (grub_zfs_to_cpu64 (ub2->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) + ub2_endian = LITTLE_ENDIAN; + else + ub2_endian = BIG_ENDIAN; + + if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) + < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) + return (-1); + if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) + > grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) + return (1); + + if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) + < grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) + return (-1); + if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) + > grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) + return (1); + + return (0); +} + +/* + * Three pieces of information are needed to verify an uberblock: the magic + * number, the version number, and the checksum. + * + * Currently Implemented: version number, magic number + * Need to Implement: checksum + * + */ +static grub_err_t +uberblock_verify (uberblock_phys_t * ub, int offset) +{ + uberblock_t *uber = &ub->ubp_uberblock; + grub_err_t err; + grub_zfs_endian_t endian = UNKNOWN_ENDIAN; + zio_cksum_t zc; + + if (grub_zfs_to_cpu64 (uber->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC + && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) > 0 + && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) <= SPA_VERSION) + endian = LITTLE_ENDIAN; + + if (grub_zfs_to_cpu64 (uber->ub_magic, BIG_ENDIAN) == UBERBLOCK_MAGIC + && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) > 0 + && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) <= SPA_VERSION) + endian = BIG_ENDIAN; + + if (endian == UNKNOWN_ENDIAN) + return grub_error (GRUB_ERR_BAD_FS, "invalid uberblock magic"); + + grub_memset (&zc, 0, sizeof (zc)); + + zc.zc_word[0] = grub_cpu_to_zfs64 (offset, endian); + err = zio_checksum_verify (zc, ZIO_CHECKSUM_LABEL, endian, + (char *) ub, UBERBLOCK_SIZE); + + return err; +} + +/* + * Find the best uberblock. + * Return: + * Success - Pointer to the best uberblock. + * Failure - NULL + */ +static uberblock_phys_t * +find_bestub (uberblock_phys_t * ub_array, grub_disk_addr_t sector) +{ + uberblock_phys_t *ubbest = NULL; + int i; + grub_disk_addr_t offset; + grub_err_t err = GRUB_ERR_NONE; + + for (i = 0; i < (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT); i++) + { + offset = (sector << SPA_MINBLOCKSHIFT) + VDEV_PHYS_SIZE + + (i << VDEV_UBERBLOCK_SHIFT); + + err = uberblock_verify (&ub_array[i], offset); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (ubbest == NULL + || vdev_uberblock_compare (&(ub_array[i].ubp_uberblock), + &(ubbest->ubp_uberblock)) > 0) + ubbest = &ub_array[i]; + } + if (!ubbest) + grub_errno = err; + + return (ubbest); +} + +static inline grub_size_t +get_psize (blkptr_t * bp, grub_zfs_endian_t endian) +{ + return ((((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) >> 16) & 0xffff) + 1) + << SPA_MINBLOCKSHIFT); +} + +static grub_uint64_t +dva_get_offset (dva_t * dva, grub_zfs_endian_t endian) +{ + grub_dprintf ("zfs", "dva=%llx, %llx\n", + (unsigned long long) dva->dva_word[0], + (unsigned long long) dva->dva_word[1]); + return grub_zfs_to_cpu64 ((dva)->dva_word[1], + endian) << SPA_MINBLOCKSHIFT; +} + + +/* + * Read a block of data based on the gang block address dva, + * and put its data in buf. + * + */ +static grub_err_t +zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, + struct grub_zfs_data *data) +{ + zio_gbh_phys_t *zio_gb; + grub_uint64_t offset, sector; + unsigned i; + grub_err_t err; + zio_cksum_t zc; + + grub_memset (&zc, 0, sizeof (zc)); + + zio_gb = grub_malloc (SPA_GANGBLOCKSIZE); + if (!zio_gb) + return grub_errno; + grub_dprintf ("zfs", endian == LITTLE_ENDIAN ? "little-endian gang\n" + :"big-endian gang\n"); + offset = dva_get_offset (dva, endian); + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); + grub_dprintf ("zfs", "offset=%llx\n", (unsigned long long) offset); + + /* read in the gang block header */ + err = grub_disk_read (data->disk, sector, 0, SPA_GANGBLOCKSIZE, + (char *) zio_gb); + if (err) + { + grub_free (zio_gb); + return err; + } + + /* XXX */ + /* self checksuming the gang block header */ + ZIO_SET_CHECKSUM (&zc, DVA_GET_VDEV (dva), + dva_get_offset (dva, endian), bp->blk_birth, 0); + err = zio_checksum_verify (zc, ZIO_CHECKSUM_GANG_HEADER, endian, + (char *) zio_gb, SPA_GANGBLOCKSIZE); + if (err) + { + grub_free (zio_gb); + return err; + } + + endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; + + for (i = 0; i < SPA_GBH_NBLKPTRS; i++) + { + if (zio_gb->zg_blkptr[i].blk_birth == 0) + continue; + + err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data); + if (err) + { + grub_free (zio_gb); + return err; + } + buf = (char *) buf + get_psize (&zio_gb->zg_blkptr[i], endian); + } + grub_free (zio_gb); + return GRUB_ERR_NONE; +} + +/* + * Read in a block of raw data to buf. + */ +static grub_err_t +zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, + struct grub_zfs_data *data) +{ + int i, psize; + grub_err_t err = GRUB_ERR_NONE; + + psize = get_psize (bp, endian); + + /* pick a good dva from the block pointer */ + for (i = 0; i < SPA_DVAS_PER_BP; i++) + { + grub_uint64_t offset, sector; + + if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0) + continue; + + if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1) + err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data); + else + { + /* read in a data block */ + offset = dva_get_offset (&bp->blk_dva[i], endian); + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); + err = grub_disk_read (data->disk, sector, 0, psize, buf); + } + if (!err) + return GRUB_ERR_NONE; + grub_errno = GRUB_ERR_NONE; + } + + if (!err) + err = grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid DVA"); + grub_errno = err; + + return err; +} + +/* + * Read in a block of data, verify its checksum, decompress if needed, + * and put the uncompressed data in buf. + */ +static grub_err_t +zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, + grub_size_t *size, struct grub_zfs_data *data) +{ + grub_size_t lsize, psize; + unsigned int comp; + char *compbuf = NULL; + grub_err_t err; + zio_cksum_t zc = bp->blk_cksum; + grub_uint32_t checksum; + + *buf = NULL; + + checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; + comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7; + lsize = (BP_IS_HOLE(bp) ? 0 : + (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) + << SPA_MINBLOCKSHIFT)); + psize = get_psize (bp, endian); + + if (size) + *size = lsize; + + if (comp >= ZIO_COMPRESS_FUNCTIONS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "compression algorithm %u not supported\n", (unsigned int) comp); + + if (comp != ZIO_COMPRESS_OFF && decomp_table[comp].decomp_func == NULL) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "compression algorithm %s not supported\n", decomp_table[comp].name); + + if (comp != ZIO_COMPRESS_OFF) + { + compbuf = grub_malloc (psize); + if (! compbuf) + return grub_errno; + } + else + compbuf = *buf = grub_malloc (lsize); + + grub_dprintf ("zfs", "endian = %d\n", endian); + err = zio_read_data (bp, endian, compbuf, data); + if (err) + { + grub_free (compbuf); + *buf = NULL; + return err; + } + + err = zio_checksum_verify (zc, checksum, endian, compbuf, psize); + if (err) + { + grub_dprintf ("zfs", "incorrect checksum\n"); + grub_free (compbuf); + *buf = NULL; + return err; + } + + if (comp != ZIO_COMPRESS_OFF) + { + *buf = grub_malloc (lsize); + if (!*buf) + { + grub_free (compbuf); + return grub_errno; + } + + err = decomp_table[comp].decomp_func (compbuf, *buf, psize, lsize); + grub_free (compbuf); + if (err) + { + grub_free (*buf); + *buf = NULL; + return err; + } + } + + return GRUB_ERR_NONE; +} + +/* + * Get the block from a block id. + * push the block onto the stack. + * + */ +static grub_err_t +dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, + grub_zfs_endian_t *endian_out, struct grub_zfs_data *data) +{ + int idx, level; + blkptr_t *bp_array = dn->dn.dn_blkptr; + int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT; + blkptr_t *bp, *tmpbuf = 0; + grub_zfs_endian_t endian; + grub_err_t err = GRUB_ERR_NONE; + + bp = grub_malloc (sizeof (blkptr_t)); + if (!bp) + return grub_errno; + + endian = dn->endian; + for (level = dn->dn.dn_nlevels - 1; level >= 0; level--) + { + grub_dprintf ("zfs", "endian = %d\n", endian); + idx = (blkid >> (epbs * level)) & ((1 << epbs) - 1); + *bp = bp_array[idx]; + if (bp_array != dn->dn.dn_blkptr) + { + grub_free (bp_array); + bp_array = 0; + } + + if (BP_IS_HOLE (bp)) + { + grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec, + dn->endian) + << SPA_MINBLOCKSHIFT; + *buf = grub_malloc (size); + if (*buf) + { + err = grub_errno; + break; + } + grub_memset (*buf, 0, size); + endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; + break; + } + if (level == 0) + { + grub_dprintf ("zfs", "endian = %d\n", endian); + err = zio_read (bp, endian, buf, 0, data); + endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; + break; + } + grub_dprintf ("zfs", "endian = %d\n", endian); + err = zio_read (bp, endian, (void **) &tmpbuf, 0, data); + endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; + if (err) + break; + bp_array = tmpbuf; + } + if (bp_array != dn->dn.dn_blkptr) + grub_free (bp_array); + if (endian_out) + *endian_out = endian; + + grub_free (bp); + return err; +} + +/* + * mzap_lookup: Looks up property described by "name" and returns the value + * in "value". + */ +static grub_err_t +mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, + int objsize, char *name, grub_uint64_t * value) +{ + int i, chunks; + mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; + + chunks = objsize / MZAP_ENT_LEN - 1; + for (i = 0; i < chunks; i++) + { + if (grub_strcmp (mzap_ent[i].mze_name, name) == 0) + { + *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian); + return GRUB_ERR_NONE; + } + } + + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't find %s", name); +} + +static int +mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, + int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_uint64_t val)) +{ + int i, chunks; + mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; + + chunks = objsize / MZAP_ENT_LEN - 1; + for (i = 0; i < chunks; i++) + { + grub_dprintf ("zfs", "zap: name = %s, value = %llx, cd = %x\n", + mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value, + (int)mzap_ent[i].mze_cd); + if (hook (mzap_ent[i].mze_name, + grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian))) + return 1; + } + + return 0; +} + +static grub_uint64_t +zap_hash (grub_uint64_t salt, const char *name) +{ + static grub_uint64_t table[256]; + const grub_uint8_t *cp; + grub_uint8_t c; + grub_uint64_t crc = salt; + + if (table[128] == 0) + { + grub_uint64_t *ct; + int i, j; + for (i = 0; i < 256; i++) + { + for (ct = table + i, *ct = i, j = 8; j > 0; j--) + *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY); + } + } + + for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) + crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; + + /* + * Only use 28 bits, since we need 4 bits in the cookie for the + * collision differentiator. We MUST use the high bits, since + * those are the onces that we first pay attention to when + * chosing the bucket. + */ + crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1); + + return (crc); +} + +/* + * Only to be used on 8-bit arrays. + * array_len is actual len in bytes (not encoded le_value_length). + * buf is null-terminated. + */ +/* XXX */ +static int +zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, + int blksft, int chunk, int array_len, const char *buf) +{ + int bseen = 0; + + while (bseen < array_len) + { + struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array; + int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES); + + if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) + return (0); + + if (grub_memcmp (la->la_array, buf + bseen, toread) != 0) + break; + chunk = grub_zfs_to_cpu16 (la->la_next, endian); + bseen += toread; + } + return (bseen == array_len); +} + +/* XXX */ +static grub_err_t +zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, + int chunk, int array_len, char *buf) +{ + int bseen = 0; + + while (bseen < array_len) + { + struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk).l_array; + int toread = MIN (array_len - bseen, ZAP_LEAF_ARRAY_BYTES); + + if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) + /* Don't use grub_error because this error is to be ignored. */ + return GRUB_ERR_BAD_FS; + + grub_memcpy (buf + bseen,la->la_array, toread); + chunk = grub_zfs_to_cpu16 (la->la_next, endian); + bseen += toread; + } + return GRUB_ERR_NONE; +} + + +/* + * Given a zap_leaf_phys_t, walk thru the zap leaf chunks to get the + * value for the property "name". + * + */ +/* XXX */ +static grub_err_t +zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, + int blksft, grub_uint64_t h, + const char *name, grub_uint64_t * value) +{ + grub_uint16_t chunk; + struct zap_leaf_entry *le; + + /* Verify if this is a valid leaf block */ + if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF) + return grub_error (GRUB_ERR_BAD_FS, "invalid leaf type"); + if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) + return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic"); + + for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h)], endian); + chunk != CHAIN_END; chunk = le->le_next) + { + + if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) + return grub_error (GRUB_ERR_BAD_FS, "invalid chunk number"); + + le = ZAP_LEAF_ENTRY (l, blksft, chunk); + + /* Verify the chunk entry */ + if (le->le_type != ZAP_CHUNK_ENTRY) + return grub_error (GRUB_ERR_BAD_FS, "invalid chunk entry"); + + if (grub_zfs_to_cpu64 (le->le_hash,endian) != h) + continue; + + grub_dprintf ("zfs", "fzap: length %d\n", (int) le->le_name_length); + + if (zap_leaf_array_equal (l, endian, blksft, + grub_zfs_to_cpu16 (le->le_name_chunk,endian), + grub_zfs_to_cpu16 (le->le_name_length, endian), + name)) + { + struct zap_leaf_array *la; + grub_uint8_t *ip; + + if (le->le_int_size != 8 || le->le_value_length != 1) + return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); + + /* get the uint64_t property value */ + la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; + ip = la->la_array; + + *value = grub_be_to_cpu64 (la->la_array64); + + return GRUB_ERR_NONE; + } + } + + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't find %s", name); +} + + +/* Verify if this is a fat zap header block */ +static grub_err_t +zap_verify (zap_phys_t *zap) +{ + if (zap->zap_magic != (grub_uint64_t) ZAP_MAGIC) + return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); + + if (zap->zap_flags != 0) + return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags"); + + if (zap->zap_salt == 0) + return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); + + return GRUB_ERR_NONE; +} + +/* + * Fat ZAP lookup + * + */ +/* XXX */ +static grub_err_t +fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, + char *name, grub_uint64_t * value, struct grub_zfs_data *data) +{ + zap_leaf_phys_t *l; + grub_uint64_t hash, idx, blkid; + int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, + zap_dnode->endian) << DNODE_SHIFT); + grub_err_t err; + grub_zfs_endian_t leafendian; + + err = zap_verify (zap); + if (err) + return err; + + hash = zap_hash (zap->zap_salt, name); + + /* get block id from index */ + if (zap->zap_ptrtbl.zt_numblks != 0) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "external pointer tables not supported"); + idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift); + blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + + /* Get the leaf block */ + if ((1U << blksft) < sizeof (zap_leaf_phys_t)) + return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); + err = dmu_read (zap_dnode, blkid, (void **) &l, &leafendian, data); + if (err) + return err; + + err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value); + grub_free (l); + return err; +} + +/* XXX */ +static int +fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, + int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_uint64_t val), + struct grub_zfs_data *data) +{ + zap_leaf_phys_t *l; + grub_uint64_t idx, blkid; + grub_uint16_t chunk; + int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, + zap_dnode->endian) << DNODE_SHIFT); + grub_err_t err; + grub_zfs_endian_t endian; + + if (zap_verify (zap)) + return 0; + + /* get block id from index */ + if (zap->zap_ptrtbl.zt_numblks != 0) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "external pointer tables not supported"); + return 0; + } + /* Get the leaf block */ + if ((1U << blksft) < sizeof (zap_leaf_phys_t)) + { + grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); + return 0; + } + for (idx = 0; idx < zap->zap_ptrtbl.zt_numblks; idx++) + { + blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + + err = dmu_read (zap_dnode, blkid, (void **) &l, &endian, data); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + + /* Verify if this is a valid leaf block */ + if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF) + { + grub_free (l); + continue; + } + if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) + { + grub_free (l); + continue; + } + + for (chunk = 0; chunk < ZAP_LEAF_NUMCHUNKS (blksft); chunk++) + { + char *buf; + struct zap_leaf_array *la; + struct zap_leaf_entry *le; + grub_uint64_t val; + le = ZAP_LEAF_ENTRY (l, blksft, chunk); + + /* Verify the chunk entry */ + if (le->le_type != ZAP_CHUNK_ENTRY) + continue; + + buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) + + 1); + if (zap_leaf_array_get (l, endian, blksft, le->le_name_chunk, + le->le_name_length, buf)) + { + grub_free (buf); + continue; + } + buf[le->le_name_length] = 0; + + if (le->le_int_size != 8 + || grub_zfs_to_cpu16 (le->le_value_length, endian) != 1) + continue; + + /* get the uint64_t property value */ + la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; + val = grub_be_to_cpu64 (la->la_array64); + if (hook (buf, val)) + return 1; + grub_free (buf); + } + } + return 0; +} + + +/* + * Read in the data of a zap object and find the value for a matching + * property name. + * + */ +static grub_err_t +zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, + struct grub_zfs_data *data) +{ + grub_uint64_t block_type; + int size; + void *zapbuf; + grub_err_t err; + grub_zfs_endian_t endian; + + grub_dprintf ("zfs", "looking for '%s'\n", name); + + /* Read in the first block of the zap object data. */ + size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, + zap_dnode->endian) << SPA_MINBLOCKSHIFT; + err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); + if (err) + return err; + block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); + + grub_dprintf ("zfs", "zap read\n"); + + if (block_type == ZBT_MICRO) + { + grub_dprintf ("zfs", "micro zap\n"); + err = (mzap_lookup (zapbuf, endian, size, name, val)); + grub_dprintf ("zfs", "returned %d\n", err); + grub_free (zapbuf); + return err; + } + else if (block_type == ZBT_HEADER) + { + grub_dprintf ("zfs", "fat zap\n"); + /* this is a fat zap */ + err = (fzap_lookup (zap_dnode, zapbuf, name, val, data)); + grub_dprintf ("zfs", "returned %d\n", err); + grub_free (zapbuf); + return err; + } + + return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); +} + +static int +zap_iterate (dnode_end_t * zap_dnode, + int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t val), + struct grub_zfs_data *data) +{ + grub_uint64_t block_type; + int size; + void *zapbuf; + grub_err_t err; + int ret; + grub_zfs_endian_t endian; + + /* Read in the first block of the zap object data. */ + size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; + err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); + if (err) + return 0; + block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); + + grub_dprintf ("zfs", "zap read\n"); + + if (block_type == ZBT_MICRO) + { + grub_dprintf ("zfs", "micro zap\n"); + ret = mzap_iterate (zapbuf, endian, size, hook); + grub_free (zapbuf); + return ret; + } + else if (block_type == ZBT_HEADER) + { + grub_dprintf ("zfs", "fat zap\n"); + /* this is a fat zap */ + ret = fzap_iterate (zap_dnode, zapbuf, hook, data); + grub_free (zapbuf); + return ret; + } + grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + return 0; +} + + +/* + * Get the dnode of an object number from the metadnode of an object set. + * + * Input + * mdn - metadnode to get the object dnode + * objnum - object number for the object dnode + * buf - data buffer that holds the returning dnode + */ +static grub_err_t +dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, + dnode_end_t * buf, struct grub_zfs_data *data) +{ + grub_uint64_t blkid, blksz; /* the block id this object dnode is in */ + int epbs; /* shift of number of dnodes in a block */ + int idx; /* index within a block */ + dnode_phys_t *dnbuf; + grub_err_t err; + grub_zfs_endian_t endian; + + blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, + mdn->endian) << SPA_MINBLOCKSHIFT; + epbs = zfs_log2 (blksz) - DNODE_SHIFT; + blkid = objnum >> epbs; + idx = objnum & ((1 << epbs) - 1); + + if (data->dnode_buf != NULL && grub_memcmp (data->dnode_mdn, mdn, + sizeof (*mdn)) == 0 + && objnum >= data->dnode_start && objnum < data->dnode_end) + { + grub_memmove (&(buf->dn), &(data->dnode_buf)[idx], DNODE_SIZE); + buf->endian = data->dnode_endian; + if (type && buf->dn.dn_type != type) + return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); + return GRUB_ERR_NONE; + } + + grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian, + (unsigned long long) blkid); + err = dmu_read (mdn, blkid, (void **) &dnbuf, &endian, data); + if (err) + return err; + grub_dprintf ("zfs", "alive\n"); + + grub_free (data->dnode_buf); + grub_free (data->dnode_mdn); + data->dnode_mdn = grub_malloc (sizeof (*mdn)); + if (! data->dnode_mdn) + { + grub_errno = GRUB_ERR_NONE; + data->dnode_buf = 0; + } + else + { + grub_memcpy (data->dnode_mdn, mdn, sizeof (*mdn)); + data->dnode_buf = dnbuf; + data->dnode_start = blkid << epbs; + data->dnode_end = (blkid + 1) << epbs; + data->dnode_endian = endian; + } + + grub_memmove (&(buf->dn), &dnbuf[idx], DNODE_SIZE); + buf->endian = endian; + if (type && buf->dn.dn_type != type) + return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); + + return GRUB_ERR_NONE; +} + +/* + * Get the file dnode for a given file name where mdn is the meta dnode + * for this ZFS object set. When found, place the file dnode in dn. + * The 'path' argument will be mangled. + * + */ +static grub_err_t +dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, + struct grub_zfs_data *data) +{ + grub_uint64_t objnum, version; + char *cname, ch; + grub_err_t err = GRUB_ERR_NONE; + char *path, *path_buf; + struct dnode_chain + { + struct dnode_chain *next; + dnode_end_t dn; + }; + struct dnode_chain *dnode_path = 0, *dn_new, *root; + + dn_new = grub_malloc (sizeof (*dn_new)); + if (! dn_new) + return grub_errno; + dn_new->next = 0; + dnode_path = root = dn_new; + + err = dnode_get (mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + &(dnode_path->dn), data); + if (err) + { + grub_free (dn_new); + return err; + } + + err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, data); + if (err) + { + grub_free (dn_new); + return err; + } + if (version > ZPL_VERSION) + { + grub_free (dn_new); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); + } + + err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data); + if (err) + { + grub_free (dn_new); + return err; + } + + err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); + if (err) + { + grub_free (dn_new); + return err; + } + + path = path_buf = grub_strdup (path_in); + if (!path_buf) + { + grub_free (dn_new); + return grub_errno; + } + + while (1) + { + /* skip leading slashes */ + while (*path == '/') + path++; + if (!*path) + break; + /* get the next component name */ + cname = path; + while (*path && *path != '/') + path++; + /* Skip dot. */ + if (cname + 1 == path && cname[0] == '.') + continue; + /* Handle double dot. */ + if (cname + 2 == path && cname[0] == '.' && cname[1] == '.') + { + if (dn_new->next) + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + else + { + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, + "can't resolve .."); + break; + } + continue; + } + + ch = *path; + *path = 0; /* ensure null termination */ + + if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) + { + grub_free (path_buf); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } + err = zap_lookup (&(dnode_path->dn), cname, &objnum, data); + if (err) + break; + + dn_new = grub_malloc (sizeof (*dn_new)); + if (! dn_new) + { + err = grub_errno; + break; + } + dn_new->next = dnode_path; + dnode_path = dn_new; + + objnum = ZFS_DIRENT_OBJ (objnum); + err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); + if (err) + break; + + *path = ch; +#if 0 + if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa && ch) + { + char *oldpath = path, *oldpathbuf = path_buf; + path = path_buf + = grub_malloc (sizeof (dnode_path->dn.dn.dn_bonus) + - sizeof (znode_phys_t) + grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + return grub_errno; + } + grub_memcpy (path, + (char *) DN_BONUS(&dnode_path->dn.dn) + sizeof (znode_phys_t), + sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)); + path [sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)] = 0; + grub_memcpy (path + grub_strlen (path), oldpath, + grub_strlen (oldpath) + 1); + + grub_free (oldpathbuf); + if (path[0] != '/') + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + else while (dnode_path != root) + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + } +#endif + } + + if (!err) + grub_memcpy (dn, &(dnode_path->dn), sizeof (*dn)); + + while (dnode_path) + { + dn_new = dnode_path->next; + grub_free (dnode_path); + dnode_path = dn_new; + } + grub_free (path_buf); + return err; +} + +#if 0 +/* + * Get the default 'bootfs' property value from the rootpool. + * + */ +static grub_err_t +get_default_bootfsobj (dnode_phys_t * mosmdn, grub_uint64_t * obj, + struct grub_zfs_data *data) +{ + grub_uint64_t objnum = 0; + dnode_phys_t *dn; + if (!dn) + return grub_errno; + + if ((grub_errno = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, + DMU_OT_OBJECT_DIRECTORY, dn, data))) + { + grub_free (dn); + return (grub_errno); + } + + /* + * find the object number for 'pool_props', and get the dnode + * of the 'pool_props'. + */ + if (zap_lookup (dn, DMU_POOL_PROPS, &objnum, data)) + { + grub_free (dn); + return (GRUB_ERR_BAD_FS); + } + if ((grub_errno = dnode_get (mosmdn, objnum, DMU_OT_POOL_PROPS, dn, data))) + { + grub_free (dn); + return (grub_errno); + } + if (zap_lookup (dn, ZPOOL_PROP_BOOTFS, &objnum, data)) + { + grub_free (dn); + return (GRUB_ERR_BAD_FS); + } + + if (!objnum) + { + grub_free (dn); + return (GRUB_ERR_BAD_FS); + } + + *obj = objnum; + return (0); +} +#endif +/* + * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname), + * e.g. pool/rootfs, or a given object number (obj), e.g. the object number + * of pool/rootfs. + * + * If no fsname and no obj are given, return the DSL_DIR metadnode. + * If fsname is given, return its metadnode and its matching object number. + * If only obj is given, return the metadnode for this object number. + * + */ +static grub_err_t +get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, + dnode_end_t * mdn, struct grub_zfs_data *data) +{ + grub_uint64_t objnum; + grub_err_t err; + + grub_dprintf ("zfs", "endian = %d\n", mosmdn->endian); + + err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, + DMU_OT_OBJECT_DIRECTORY, mdn, data); + if (err) + return err; + + grub_dprintf ("zfs", "alive\n"); + + err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data); + if (err) + return err; + + grub_dprintf ("zfs", "alive\n"); + + err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data); + if (err) + return err; + + grub_dprintf ("zfs", "alive\n"); + + while (*fsname) + { + grub_uint64_t childobj; + char *cname, ch; + + while (*fsname == '/') + fsname++; + + if (! *fsname || *fsname == '@') + break; + + cname = fsname; + while (*fsname && !grub_isspace (*fsname) && *fsname != '/') + fsname++; + ch = *fsname; + *fsname = 0; + + childobj = grub_zfs_to_cpu64 ((((dsl_dir_phys_t *) DN_BONUS (&mdn->dn)))->dd_child_dir_zapobj, mdn->endian); + err = dnode_get (mosmdn, childobj, + DMU_OT_DSL_DIR_CHILD_MAP, mdn, data); + if (err) + return err; + + err = zap_lookup (mdn, cname, &objnum, data); + if (err) + return err; + + err = dnode_get (mosmdn, objnum, DMU_OT_DSL_DIR, mdn, data); + if (err) + return err; + + *fsname = ch; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) +{ + objset_phys_t *osp; + blkptr_t *bp; + grub_size_t ospsize; + grub_err_t err; + + grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + + bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp); + err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data); + if (err) + return err; + if (ospsize < OBJSET_PHYS_SIZE_V14) + { + grub_free (osp); + return grub_error (GRUB_ERR_BAD_FS, "too small osp"); + } + + mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1; + grub_memmove ((char *) &(mdn->dn), (char *) &osp->os_meta_dnode, DNODE_SIZE); + grub_free (osp); + return GRUB_ERR_NONE; +} + +static grub_err_t +dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, + grub_uint64_t *mdnobj, dnode_end_t * dn, int *isfs, + struct grub_zfs_data *data) +{ + char *fsname, *snapname; + const char *ptr_at, *filename; + grub_uint64_t headobj; + grub_err_t err; + + ptr_at = grub_strchr (fullpath, '@'); + if (! ptr_at) + { + *isfs = 1; + filename = 0; + snapname = 0; + fsname = grub_strdup (fullpath); + } + else + { + const char *ptr_slash = grub_strchr (ptr_at, '/'); + + *isfs = 0; + fsname = grub_malloc (ptr_at - fullpath + 1); + if (!fsname) + return grub_errno; + grub_memcpy (fsname, fullpath, ptr_at - fullpath); + fsname[ptr_at - fullpath] = 0; + if (ptr_at[1] && ptr_at[1] != '/') + { + snapname = grub_malloc (ptr_slash - ptr_at); + if (!snapname) + { + grub_free (fsname); + return grub_errno; + } + grub_memcpy (snapname, ptr_at + 1, ptr_slash - ptr_at - 1); + snapname[ptr_slash - ptr_at - 1] = 0; + } + else + snapname = 0; + if (ptr_slash) + filename = ptr_slash; + else + filename = "/"; + grub_dprintf ("zfs", "fsname = '%s' snapname='%s' filename = '%s'\n", + fsname, snapname, filename); + } + grub_dprintf ("zfs", "alive\n"); + err = get_filesystem_dnode (&(data->mos), fsname, dn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + + grub_dprintf ("zfs", "alive\n"); + + headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_head_dataset_obj, dn->endian); + + grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + + if (snapname) + { + grub_uint64_t snapobj; + + snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_snapnames_zapobj, mdn->endian); + + err = dnode_get (&(data->mos), snapobj, + DMU_OT_DSL_DS_SNAP_MAP, mdn, data); + if (!err) + err = zap_lookup (mdn, snapname, &headobj, data); + if (!err) + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + } + + if (mdnobj) + *mdnobj = headobj; + + make_mdn (mdn, data); + + grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + + if (*isfs) + { + grub_free (fsname); + grub_free (snapname); + return GRUB_ERR_NONE; + } + err = dnode_get_path (mdn, filename, dn, data); + grub_free (fsname); + grub_free (snapname); + return err; +} + +/* + * For a given XDR packed nvlist, verify the first 4 bytes and move on. + * + * An XDR packed nvlist is encoded as (comments from nvs_xdr_create) : + * + * encoding method/host endian (4 bytes) + * nvl_version (4 bytes) + * nvl_nvflag (4 bytes) + * encoded nvpairs: + * encoded size of the nvpair (4 bytes) + * decoded size of the nvpair (4 bytes) + * name string size (4 bytes) + * name string data (sizeof(NV_ALIGN4(string)) + * data type (4 bytes) + * # of elements in the nvpair (4 bytes) + * data + * 2 zero's for the last nvpair + * (end of the entire list) (8 bytes) + * + */ + +static int +nvlist_find_value (char *nvlist, char *name, int valtype, char **val, + grub_size_t *size_out, grub_size_t *nelm_out) +{ + int name_len, type, encode_size; + char *nvpair, *nvp_name; + + /* Verify if the 1st and 2nd byte in the nvlist are valid. */ + /* NOTE: independently of what endianness header announces all + subsequent values are big-endian. */ + if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN + && nvlist[1] != NV_BIG_ENDIAN)) + { + grub_dprintf ("zfs", "incorrect nvlist header\n"); + grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); + return 0; + } + + /* skip the header, nvl_version, and nvl_nvflag */ + nvlist = nvlist + 4 * 3; + /* + * Loop thru the nvpair list + * The XDR representation of an integer is in big-endian byte order. + */ + while ((encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvlist))) + { + int nelm; + + nvpair = nvlist + 4 * 2; /* skip the encode/decode size */ + + name_len = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + nvpair += 4; + + nvp_name = nvpair; + nvpair = nvpair + ((name_len + 3) & ~3); /* align */ + + type = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + nvpair += 4; + + nelm = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + if (nelm < 1) + return grub_error (GRUB_ERR_BAD_FS, "empty nvpair"); + + nvpair += 4; + + if ((grub_strncmp (nvp_name, name, name_len) == 0) && type == valtype) + { + *val = nvpair; + *size_out = encode_size; + if (nelm_out) + *nelm_out = nelm; + return 1; + } + + nvlist += encode_size; /* goto the next nvpair */ + } + return 0; +} + +int +grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t * out) +{ + char *nvpair; + grub_size_t size; + int found; + + found = nvlist_find_value (nvlist, name, DATA_TYPE_UINT64, &nvpair, &size, 0); + if (!found) + return 0; + if (size < sizeof (grub_uint64_t)) + { + grub_error (GRUB_ERR_BAD_FS, "invalid uint64"); + return 0; + } + + *out = grub_be_to_cpu64 (*(grub_uint64_t *) nvpair); + return 1; +} + +char * +grub_zfs_nvlist_lookup_string (char *nvlist, char *name) +{ + char *nvpair; + char *ret; + grub_size_t slen; + grub_size_t size; + int found; + + found = nvlist_find_value (nvlist, name, DATA_TYPE_STRING, &nvpair, &size, 0); + if (!found) + return 0; + if (size < 4) + { + grub_error (GRUB_ERR_BAD_FS, "invalid string"); + return 0; + } + slen = grub_be_to_cpu32 (*(grub_uint32_t *) nvpair); + if (slen > size - 4) + slen = size - 4; + ret = grub_malloc (slen + 1); + if (!ret) + return 0; + grub_memcpy (ret, nvpair + 4, slen); + ret[slen] = 0; + return ret; +} + +char * +grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name) +{ + char *nvpair; + char *ret; + grub_size_t size; + int found; + + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + &size, 0); + if (!found) + return 0; + ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t)); + if (!ret) + return 0; + grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); + + grub_memcpy (ret + sizeof (grub_uint32_t), nvpair, size); + return ret; +} + +int +grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) +{ + char *nvpair; + grub_size_t nelm, size; + int found; + + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + &size, &nelm); + if (! found) + return -1; + return nelm; +} + +char * +grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, + grub_size_t index) +{ + char *nvpair, *nvpairptr; + int found; + char *ret; + grub_size_t size; + unsigned i; + grub_size_t nelm; + + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + &size, &nelm); + if (!found) + return 0; + if (index >= nelm) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "trying to lookup past nvlist array"); + return 0; + } + + nvpairptr = nvpair; + + for (i = 0; i < index; i++) + { + grub_uint32_t encode_size; + + /* skip the header, nvl_version, and nvl_nvflag */ + nvpairptr = nvpairptr + 4 * 2; + + while (nvpairptr < nvpair + size + && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvpairptr))) + nvlist += encode_size; /* goto the next nvpair */ + + nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */ + } + + if (nvpairptr >= nvpair + size + || nvpairptr + grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) + >= nvpair + size) + { + grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); + return 0; + } + + ret = grub_zalloc (grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) + + 3 * sizeof (grub_uint32_t)); + if (!ret) + return 0; + grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); + + grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, size); + return ret; +} + +static grub_err_t +zfs_fetch_nvlist (struct grub_zfs_data * data, char **nvlist) +{ + grub_err_t err; + + *nvlist = grub_malloc (VDEV_PHYS_SIZE); + /* Read in the vdev name-value pair list (112K). */ + err = grub_disk_read (data->disk, data->vdev_phys_sector, 0, + VDEV_PHYS_SIZE, *nvlist); + if (err) + { + grub_free (*nvlist); + *nvlist = 0; + return err; + } + return GRUB_ERR_NONE; +} + +/* + * Check the disk label information and retrieve needed vdev name-value pairs. + * + */ +static grub_err_t +check_pool_label (struct grub_zfs_data *data) +{ + grub_uint64_t pool_state, txg = 0; + char *nvlist; +#if 0 + char *nv; +#endif + grub_uint64_t diskguid; + grub_uint64_t version; + int found; + grub_err_t err; + + err = zfs_fetch_nvlist (data, &nvlist); + if (err) + return err; + + grub_dprintf ("zfs", "check 2 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, + &pool_state); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 3 passed\n"); + + if (pool_state == POOL_STATE_DESTROYED) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); + } + grub_dprintf ("zfs", "check 4 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); + if (!found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 6 passed\n"); + + /* not an active device */ + if (txg == 0) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); + } + grub_dprintf ("zfs", "check 7 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, + &version); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 8 passed\n"); + + if (version > SPA_VERSION) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "too new version %llu > %llu", + (unsigned long long) version, + (unsigned long long) SPA_VERSION); + } + grub_dprintf ("zfs", "check 9 passed\n"); +#if 0 + if (nvlist_lookup_value (nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv, + DATA_TYPE_NVLIST, NULL)) + { + grub_free (vdev); + return (GRUB_ERR_BAD_FS); + } + grub_dprintf ("zfs", "check 10 passed\n"); +#endif + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 11 passed\n"); + + grub_free (nvlist); + + return GRUB_ERR_NONE; +} + +static void +zfs_unmount (struct grub_zfs_data *data) +{ + grub_free (data->dnode_buf); + grub_free (data->dnode_mdn); + grub_free (data->file_buf); + grub_free (data); +} + +/* + * zfs_mount() locates a valid uberblock of the root pool and read in its MOS + * to the memory address MOS. + * + */ +static struct grub_zfs_data * +zfs_mount (grub_device_t dev) +{ + struct grub_zfs_data *data = 0; + int label = 0; + uberblock_phys_t *ub_array, *ubbest = NULL; + vdev_boot_header_t *bh; + objset_phys_t *osp = 0; + grub_size_t ospsize; + grub_err_t err; + int vdevnum; + + if (! dev->disk) + { + grub_error (GRUB_ERR_BAD_DEVICE, "not a disk"); + return 0; + } + + data = grub_malloc (sizeof (*data)); + if (!data) + return 0; + grub_memset (data, 0, sizeof (*data)); +#if 0 + /* if it's our first time here, zero the best uberblock out */ + if (data->best_drive == 0 && data->best_part == 0 && find_best_root) + grub_memset (¤t_uberblock, 0, sizeof (uberblock_t)); +#endif + + data->disk = dev->disk; + + ub_array = grub_malloc (VDEV_UBERBLOCK_RING); + if (!ub_array) + { + zfs_unmount (data); + return 0; + } + + bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); + if (!bh) + { + zfs_unmount (data); + grub_free (ub_array); + return 0; + } + + vdevnum = VDEV_LABELS; + + /* Don't check back labels on CDROM. */ + if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) + vdevnum = VDEV_LABELS / 2; + + for (label = 0; ubbest == NULL && label < vdevnum; label++) + { + grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + grub_dprintf ("zfs", "label %d\n", label); + + data->vdev_phys_sector + = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) + + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) + + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (dev->disk) + - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); + + /* Read in the uberblock ring (128K). */ + err = grub_disk_read (data->disk, data->vdev_phys_sector + + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), + 0, VDEV_UBERBLOCK_RING, (char *) ub_array); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + grub_dprintf ("zfs", "label ok %d\n", label); + + ubbest = find_bestub (ub_array, data->vdev_phys_sector); + if (!ubbest) + { + grub_dprintf ("zfs", "No uberblock found\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + ub_endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_magic, + LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? LITTLE_ENDIAN : BIG_ENDIAN); + err = zio_read (&ubbest->ubp_uberblock.ub_rootbp, + ub_endian, + (void **) &osp, &ospsize, data); + if (err) + { + grub_dprintf ("zfs", "couldn't zio_read\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + + if (ospsize < OBJSET_PHYS_SIZE_V14) + { + grub_dprintf ("zfs", "osp too small\n"); + grub_free (osp); + continue; + } + grub_dprintf ("zfs", "ubbest %p\n", ubbest); + + err = check_pool_label (data); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } +#if 0 + if (find_best_root && + vdev_uberblock_compare (&ubbest->ubp_uberblock, + &(current_uberblock)) <= 0) + continue; +#endif + /* Got the MOS. Save it at the memory addr MOS. */ + grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); + data->mos.endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_rootbp.blk_prop, ub_endian) >> 63) & 1; + grub_memmove (&(data->current_uberblock), + &ubbest->ubp_uberblock, sizeof (uberblock_t)); + grub_free (ub_array); + grub_free (bh); + grub_free (osp); + return data; + } + grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); + zfs_unmount (data); + grub_free (ub_array); + grub_free (bh); + grub_free (osp); + + return 0; +} + +grub_err_t +grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) +{ + struct grub_zfs_data *zfs; + grub_err_t err; + + zfs = zfs_mount (dev); + if (!zfs) + return grub_errno; + err = zfs_fetch_nvlist (zfs, nvlist); + zfs_unmount (zfs); + return err; +} + +static grub_err_t +zfs_label (grub_device_t device, char **label) +{ + char *nvlist; + grub_err_t err; + struct grub_zfs_data *data; + + data = zfs_mount (device); + if (! data) + return grub_errno; + + err = zfs_fetch_nvlist (data, &nvlist); + if (err) + { + zfs_unmount (data); + return err; + } + + *label = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); + grub_free (nvlist); + zfs_unmount (data); + return grub_errno; +} + +static grub_err_t +zfs_uuid (grub_device_t device, char **uuid) +{ + char *nvlist; + int found; + struct grub_zfs_data *data; + grub_uint64_t guid; + grub_err_t err; + + *uuid = 0; + + data = zfs_mount (device); + if (! data) + return grub_errno; + + err = zfs_fetch_nvlist (data, &nvlist); + if (err) + { + zfs_unmount (data); + return err; + } + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); + if (! found) + return grub_errno; + grub_free (nvlist); + *uuid = grub_xasprintf ("%016llx", (long long unsigned) guid); + zfs_unmount (data); + if (! *uuid) + return grub_errno; + return GRUB_ERR_NONE; +} + +/* + * zfs_open() locates a file in the rootpool by following the + * MOS and places the dnode of the file in the memory address DNODE. + */ +static grub_err_t +grub_zfs_open (struct grub_file *file, const char *fsfilename) +{ + struct grub_zfs_data *data; + grub_err_t err; + int isfs; + + data = zfs_mount (file->device); + if (! data) + return grub_errno; + + err = dnode_get_fullpath (fsfilename, &(data->mdn), 0, + &(data->dnode), &isfs, data); + if (err) + { + zfs_unmount (data); + return err; + } + + if (isfs) + { + zfs_unmount (data); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Missing @ or / separator"); + } + + /* We found the dnode for this file. Verify if it is a plain file. */ + if (data->dnode.dn.dn_type != DMU_OT_PLAIN_FILE_CONTENTS) + { + zfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file"); + } + + /* get the file size and set the file position to 0 */ + + /* + * For DMU_OT_SA we will need to locate the SIZE attribute + * attribute, which could be either in the bonus buffer + * or the "spill" block. + */ + if (data->dnode.dn.dn_bonustype == DMU_OT_SA) + { + sa_hdr_phys_t *sahdrp; + int hdrsize; + + if (data->dnode.dn.dn_bonuslen != 0) + { + sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn); + } + else if (data->dnode.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &data->dnode.dn.dn_spill; + + err = zio_read (bp, data->dnode.endian, (void **) &sahdrp, NULL, data); + if (err) + return err; + } + else + { + return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + } + + hdrsize = SA_HDR_SIZE (sahdrp); + file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET); + } + else + { + file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian); + } + + file->data = data; + file->offset = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_zfs_data *data = (struct grub_zfs_data *) file->data; + int blksz, movesize; + grub_size_t length; + grub_size_t read; + grub_err_t err; + + if (data->file_buf == NULL) + { + data->file_buf = grub_malloc (SPA_MAXBLOCKSIZE); + if (!data->file_buf) + return -1; + data->file_start = data->file_end = 0; + } + + /* + * If offset is in memory, move it into the buffer provided and return. + */ + if (file->offset >= data->file_start + && file->offset + len <= data->file_end) + { + grub_memmove (buf, data->file_buf + file->offset - data->file_start, + len); + return len; + } + + blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec, + data->dnode.endian) << SPA_MINBLOCKSHIFT; + + /* + * Entire Dnode is too big to fit into the space available. We + * will need to read it in chunks. This could be optimized to + * read in as large a chunk as there is space available, but for + * now, this only reads in one data block at a time. + */ + length = len; + read = 0; + while (length) + { + /* + * Find requested blkid and the offset within that block. + */ + grub_uint64_t blkid = grub_divmod64 (file->offset + read, blksz, 0); + grub_free (data->file_buf); + data->file_buf = 0; + + err = dmu_read (&(data->dnode), blkid, (void **) &(data->file_buf), + 0, data); + if (err) + return -1; + + data->file_start = blkid * blksz; + data->file_end = data->file_start + blksz; + + movesize = MIN (length, data->file_end - (int) file->offset - read); + + grub_memmove (buf, data->file_buf + file->offset + read + - data->file_start, movesize); + buf += movesize; + length -= movesize; + read += movesize; + } + + return len; +} + +static grub_err_t +grub_zfs_close (grub_file_t file) +{ + zfs_unmount ((struct grub_zfs_data *) file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, + grub_uint64_t *mdnobj) +{ + struct grub_zfs_data *data; + grub_err_t err; + int isfs; + + data = zfs_mount (dev); + if (! data) + return grub_errno; + + err = dnode_get_fullpath (fsfilename, &(data->mdn), mdnobj, + &(data->dnode), &isfs, data); + zfs_unmount (data); + return err; +} + +static void +fill_fs_info (struct grub_dirhook_info *info, + dnode_end_t mdn, struct grub_zfs_data *data) +{ + grub_err_t err; + dnode_end_t dn; + grub_uint64_t objnum; + grub_uint64_t headobj; + + grub_memset (info, 0, sizeof (*info)); + + info->dir = 1; + + if (mdn.dn.dn_type == DMU_OT_DSL_DIR) + { + headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian); + + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &mdn, data); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); + return; + } + } + make_mdn (&mdn, data); + err = dnode_get (&mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + &dn, data); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); + return; + } + + err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); + return; + } + + err = dnode_get (&mdn, objnum, 0, &dn, data); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); + return; + } + + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + return; +} + +static grub_err_t +grub_zfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *, const struct grub_dirhook_info *)) +{ + struct grub_zfs_data *data; + grub_err_t err; + int isfs; + auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); + auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, + grub_uint64_t val); + auto int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, + grub_uint64_t val); + + int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val) + { + struct grub_dirhook_info info; + dnode_end_t dn; + grub_memset (&info, 0, sizeof (info)); + + dnode_get (&(data->mdn), val, 0, &dn, data); + info.mtimeset = 1; + info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); + grub_dprintf ("zfs", "type=%d, name=%s\n", + (int)dn.dn.dn_type, (char *)name); + return hook (name, &info); + } + + int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val) + { + struct grub_dirhook_info info; + dnode_end_t mdn; + err = dnode_get (&(data->mos), val, 0, &mdn, data); + if (err) + return 0; + if (mdn.dn.dn_type != DMU_OT_DSL_DIR) + return 0; + + fill_fs_info (&info, mdn, data); + return hook (name, &info); + } + int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, grub_uint64_t val) + { + struct grub_dirhook_info info; + char *name2; + int ret; + dnode_end_t mdn; + + err = dnode_get (&(data->mos), val, 0, &mdn, data); + if (err) + return 0; + + if (mdn.dn.dn_type != DMU_OT_DSL_DATASET) + return 0; + + fill_fs_info (&info, mdn, data); + + name2 = grub_malloc (grub_strlen (name) + 2); + name2[0] = '@'; + grub_memcpy (name2 + 1, name, grub_strlen (name) + 1); + ret = hook (name2, &info); + grub_free (name2); + return ret; + } + + data = zfs_mount (device); + if (! data) + return grub_errno; + err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data); + if (err) + { + zfs_unmount (data); + return err; + } + if (isfs) + { + grub_uint64_t childobj, headobj; + grub_uint64_t snapobj; + dnode_end_t dn; + struct grub_dirhook_info info; + + fill_fs_info (&info, data->dnode, data); + hook ("@", &info); + + childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian); + headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian); + err = dnode_get (&(data->mos), childobj, + DMU_OT_DSL_DIR_CHILD_MAP, &dn, data); + if (err) + { + zfs_unmount (data); + return err; + } + + zap_iterate (&dn, iterate_zap_fs, data); + + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data); + if (err) + { + zfs_unmount (data); + return err; + } + + snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&dn.dn))->ds_snapnames_zapobj, dn.endian); + + err = dnode_get (&(data->mos), snapobj, + DMU_OT_DSL_DS_SNAP_MAP, &dn, data); + if (err) + { + zfs_unmount (data); + return err; + } + + zap_iterate (&dn, iterate_zap_snap, data); + } + else + { + if (data->dnode.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) + { + zfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } + zap_iterate (&(data->dnode), iterate_zap, data); + } + zfs_unmount (data); + return grub_errno; +} + +static struct grub_fs grub_zfs_fs = { + .name = "zfs", + .dir = grub_zfs_dir, + .open = grub_zfs_open, + .read = grub_zfs_read, + .close = grub_zfs_close, + .label = zfs_label, + .uuid = zfs_uuid, + .mtime = 0, + .next = 0 +}; + +GRUB_MOD_INIT (zfs) +{ + grub_fs_register (&grub_zfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI (zfs) +{ + grub_fs_unregister (&grub_zfs_fs); +} diff --git a/grub-core/fs/zfs/zfs_fletcher.c b/grub-core/fs/zfs/zfs_fletcher.c new file mode 100644 index 000000000..eaed15a2c --- /dev/null +++ b/grub-core/fs/zfs/zfs_fletcher.c @@ -0,0 +1,86 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright 2007 Sun Microsystems, Inc. + * Copyright (C) 2009 Vladimir Serbinenko + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +fletcher_2(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, + zio_cksum_t *zcp) +{ + const grub_uint64_t *ip = buf; + const grub_uint64_t *ipend = ip + (size / sizeof (grub_uint64_t)); + grub_uint64_t a0, b0, a1, b1; + + for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) + { + a0 += grub_zfs_to_cpu64 (ip[0], endian); + a1 += grub_zfs_to_cpu64 (ip[1], endian); + b0 += a0; + b1 += a1; + } + + zcp->zc_word[0] = grub_cpu_to_zfs64 (a0, endian); + zcp->zc_word[1] = grub_cpu_to_zfs64 (a1, endian); + zcp->zc_word[2] = grub_cpu_to_zfs64 (b0, endian); + zcp->zc_word[3] = grub_cpu_to_zfs64 (b1, endian); +} + +void +fletcher_4 (const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, + zio_cksum_t *zcp) +{ + const grub_uint32_t *ip = buf; + const grub_uint32_t *ipend = ip + (size / sizeof (grub_uint32_t)); + grub_uint64_t a, b, c, d; + + for (a = b = c = d = 0; ip < ipend; ip++) + { + a += grub_zfs_to_cpu32 (ip[0], endian);; + b += a; + c += b; + d += c; + } + + zcp->zc_word[0] = grub_cpu_to_zfs64 (a, endian); + zcp->zc_word[1] = grub_cpu_to_zfs64 (b, endian); + zcp->zc_word[2] = grub_cpu_to_zfs64 (c, endian); + zcp->zc_word[3] = grub_cpu_to_zfs64 (d, endian); +} + diff --git a/grub-core/fs/zfs/zfs_lzjb.c b/grub-core/fs/zfs/zfs_lzjb.c new file mode 100644 index 000000000..0965d2d1f --- /dev/null +++ b/grub-core/fs/zfs/zfs_lzjb.c @@ -0,0 +1,95 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright 2007 Sun Microsystems, Inc. + * Copyright (C) 2009 Vladimir Serbinenko + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MATCH_BITS 6 +#define MATCH_MIN 3 +#define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) + +/* + * Decompression Entry - lzjb + */ +#ifndef NBBY +#define NBBY 8 +#endif + +grub_err_t +lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len, + grub_size_t d_len); + +grub_err_t +lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len, + grub_size_t d_len) +{ + grub_uint8_t *src = s_start; + grub_uint8_t *dst = d_start; + grub_uint8_t *d_end = (grub_uint8_t *) d_start + d_len; + grub_uint8_t *s_end = (grub_uint8_t *) s_start + s_len; + grub_uint8_t *cpy, copymap = 0; + int copymask = 1 << (NBBY - 1); + + while (dst < d_end && src < s_end) + { + if ((copymask <<= 1) == (1 << NBBY)) + { + copymask = 1; + copymap = *src++; + } + if (src >= s_end) + return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); + if (copymap & copymask) + { + int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; + int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; + src += 2; + cpy = dst - offset; + if (src > s_end || cpy < (grub_uint8_t *) d_start) + return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); + while (--mlen >= 0 && dst < d_end) + *dst++ = *cpy++; + } + else + *dst++ = *src++; + } + if (dst < d_end) + return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); + return GRUB_ERR_NONE; +} diff --git a/grub-core/fs/zfs/zfs_sha256.c b/grub-core/fs/zfs/zfs_sha256.c new file mode 100644 index 000000000..3dc79268a --- /dev/null +++ b/grub-core/fs/zfs/zfs_sha256.c @@ -0,0 +1,145 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright 2007 Sun Microsystems, Inc. + * Copyright (C) 2009 Vladimir Serbinenko + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * SHA-256 checksum, as specified in FIPS 180-2, available at: + * http://csrc.nist.gov/cryptval + * + * This is a very compact implementation of SHA-256. + * It is designed to be simple and portable, not to be fast. + */ + +/* + * The literal definitions according to FIPS180-2 would be: + * + * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) + * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) + * + * We use logical equivalents which require one less op. + */ +#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) +#define Rot32(x, s) (((x) >> s) | ((x) << (32 - s))) +#define SIGMA0(x) (Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22)) +#define SIGMA1(x) (Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25)) +#define sigma0(x) (Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3)) +#define sigma1(x) (Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10)) + +static const grub_uint32_t SHA256_K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static void +SHA256Transform(grub_uint32_t *H, const grub_uint8_t *cp) +{ + grub_uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64]; + + for (t = 0; t < 16; t++, cp += 4) + W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]; + + for (t = 16; t < 64; t++) + W[t] = sigma1(W[t - 2]) + W[t - 7] + + sigma0(W[t - 15]) + W[t - 16]; + + a = H[0]; b = H[1]; c = H[2]; d = H[3]; + e = H[4]; f = H[5]; g = H[6]; h = H[7]; + + for (t = 0; t < 64; t++) { + T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t]; + T2 = SIGMA0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + T1; + d = c; c = b; b = a; a = T1 + T2; + } + + H[0] += a; H[1] += b; H[2] += c; H[3] += d; + H[4] += e; H[5] += f; H[6] += g; H[7] += h; +} + +void +zio_checksum_SHA256(const void *buf, grub_uint64_t size, + grub_zfs_endian_t endian, zio_cksum_t *zcp) +{ + grub_uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; + grub_uint8_t pad[128]; + unsigned padsize = size & 63; + unsigned i; + + for (i = 0; i < size - padsize; i += 64) + SHA256Transform(H, (grub_uint8_t *)buf + i); + + for (i = 0; i < padsize; i++) + pad[i] = ((grub_uint8_t *)buf)[i]; + + for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) + pad[padsize] = 0; + + for (i = 0; i < 8; i++) + pad[padsize++] = (size << 3) >> (56 - 8 * i); + + for (i = 0; i < padsize; i += 64) + SHA256Transform(H, pad + i); + + zcp->zc_word[0] = grub_cpu_to_zfs64 ((grub_uint64_t)H[0] << 32 | H[1], + endian); + zcp->zc_word[1] = grub_cpu_to_zfs64 ((grub_uint64_t)H[2] << 32 | H[3], + endian); + zcp->zc_word[2] = grub_cpu_to_zfs64 ((grub_uint64_t)H[4] << 32 | H[5], + endian); + zcp->zc_word[3] = grub_cpu_to_zfs64 ((grub_uint64_t)H[6] << 32 | H[7], + endian); +} diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c new file mode 100644 index 000000000..a9a13507e --- /dev/null +++ b/grub-core/fs/zfs/zfsinfo.c @@ -0,0 +1,414 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright 2008 Sun Microsystems, Inc. + * Copyright (C) 2009 Vladimir Serbinenko + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void +print_tabs (int n) +{ + int i; + + for (i = 0; i < n; i++) + grub_printf (" "); +} + +static grub_err_t +print_state (char *nvlist, int tab) +{ + grub_uint64_t ival; + int isok = 1; + + print_tabs (tab); + grub_printf ("State: "); + + if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_REMOVED, &ival)) + { + grub_printf ("removed "); + isok = 0; + } + + if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) + { + grub_printf ("faulted "); + isok = 0; + } + + if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_OFFLINE, &ival)) + { + grub_printf ("offline "); + isok = 0; + } + + if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) + grub_printf ("degraded "); + + if (isok) + grub_printf ("online"); + grub_printf ("\n"); + + return GRUB_ERR_NONE; +} + +static grub_err_t +print_vdev_info (char *nvlist, int tab) +{ + char *type = 0; + + type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); + + if (!type) + { + print_tabs (tab); + grub_printf ("Incorrect VDEV: no type available\n"); + return grub_errno; + } + + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) + { + char *bootpath = 0; + char *path = 0; + char *devid = 0; + + print_tabs (tab); + grub_printf ("Leaf VDEV\n"); + + print_state (nvlist, tab); + + bootpath = + grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH); + print_tabs (tab); + if (!bootpath) + grub_printf ("Bootpath: unavailable\n"); + else + grub_printf ("Bootpath: %s\n", bootpath); + + path = grub_zfs_nvlist_lookup_string (nvlist, "path"); + print_tabs (tab); + if (!path) + grub_printf ("Path: unavailable\n"); + else + grub_printf ("Path: %s\n", path); + + devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); + print_tabs (tab); + if (!devid) + grub_printf ("Devid: unavailable\n"); + else + grub_printf ("Devid: %s\n", devid); + grub_free (bootpath); + grub_free (devid); + grub_free (path); + return GRUB_ERR_NONE; + } + + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + { + int nelm, i; + + nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm + (nvlist, ZPOOL_CONFIG_CHILDREN); + + print_tabs (tab); + if (nelm <= 0) + { + grub_printf ("Incorrect mirror VDEV\n"); + return GRUB_ERR_NONE; + } + grub_printf ("Mirror VDEV with %d children\n", nelm); + print_state (nvlist, tab); + + for (i = 0; i < nelm; i++) + { + char *child; + + child = grub_zfs_nvlist_lookup_nvlist_array + (nvlist, ZPOOL_CONFIG_CHILDREN, i); + + print_tabs (tab); + if (!child) + { + grub_printf ("Mirror VDEV element %d isn't correct\n", i); + continue; + } + + grub_printf ("Mirror VDEV element %d:\n", i); + print_vdev_info (child, tab + 1); + + grub_free (child); + } + } + + print_tabs (tab); + grub_printf ("Unknown VDEV type: %s\n", type); + + return GRUB_ERR_NONE; +} + +static grub_err_t +get_bootpath (char *nvlist, char **bootpath, char **devid) +{ + char *type = 0; + + type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); + + if (!type) + return grub_errno; + + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) + { + *bootpath = grub_zfs_nvlist_lookup_string (nvlist, + ZPOOL_CONFIG_PHYS_PATH); + *devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); + if (!*bootpath || !*devid) + { + grub_free (*bootpath); + grub_free (*devid); + *bootpath = 0; + *devid = 0; + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + { + int nelm, i; + + nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm + (nvlist, ZPOOL_CONFIG_CHILDREN); + + for (i = 0; i < nelm; i++) + { + char *child; + + child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, + ZPOOL_CONFIG_CHILDREN, + i); + + get_bootpath (child, bootpath, devid); + + grub_free (child); + + if (*bootpath && *devid) + return GRUB_ERR_NONE; + } + } + + return GRUB_ERR_NONE; +} + +static char *poolstates[] = { + [POOL_STATE_ACTIVE] = "active", + [POOL_STATE_EXPORTED] = "exported", + [POOL_STATE_DESTROYED] = "destroyed", + [POOL_STATE_SPARE] = "reserved for hot spare", + [POOL_STATE_L2CACHE] = "level 2 ARC device", + [POOL_STATE_UNINITIALIZED] = "uninitialized", + [POOL_STATE_UNAVAIL] = "unavailable", + [POOL_STATE_POTENTIALLY_ACTIVE] = "potentially active" +}; + +static grub_err_t +grub_cmd_zfsinfo (grub_command_t cmd __attribute__ ((unused)), int argc, + char **args) +{ + grub_device_t dev; + char *devname; + grub_err_t err; + char *nvlist = 0; + char *nv = 0; + char *poolname; + grub_uint64_t guid; + grub_uint64_t pool_state; + int found; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')') + { + devname = grub_strdup (args[0] + 1); + if (devname) + devname[grub_strlen (devname) - 1] = 0; + } + else + devname = grub_strdup (args[0]); + if (!devname) + return grub_errno; + + dev = grub_device_open (devname); + grub_free (devname); + if (!dev) + return grub_errno; + + err = grub_zfs_fetch_nvlist (dev, &nvlist); + + grub_device_close (dev); + + if (err) + return err; + + poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); + if (!poolname) + grub_printf ("Pool name: unavailable\n"); + else + grub_printf ("Pool name: %s\n", poolname); + + found = + grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); + if (!found) + grub_printf ("Pool GUID: unavailable\n"); + else + grub_printf ("Pool GUID: %016llx\n", (long long unsigned) guid); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, + &pool_state); + if (!found) + grub_printf ("Unable to retrieve pool state\n"); + else if (pool_state >= ARRAY_SIZE (poolstates)) + grub_printf ("Unrecognized pool state\n"); + else + grub_printf ("Pool state: %s\n", poolstates[pool_state]); + + nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); + + if (!nv) + grub_printf ("No vdev tree available\n"); + else + print_vdev_info (nv, 1); + + grub_free (nv); + grub_free (nvlist); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, + char **args) +{ + grub_device_t dev; + char *devname; + grub_err_t err; + char *nvlist = 0; + char *nv = 0; + char *bootpath = 0, *devid = 0; + char *fsname; + char *bootfs; + char *poolname; + grub_uint64_t mdnobj; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "filesystem name required"); + + devname = grub_file_get_device_name (args[0]); + if (grub_errno) + return grub_errno; + + dev = grub_device_open (devname); + grub_free (devname); + if (!dev) + return grub_errno; + + err = grub_zfs_fetch_nvlist (dev, &nvlist); + + fsname = grub_strchr (args[0], ')'); + if (fsname) + fsname++; + else + fsname = args[0]; + + if (!err) + err = grub_zfs_getmdnobj (dev, fsname, &mdnobj); + + grub_device_close (dev); + + if (err) + return err; + + poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); + if (!poolname) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_FS, "No poolname found"); + return grub_errno; + } + + nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); + + if (nv) + get_bootpath (nv, &bootpath, &devid); + + grub_free (nv); + grub_free (nvlist); + + if (bootpath && devid) + { + bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu bootpath=%s diskdevid=%s", + poolname, (unsigned long long) mdnobj, + bootpath, devid); + if (!bootfs) + return grub_errno; + } + else + { + bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu", + poolname, (unsigned long long) mdnobj); + if (!bootfs) + return grub_errno; + } + if (argc >= 2) + grub_env_set (args[1], bootfs); + else + grub_printf ("%s\n", bootfs); + + grub_free (bootfs); + grub_free (poolname); + grub_free (bootpath); + grub_free (devid); + + return GRUB_ERR_NONE; +} + + +static grub_command_t cmd_info, cmd_bootfs; + +GRUB_MOD_INIT (zfsinfo) +{ + cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, + "zfsinfo DEVICE", + "Print ZFS info about DEVICE."); + cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, + "zfs-bootfs FILESYSTEM [VARIABLE]", + "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); +} + +GRUB_MOD_FINI (zfsinfo) +{ + grub_unregister_command (cmd_info); + grub_unregister_command (cmd_bootfs); +} diff --git a/include/grub/zfs/dmu.h b/include/grub/zfs/dmu.h new file mode 100644 index 000000000..7faa7088b --- /dev/null +++ b/include/grub/zfs/dmu.h @@ -0,0 +1,120 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_DMU_H +#define _SYS_DMU_H + +/* + * This file describes the interface that the DMU provides for its + * consumers. + * + * The DMU also interacts with the SPA. That interface is described in + * dmu_spa.h. + */ +typedef enum dmu_object_type { + DMU_OT_NONE, + /* general: */ + DMU_OT_OBJECT_DIRECTORY, /* ZAP */ + DMU_OT_OBJECT_ARRAY, /* UINT64 */ + DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */ + DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */ + DMU_OT_BPLIST, /* UINT64 */ + DMU_OT_BPLIST_HDR, /* UINT64 */ + /* spa: */ + DMU_OT_SPACE_MAP_HEADER, /* UINT64 */ + DMU_OT_SPACE_MAP, /* UINT64 */ + /* zil: */ + DMU_OT_INTENT_LOG, /* UINT64 */ + /* dmu: */ + DMU_OT_DNODE, /* DNODE */ + DMU_OT_OBJSET, /* OBJSET */ + /* dsl: */ + DMU_OT_DSL_DIR, /* UINT64 */ + DMU_OT_DSL_DIR_CHILD_MAP, /* ZAP */ + DMU_OT_DSL_DS_SNAP_MAP, /* ZAP */ + DMU_OT_DSL_PROPS, /* ZAP */ + DMU_OT_DSL_DATASET, /* UINT64 */ + /* zpl: */ + DMU_OT_ZNODE, /* ZNODE */ + DMU_OT_OLDACL, /* OLD ACL */ + DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */ + DMU_OT_DIRECTORY_CONTENTS, /* ZAP */ + DMU_OT_MASTER_NODE, /* ZAP */ + DMU_OT_UNLINKED_SET, /* ZAP */ + /* zvol: */ + DMU_OT_ZVOL, /* UINT8 */ + DMU_OT_ZVOL_PROP, /* ZAP */ + /* other; for testing only! */ + DMU_OT_PLAIN_OTHER, /* UINT8 */ + DMU_OT_UINT64_OTHER, /* UINT64 */ + DMU_OT_ZAP_OTHER, /* ZAP */ + /* new object types: */ + DMU_OT_ERROR_LOG, /* ZAP */ + DMU_OT_SPA_HISTORY, /* UINT8 */ + DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */ + DMU_OT_POOL_PROPS, /* ZAP */ + DMU_OT_DSL_PERMS, /* ZAP */ + DMU_OT_ACL, /* ACL */ + DMU_OT_SYSACL, /* SYSACL */ + DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ + DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ + DMU_OT_NEXT_CLONES, /* ZAP */ + DMU_OT_SCRUB_QUEUE, /* ZAP */ + DMU_OT_USERGROUP_USED, /* ZAP */ + DMU_OT_USERGROUP_QUOTA, /* ZAP */ + DMU_OT_USERREFS, /* ZAP */ + DMU_OT_DDT_ZAP, /* ZAP */ + DMU_OT_DDT_STATS, /* ZAP */ + DMU_OT_SA, /* System attr */ + DMU_OT_SA_MASTER_NODE, /* ZAP */ + DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ + DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ + DMU_OT_NUMTYPES +} dmu_object_type_t; + +typedef enum dmu_objset_type { + DMU_OST_NONE, + DMU_OST_META, + DMU_OST_ZFS, + DMU_OST_ZVOL, + DMU_OST_OTHER, /* For testing only! */ + DMU_OST_ANY, /* Be careful! */ + DMU_OST_NUMTYPES +} dmu_objset_type_t; + +/* + * The names of zap entries in the DIRECTORY_OBJECT of the MOS. + */ +#define DMU_POOL_DIRECTORY_OBJECT 1 +#define DMU_POOL_CONFIG "config" +#define DMU_POOL_ROOT_DATASET "root_dataset" +#define DMU_POOL_SYNC_BPLIST "sync_bplist" +#define DMU_POOL_ERRLOG_SCRUB "errlog_scrub" +#define DMU_POOL_ERRLOG_LAST "errlog_last" +#define DMU_POOL_SPARES "spares" +#define DMU_POOL_DEFLATE "deflate" +#define DMU_POOL_HISTORY "history" +#define DMU_POOL_PROPS "pool_props" +#define DMU_POOL_L2CACHE "l2cache" + +#endif /* _SYS_DMU_H */ diff --git a/include/grub/zfs/dmu_objset.h b/include/grub/zfs/dmu_objset.h new file mode 100644 index 000000000..aa1f4ab19 --- /dev/null +++ b/include/grub/zfs/dmu_objset.h @@ -0,0 +1,44 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 2010 Robert Millan + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_DMU_OBJSET_H +#define _SYS_DMU_OBJSET_H + +#include + +#define OBJSET_PHYS_SIZE 2048 +#define OBJSET_PHYS_SIZE_V14 1024 + +typedef struct objset_phys { + dnode_phys_t os_meta_dnode; + zil_header_t os_zil_header; + grub_uint64_t os_type; + grub_uint64_t os_flags; + char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 - + sizeof (zil_header_t) - sizeof (grub_uint64_t)*2]; + dnode_phys_t os_userused_dnode; + dnode_phys_t os_groupused_dnode; +} objset_phys_t; + +#endif /* _SYS_DMU_OBJSET_H */ diff --git a/include/grub/zfs/dnode.h b/include/grub/zfs/dnode.h new file mode 100644 index 000000000..6b0e18427 --- /dev/null +++ b/include/grub/zfs/dnode.h @@ -0,0 +1,81 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_DNODE_H +#define _SYS_DNODE_H + +#include + +/* + * Fixed constants. + */ +#define DNODE_SHIFT 9 /* 512 bytes */ +#define DN_MIN_INDBLKSHIFT 10 /* 1k */ +#define DN_MAX_INDBLKSHIFT 14 /* 16k */ +#define DNODE_BLOCK_SHIFT 14 /* 16k */ +#define DNODE_CORE_SIZE 64 /* 64 bytes for dnode sans blkptrs */ +#define DN_MAX_OBJECT_SHIFT 48 /* 256 trillion (zfs_fid_t limit) */ +#define DN_MAX_OFFSET_SHIFT 64 /* 2^64 bytes in a dnode */ + +/* + * Derived constants. + */ +#define DNODE_SIZE (1 << DNODE_SHIFT) +#define DN_MAX_NBLKPTR ((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT) +#define DN_MAX_BONUSLEN (DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT)) +#define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT) + +#define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT) +#define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT) +#define DNODES_PER_LEVEL_SHIFT (DN_MAX_INDBLKSHIFT - SPA_BLKPTRSHIFT) + +#define DNODE_FLAG_SPILL_BLKPTR (1<<2) + +#define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \ + (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t)))) + +typedef struct dnode_phys { + grub_uint8_t dn_type; /* dmu_object_type_t */ + grub_uint8_t dn_indblkshift; /* ln2(indirect block size) */ + grub_uint8_t dn_nlevels; /* 1=dn_blkptr->data blocks */ + grub_uint8_t dn_nblkptr; /* length of dn_blkptr */ + grub_uint8_t dn_bonustype; /* type of data in bonus buffer */ + grub_uint8_t dn_checksum; /* ZIO_CHECKSUM type */ + grub_uint8_t dn_compress; /* ZIO_COMPRESS type */ + grub_uint8_t dn_flags; /* DNODE_FLAG_* */ + grub_uint16_t dn_datablkszsec; /* data block size in 512b sectors */ + grub_uint16_t dn_bonuslen; /* length of dn_bonus */ + grub_uint8_t dn_pad2[4]; + + /* accounting is protected by dn_dirty_mtx */ + grub_uint64_t dn_maxblkid; /* largest allocated block ID */ + grub_uint64_t dn_used; /* bytes (or sectors) of disk space */ + + grub_uint64_t dn_pad3[4]; + + blkptr_t dn_blkptr[1]; + grub_uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)]; + blkptr_t dn_spill; +} dnode_phys_t; + +#endif /* _SYS_DNODE_H */ diff --git a/include/grub/zfs/dsl_dataset.h b/include/grub/zfs/dsl_dataset.h new file mode 100644 index 000000000..de0dc54a8 --- /dev/null +++ b/include/grub/zfs/dsl_dataset.h @@ -0,0 +1,53 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_DSL_DATASET_H +#define _SYS_DSL_DATASET_H + +typedef struct dsl_dataset_phys { + grub_uint64_t ds_dir_obj; + grub_uint64_t ds_prev_snap_obj; + grub_uint64_t ds_prev_snap_txg; + grub_uint64_t ds_next_snap_obj; + grub_uint64_t ds_snapnames_zapobj; /* zap obj of snaps; ==0 for snaps */ + grub_uint64_t ds_num_children; /* clone/snap children; ==0 for head */ + grub_uint64_t ds_creation_time; /* seconds since 1970 */ + grub_uint64_t ds_creation_txg; + grub_uint64_t ds_deadlist_obj; + grub_uint64_t ds_used_bytes; + grub_uint64_t ds_compressed_bytes; + grub_uint64_t ds_uncompressed_bytes; + grub_uint64_t ds_unique_bytes; /* only relevant to snapshots */ + /* + * The ds_fsid_guid is a 56-bit ID that can change to avoid + * collisions. The ds_guid is a 64-bit ID that will never + * change, so there is a small probability that it will collide. + */ + grub_uint64_t ds_fsid_guid; + grub_uint64_t ds_guid; + grub_uint64_t ds_flags; + blkptr_t ds_bp; + grub_uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */ +} dsl_dataset_phys_t; + +#endif /* _SYS_DSL_DATASET_H */ diff --git a/include/grub/zfs/dsl_dir.h b/include/grub/zfs/dsl_dir.h new file mode 100644 index 000000000..717f3592b --- /dev/null +++ b/include/grub/zfs/dsl_dir.h @@ -0,0 +1,49 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_DSL_DIR_H +#define _SYS_DSL_DIR_H + +typedef struct dsl_dir_phys { + grub_uint64_t dd_creation_time; /* not actually used */ + grub_uint64_t dd_head_dataset_obj; + grub_uint64_t dd_parent_obj; + grub_uint64_t dd_clone_parent_obj; + grub_uint64_t dd_child_dir_zapobj; + /* + * how much space our children are accounting for; for leaf + * datasets, == physical space used by fs + snaps + */ + grub_uint64_t dd_used_bytes; + grub_uint64_t dd_compressed_bytes; + grub_uint64_t dd_uncompressed_bytes; + /* Administrative quota setting */ + grub_uint64_t dd_quota; + /* Administrative reservation setting */ + grub_uint64_t dd_reserved; + grub_uint64_t dd_props_zapobj; + grub_uint64_t dd_deleg_zapobj; /* dataset permissions */ + grub_uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */ +} dsl_dir_phys_t; + +#endif /* _SYS_DSL_DIR_H */ diff --git a/include/grub/zfs/sa_impl.h b/include/grub/zfs/sa_impl.h new file mode 100644 index 000000000..8aa6e2e08 --- /dev/null +++ b/include/grub/zfs/sa_impl.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#ifndef _SYS_SA_IMPL_H +#define _SYS_SA_IMPL_H + +typedef struct sa_hdr_phys { + grub_uint32_t sa_magic; + grub_uint16_t sa_layout_info; + grub_uint16_t sa_lengths[1]; +} sa_hdr_phys_t; + +#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0) +#define SA_SIZE_OFFSET 0x8 + +#endif /* _SYS_SA_IMPL_H */ diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h new file mode 100644 index 000000000..36b8e6708 --- /dev/null +++ b/include/grub/zfs/spa.h @@ -0,0 +1,312 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright 2010 Sun Microsystems, Inc. + * Copyright (C) 2009 Vladimir Serbinenko + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef GRUB_ZFS_SPA_HEADER +#define GRUB_ZFS_SPA_HEADER 1 + +typedef enum grub_zfs_endian + { + UNKNOWN_ENDIAN = -2, + LITTLE_ENDIAN = -1, + BIG_ENDIAN = 0 + } grub_zfs_endian_t; + +#define grub_zfs_to_cpu16(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu16(x) \ + : grub_le_to_cpu16(x)) +#define grub_cpu_to_zfs16(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be16(x) \ + : grub_cpu_to_le16(x)) + +#define grub_zfs_to_cpu32(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu32(x) \ + : grub_le_to_cpu32(x)) +#define grub_cpu_to_zfs32(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be32(x) \ + : grub_cpu_to_le32(x)) + +#define grub_zfs_to_cpu64(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu64(x) \ + : grub_le_to_cpu64(x)) +#define grub_cpu_to_zfs64(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be64(x) \ + : grub_cpu_to_le64(x)) + +/* + * General-purpose 32-bit and 64-bit bitfield encodings. + */ +#define BF32_DECODE(x, low, len) P2PHASE((x) >> (low), 1U << (len)) +#define BF64_DECODE(x, low, len) P2PHASE((x) >> (low), 1ULL << (len)) +#define BF32_ENCODE(x, low, len) (P2PHASE((x), 1U << (len)) << (low)) +#define BF64_ENCODE(x, low, len) (P2PHASE((x), 1ULL << (len)) << (low)) + +#define BF32_GET(x, low, len) BF32_DECODE(x, low, len) +#define BF64_GET(x, low, len) BF64_DECODE(x, low, len) + +#define BF32_SET(x, low, len, val) \ + ((x) ^= BF32_ENCODE((x >> low) ^ (val), low, len)) +#define BF64_SET(x, low, len, val) \ + ((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len)) + +#define BF32_GET_SB(x, low, len, shift, bias) \ + ((BF32_GET(x, low, len) + (bias)) << (shift)) +#define BF64_GET_SB(x, low, len, shift, bias) \ + ((BF64_GET(x, low, len) + (bias)) << (shift)) + +#define BF32_SET_SB(x, low, len, shift, bias, val) \ + BF32_SET(x, low, len, ((val) >> (shift)) - (bias)) +#define BF64_SET_SB(x, low, len, shift, bias, val) \ + BF64_SET(x, low, len, ((val) >> (shift)) - (bias)) + +/* + * We currently support nine block sizes, from 512 bytes to 128K. + * We could go higher, but the benefits are near-zero and the cost + * of COWing a giant block to modify one byte would become excessive. + */ +#define SPA_MINBLOCKSHIFT 9 +#define SPA_MAXBLOCKSHIFT 17 +#define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) +#define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) + +#define SPA_BLOCKSIZES (SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1) + +/* + * Size of block to hold the configuration data (a packed nvlist) + */ +#define SPA_CONFIG_BLOCKSIZE (1 << 14) + +/* + * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. + * The ASIZE encoding should be at least 64 times larger (6 more bits) + * to support up to 4-way RAID-Z mirror mode with worst-case gang block + * overhead, three DVAs per bp, plus one more bit in case we do anything + * else that expands the ASIZE. + */ +#define SPA_LSIZEBITS 16 /* LSIZE up to 32M (2^16 * 512) */ +#define SPA_PSIZEBITS 16 /* PSIZE up to 32M (2^16 * 512) */ +#define SPA_ASIZEBITS 24 /* ASIZE up to 64 times larger */ + +/* + * All SPA data is represented by 128-bit data virtual addresses (DVAs). + * The members of the dva_t should be considered opaque outside the SPA. + */ +typedef struct dva { + grub_uint64_t dva_word[2]; +} dva_t; + +/* + * Each block has a 256-bit checksum -- strong enough for cryptographic hashes. + */ +typedef struct zio_cksum { + grub_uint64_t zc_word[4]; +} zio_cksum_t; + +/* + * Each block is described by its DVAs, time of birth, checksum, etc. + * The word-by-word, bit-by-bit layout of the blkptr is as follows: + * + * 64 56 48 40 32 24 16 8 0 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 0 | vdev1 | GRID | ASIZE | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 1 |G| offset1 | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 2 | vdev2 | GRID | ASIZE | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 3 |G| offset2 | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 4 | vdev3 | GRID | ASIZE | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 5 |G| offset3 | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 6 |BDX|lvl| type | cksum | comp | PSIZE | LSIZE | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 7 | padding | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 8 | padding | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * 9 | physical birth txg | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * a | logical birth txg | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * b | fill count | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * c | checksum[0] | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * d | checksum[1] | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * e | checksum[2] | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * f | checksum[3] | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * + * Legend: + * + * vdev virtual device ID + * offset offset into virtual device + * LSIZE logical size + * PSIZE physical size (after compression) + * ASIZE allocated size (including RAID-Z parity and gang block headers) + * GRID RAID-Z layout information (reserved for future use) + * cksum checksum function + * comp compression function + * G gang block indicator + * B byteorder (endianness) + * D dedup + * X unused + * lvl level of indirection + * type DMU object type + * phys birth txg of block allocation; zero if same as logical birth txg + * log. birth transaction group in which the block was logically born + * fill count number of non-zero blocks under this bp + * checksum[4] 256-bit checksum of the data this bp describes + */ +#define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */ +#define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */ + +typedef struct blkptr { + dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */ + grub_uint64_t blk_prop; /* size, compression, type, etc */ + grub_uint64_t blk_pad[2]; /* Extra space for the future */ + grub_uint64_t blk_phys_birth; /* txg when block was allocated */ + grub_uint64_t blk_birth; /* transaction group at birth */ + grub_uint64_t blk_fill; /* fill count */ + zio_cksum_t blk_cksum; /* 256-bit checksum */ +} blkptr_t; + +/* + * Macros to get and set fields in a bp or DVA. + */ +#define DVA_GET_ASIZE(dva) \ + BF64_GET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0) +#define DVA_SET_ASIZE(dva, x) \ + BF64_SET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0, x) + +#define DVA_GET_GRID(dva) BF64_GET((dva)->dva_word[0], 24, 8) +#define DVA_SET_GRID(dva, x) BF64_SET((dva)->dva_word[0], 24, 8, x) + +#define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32) +#define DVA_SET_VDEV(dva, x) BF64_SET((dva)->dva_word[0], 32, 32, x) + +#define DVA_GET_GANG(dva) BF64_GET((dva)->dva_word[1], 63, 1) +#define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x) + +#define BP_GET_LSIZE(bp) \ + BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1) +#define BP_SET_LSIZE(bp, x) \ + BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x) + +#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 8) +#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 8, x) + +#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8) +#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x) + +#define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8) +#define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x) + +#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5) +#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x) + +#define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1) +#define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x) + +#define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1) +#define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x) + +#define BP_GET_BYTEORDER(bp) (0 - BF64_GET((bp)->blk_prop, 63, 1)) +#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x) + +#define BP_PHYSICAL_BIRTH(bp) \ + ((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth) + +#define BP_SET_BIRTH(bp, logical, physical) \ +{ \ + (bp)->blk_birth = (logical); \ + (bp)->blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \ +} + +#define BP_GET_ASIZE(bp) \ + (DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ + DVA_GET_ASIZE(&(bp)->blk_dva[2])) + +#define BP_GET_UCSIZE(bp) \ + ((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \ + BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp)); + +#define BP_GET_NDVAS(bp) \ + (!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \ + !!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ + !!DVA_GET_ASIZE(&(bp)->blk_dva[2])) + +#define BP_COUNT_GANG(bp) \ + (DVA_GET_GANG(&(bp)->blk_dva[0]) + \ + DVA_GET_GANG(&(bp)->blk_dva[1]) + \ + DVA_GET_GANG(&(bp)->blk_dva[2])) + +#define DVA_EQUAL(dva1, dva2) \ + ((dva1)->dva_word[1] == (dva2)->dva_word[1] && \ + (dva1)->dva_word[0] == (dva2)->dva_word[0]) + +#define BP_EQUAL(bp1, bp2) \ + (BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) && \ + DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) && \ + DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) && \ + DVA_EQUAL(&(bp1)->blk_dva[2], &(bp2)->blk_dva[2])) + +#define ZIO_CHECKSUM_EQUAL(zc1, zc2) \ + (0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \ + ((zc1).zc_word[1] - (zc2).zc_word[1]) | \ + ((zc1).zc_word[2] - (zc2).zc_word[2]) | \ + ((zc1).zc_word[3] - (zc2).zc_word[3]))) + +#define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0) + +#define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \ +{ \ + (zcp)->zc_word[0] = w0; \ + (zcp)->zc_word[1] = w1; \ + (zcp)->zc_word[2] = w2; \ + (zcp)->zc_word[3] = w3; \ +} + +#define BP_IDENTITY(bp) (&(bp)->blk_dva[0]) +#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp)) +#define BP_IS_HOLE(bp) ((bp)->blk_birth == 0) + +/* BP_IS_RAIDZ(bp) assumes no block compression */ +#define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \ + BP_GET_PSIZE(bp)) + +#define BP_ZERO(bp) \ +{ \ + (bp)->blk_dva[0].dva_word[0] = 0; \ + (bp)->blk_dva[0].dva_word[1] = 0; \ + (bp)->blk_dva[1].dva_word[0] = 0; \ + (bp)->blk_dva[1].dva_word[1] = 0; \ + (bp)->blk_dva[2].dva_word[0] = 0; \ + (bp)->blk_dva[2].dva_word[1] = 0; \ + (bp)->blk_prop = 0; \ + (bp)->blk_pad[0] = 0; \ + (bp)->blk_pad[1] = 0; \ + (bp)->blk_phys_birth = 0; \ + (bp)->blk_birth = 0; \ + (bp)->blk_fill = 0; \ + ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \ +} + +#define BP_SPRINTF_LEN 320 + +#endif /* ! GRUB_ZFS_SPA_HEADER */ diff --git a/include/grub/zfs/uberblock_impl.h b/include/grub/zfs/uberblock_impl.h new file mode 100644 index 000000000..9afc565c9 --- /dev/null +++ b/include/grub/zfs/uberblock_impl.h @@ -0,0 +1,61 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_UBERBLOCK_IMPL_H +#define _SYS_UBERBLOCK_IMPL_H + +/* + * The uberblock version is incremented whenever an incompatible on-disk + * format change is made to the SPA, DMU, or ZAP. + * + * Note: the first two fields should never be moved. When a storage pool + * is opened, the uberblock must be read off the disk before the version + * can be checked. If the ub_version field is moved, we may not detect + * version mismatch. If the ub_magic field is moved, applications that + * expect the magic number in the first word won't work. + */ +#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */ +#define UBERBLOCK_SHIFT 10 /* up to 1K */ + +typedef struct uberblock { + grub_uint64_t ub_magic; /* UBERBLOCK_MAGIC */ + grub_uint64_t ub_version; /* ZFS_VERSION */ + grub_uint64_t ub_txg; /* txg of last sync */ + grub_uint64_t ub_guid_sum; /* sum of all vdev guids */ + grub_uint64_t ub_timestamp; /* UTC time of last sync */ + blkptr_t ub_rootbp; /* MOS objset_phys_t */ +} uberblock_t; + +#define UBERBLOCK_SIZE (1ULL << UBERBLOCK_SHIFT) +#define VDEV_UBERBLOCK_SHIFT UBERBLOCK_SHIFT + +/* XXX Uberblock_phys_t is no longer in the kernel zfs */ +typedef struct uberblock_phys { + uberblock_t ubp_uberblock; + char ubp_pad[UBERBLOCK_SIZE - sizeof (uberblock_t) - + sizeof (zio_eck_t)]; + zio_eck_t ubp_zec; +} uberblock_phys_t; + + +#endif /* _SYS_UBERBLOCK_IMPL_H */ diff --git a/include/grub/zfs/vdev_impl.h b/include/grub/zfs/vdev_impl.h new file mode 100644 index 000000000..6e9002ffc --- /dev/null +++ b/include/grub/zfs/vdev_impl.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_VDEV_IMPL_H +#define _SYS_VDEV_IMPL_H + +#define VDEV_SKIP_SIZE (8 << 10) +#define VDEV_BOOT_HEADER_SIZE (8 << 10) +#define VDEV_PHYS_SIZE (112 << 10) +#define VDEV_UBERBLOCK_RING (128 << 10) + +/* ZFS boot block */ +#define VDEV_BOOT_MAGIC 0x2f5b007b10cULL +#define VDEV_BOOT_VERSION 1 /* version number */ + +typedef struct vdev_boot_header { + grub_uint64_t vb_magic; /* VDEV_BOOT_MAGIC */ + grub_uint64_t vb_version; /* VDEV_BOOT_VERSION */ + grub_uint64_t vb_offset; /* start offset (bytes) */ + grub_uint64_t vb_size; /* size (bytes) */ + char vb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof (grub_uint64_t)]; +} vdev_boot_header_t; + +typedef struct vdev_phys { + char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)]; + zio_eck_t vp_zbt; +} vdev_phys_t; + +typedef struct vdev_label { + char vl_pad[VDEV_SKIP_SIZE]; /* 8K */ + vdev_boot_header_t vl_boot_header; /* 8K */ + vdev_phys_t vl_vdev_phys; /* 112K */ + char vl_uberblock[VDEV_UBERBLOCK_RING]; /* 128K */ +} vdev_label_t; /* 256K total */ + +/* + * Size and offset of embedded boot loader region on each label. + * The total size of the first two labels plus the boot area is 4MB. + */ +#define VDEV_BOOT_OFFSET (2 * sizeof (vdev_label_t)) +#define VDEV_BOOT_SIZE (7ULL << 19) /* 3.5M */ + +/* + * Size of label regions at the start and end of each leaf device. + */ +#define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE) +#define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t)) +#define VDEV_LABELS 4 + +#endif /* _SYS_VDEV_IMPL_H */ diff --git a/include/grub/zfs/zap_impl.h b/include/grub/zfs/zap_impl.h new file mode 100644 index 000000000..b229a0657 --- /dev/null +++ b/include/grub/zfs/zap_impl.h @@ -0,0 +1,112 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_ZAP_IMPL_H +#define _SYS_ZAP_IMPL_H + +#define ZAP_MAGIC 0x2F52AB2ABULL + +#define ZAP_HASHBITS 28 +#define MZAP_ENT_LEN 64 +#define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2) +#define MZAP_MAX_BLKSHIFT SPA_MAXBLOCKSHIFT +#define MZAP_MAX_BLKSZ (1 << MZAP_MAX_BLKSHIFT) + +typedef struct mzap_ent_phys { + grub_uint64_t mze_value; + grub_uint32_t mze_cd; + grub_uint16_t mze_pad; /* in case we want to chain them someday */ + char mze_name[MZAP_NAME_LEN]; +} mzap_ent_phys_t; + +typedef struct mzap_phys { + grub_uint64_t mz_block_type; /* ZBT_MICRO */ + grub_uint64_t mz_salt; + grub_uint64_t mz_pad[6]; + mzap_ent_phys_t mz_chunk[1]; + /* actually variable size depending on block size */ +} mzap_phys_t; + +/* + * The (fat) zap is stored in one object. It is an array of + * 1<= 6] [zap_leaf_t] [ptrtbl] ... + * + */ + +#define ZBT_LEAF ((1ULL << 63) + 0) +#define ZBT_HEADER ((1ULL << 63) + 1) +#define ZBT_MICRO ((1ULL << 63) + 3) +/* any other values are ptrtbl blocks */ + +/* + * the embedded pointer table takes up half a block: + * block size / entry size (2^3) / 2 + */ +#define ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1) + +/* + * The embedded pointer table starts half-way through the block. Since + * the pointer table itself is half the block, it starts at (64-bit) + * word number (1<zap_f.zap_phys) \ + [(idx) + (1< + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +#ifndef GRUB_ZFS_HEADER +#define GRUB_ZFS_HEADER 1 + +#include +#include + +/* + * On-disk version number. + */ +#define SPA_VERSION 28ULL + +/* + * The following are configuration names used in the nvlist describing a pool's + * configuration. + */ +#define ZPOOL_CONFIG_VERSION "version" +#define ZPOOL_CONFIG_POOL_NAME "name" +#define ZPOOL_CONFIG_POOL_STATE "state" +#define ZPOOL_CONFIG_POOL_TXG "txg" +#define ZPOOL_CONFIG_POOL_GUID "pool_guid" +#define ZPOOL_CONFIG_CREATE_TXG "create_txg" +#define ZPOOL_CONFIG_TOP_GUID "top_guid" +#define ZPOOL_CONFIG_VDEV_TREE "vdev_tree" +#define ZPOOL_CONFIG_TYPE "type" +#define ZPOOL_CONFIG_CHILDREN "children" +#define ZPOOL_CONFIG_ID "id" +#define ZPOOL_CONFIG_GUID "guid" +#define ZPOOL_CONFIG_PATH "path" +#define ZPOOL_CONFIG_DEVID "devid" +#define ZPOOL_CONFIG_METASLAB_ARRAY "metaslab_array" +#define ZPOOL_CONFIG_METASLAB_SHIFT "metaslab_shift" +#define ZPOOL_CONFIG_ASHIFT "ashift" +#define ZPOOL_CONFIG_ASIZE "asize" +#define ZPOOL_CONFIG_DTL "DTL" +#define ZPOOL_CONFIG_STATS "stats" +#define ZPOOL_CONFIG_WHOLE_DISK "whole_disk" +#define ZPOOL_CONFIG_ERRCOUNT "error_count" +#define ZPOOL_CONFIG_NOT_PRESENT "not_present" +#define ZPOOL_CONFIG_SPARES "spares" +#define ZPOOL_CONFIG_IS_SPARE "is_spare" +#define ZPOOL_CONFIG_NPARITY "nparity" +#define ZPOOL_CONFIG_PHYS_PATH "phys_path" +#define ZPOOL_CONFIG_L2CACHE "l2cache" +#define ZPOOL_CONFIG_HOLE_ARRAY "hole_array" +#define ZPOOL_CONFIG_VDEV_CHILDREN "vdev_children" +#define ZPOOL_CONFIG_IS_HOLE "is_hole" +#define ZPOOL_CONFIG_DDT_HISTOGRAM "ddt_histogram" +#define ZPOOL_CONFIG_DDT_OBJ_STATS "ddt_object_stats" +#define ZPOOL_CONFIG_DDT_STATS "ddt_stats" +/* + * The persistent vdev state is stored as separate values rather than a single + * 'vdev_state' entry. This is because a device can be in multiple states, such + * as offline and degraded. + */ +#define ZPOOL_CONFIG_OFFLINE "offline" +#define ZPOOL_CONFIG_FAULTED "faulted" +#define ZPOOL_CONFIG_DEGRADED "degraded" +#define ZPOOL_CONFIG_REMOVED "removed" + +#define VDEV_TYPE_ROOT "root" +#define VDEV_TYPE_MIRROR "mirror" +#define VDEV_TYPE_REPLACING "replacing" +#define VDEV_TYPE_RAIDZ "raidz" +#define VDEV_TYPE_DISK "disk" +#define VDEV_TYPE_FILE "file" +#define VDEV_TYPE_MISSING "missing" +#define VDEV_TYPE_HOLE "hole" +#define VDEV_TYPE_SPARE "spare" +#define VDEV_TYPE_L2CACHE "l2cache" + +/* + * pool state. The following states are written to disk as part of the normal + * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE, L2CACHE. The remaining + * states are software abstractions used at various levels to communicate pool + * state. + */ +typedef enum pool_state { + POOL_STATE_ACTIVE = 0, /* In active use */ + POOL_STATE_EXPORTED, /* Explicitly exported */ + POOL_STATE_DESTROYED, /* Explicitly destroyed */ + POOL_STATE_SPARE, /* Reserved for hot spare use */ + POOL_STATE_L2CACHE, /* Level 2 ARC device */ + POOL_STATE_UNINITIALIZED, /* Internal spa_t state */ + POOL_STATE_UNAVAIL, /* Internal libzfs state */ + POOL_STATE_POTENTIALLY_ACTIVE /* Internal libzfs state */ +} pool_state_t; + +struct grub_zfs_data; + +grub_err_t grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist); +grub_err_t grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, + grub_uint64_t *mdnobj); + +char *grub_zfs_nvlist_lookup_string (char *nvlist, char *name); +char *grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name); +int grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, + grub_uint64_t *out); +char *grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, + grub_size_t index); +int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name); + +#endif /* ! GRUB_ZFS_HEADER */ diff --git a/include/grub/zfs/zfs_acl.h b/include/grub/zfs/zfs_acl.h new file mode 100644 index 000000000..65d3fdadc --- /dev/null +++ b/include/grub/zfs/zfs_acl.h @@ -0,0 +1,60 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_FS_ZFS_ACL_H +#define _SYS_FS_ZFS_ACL_H + +#ifndef _UID_T +#define _UID_T +typedef unsigned int uid_t; /* UID type */ +#endif /* _UID_T */ + +typedef struct zfs_oldace { + grub_uint32_t z_fuid; /* "who" */ + grub_uint32_t z_access_mask; /* access mask */ + grub_uint16_t z_flags; /* flags, i.e inheritance */ + grub_uint16_t z_type; /* type of entry allow/deny */ +} zfs_oldace_t; + +#define ACE_SLOT_CNT 6 + +typedef struct zfs_znode_acl_v0 { + grub_uint64_t z_acl_extern_obj; /* ext acl pieces */ + grub_uint32_t z_acl_count; /* Number of ACEs */ + grub_uint16_t z_acl_version; /* acl version */ + grub_uint16_t z_acl_pad; /* pad */ + zfs_oldace_t z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */ +} zfs_znode_acl_v0_t; + +#define ZFS_ACE_SPACE (sizeof (zfs_oldace_t) * ACE_SLOT_CNT) + +typedef struct zfs_znode_acl { + grub_uint64_t z_acl_extern_obj; /* ext acl pieces */ + grub_uint32_t z_acl_size; /* Number of bytes in ACL */ + grub_uint16_t z_acl_version; /* acl version */ + grub_uint16_t z_acl_count; /* ace count */ + grub_uint8_t z_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */ +} zfs_znode_acl_t; + + +#endif /* _SYS_FS_ZFS_ACL_H */ diff --git a/include/grub/zfs/zfs_znode.h b/include/grub/zfs/zfs_znode.h new file mode 100644 index 000000000..87bc3f9fc --- /dev/null +++ b/include/grub/zfs/zfs_znode.h @@ -0,0 +1,71 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_FS_ZFS_ZNODE_H +#define _SYS_FS_ZFS_ZNODE_H + +#include + +#define MASTER_NODE_OBJ 1 +#define ZFS_ROOT_OBJ "ROOT" +#define ZPL_VERSION_STR "VERSION" +#define ZFS_SA_ATTRS "SA_ATTRS" + +#define ZPL_VERSION 5ULL + +#define ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48) + +/* + * This is the persistent portion of the znode. It is stored + * in the "bonus buffer" of the file. Short symbolic links + * are also stored in the bonus buffer. + */ +typedef struct znode_phys { + grub_uint64_t zp_atime[2]; /* 0 - last file access time */ + grub_uint64_t zp_mtime[2]; /* 16 - last file modification time */ + grub_uint64_t zp_ctime[2]; /* 32 - last file change time */ + grub_uint64_t zp_crtime[2]; /* 48 - creation time */ + grub_uint64_t zp_gen; /* 64 - generation (txg of creation) */ + grub_uint64_t zp_mode; /* 72 - file mode bits */ + grub_uint64_t zp_size; /* 80 - size of file */ + grub_uint64_t zp_parent; /* 88 - directory parent (`..') */ + grub_uint64_t zp_links; /* 96 - number of links to file */ + grub_uint64_t zp_xattr; /* 104 - DMU object for xattrs */ + grub_uint64_t zp_rdev; /* 112 - dev_t for VBLK & VCHR files */ + grub_uint64_t zp_flags; /* 120 - persistent flags */ + grub_uint64_t zp_uid; /* 128 - file owner */ + grub_uint64_t zp_gid; /* 136 - owning group */ + grub_uint64_t zp_pad[4]; /* 144 - future */ + zfs_znode_acl_t zp_acl; /* 176 - 263 ACL */ + /* + * Data may pad out any remaining bytes in the znode buffer, eg: + * + * |<---------------------- dnode_phys (512) ------------------------>| + * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->| + * |<---- znode (264) ---->|<---- data (56) ---->| + * + * At present, we only use this space to store symbolic links. + */ +} znode_phys_t; + +#endif /* _SYS_FS_ZFS_ZNODE_H */ diff --git a/include/grub/zfs/zil.h b/include/grub/zfs/zil.h new file mode 100644 index 000000000..4ae8daf63 --- /dev/null +++ b/include/grub/zfs/zil.h @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_ZIL_H +#define _SYS_ZIL_H + +/* + * Intent log format: + * + * Each objset has its own intent log. The log header (zil_header_t) + * for objset N's intent log is kept in the Nth object of the SPA's + * intent_log objset. The log header points to a chain of log blocks, + * each of which contains log records (i.e., transactions) followed by + * a log block trailer (zil_trailer_t). The format of a log record + * depends on the record (or transaction) type, but all records begin + * with a common structure that defines the type, length, and txg. + */ + +/* + * Intent log header - this on disk structure holds fields to manage + * the log. All fields are 64 bit to easily handle cross architectures. + */ +typedef struct zil_header { + grub_uint64_t zh_claim_txg; /* txg in which log blocks were claimed */ + grub_uint64_t zh_replay_seq; /* highest replayed sequence number */ + blkptr_t zh_log; /* log chain */ + grub_uint64_t zh_claim_seq; /* highest claimed sequence number */ + grub_uint64_t zh_flags; /* header flags */ + grub_uint64_t zh_pad[4]; +} zil_header_t; + +/* + * zh_flags bit settings + */ +#define ZIL_REPLAY_NEEDED 0x1 /* replay needed - internal only */ + +#endif /* _SYS_ZIL_H */ diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h new file mode 100644 index 000000000..2b177a2ce --- /dev/null +++ b/include/grub/zfs/zio.h @@ -0,0 +1,85 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _ZIO_H +#define _ZIO_H + +#include + +#define ZEC_MAGIC 0x210da7ab10c7a11ULL /* zio data bloc tail */ + +typedef struct zio_eck { + grub_uint64_t zec_magic; /* for validation, endianness */ + zio_cksum_t zec_cksum; /* 256-bit checksum */ +} zio_eck_t; + +/* + * Gang block headers are self-checksumming and contain an array + * of block pointers. + */ +#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE +#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ + sizeof (zio_eck_t)) / sizeof (blkptr_t)) +#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ + sizeof (zio_eck_t) - \ + (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ + sizeof (grub_uint64_t)) + +#define ZIO_GET_IOSIZE(zio) \ + (BP_IS_GANG((zio)->io_bp) ? \ + SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)->io_bp)) + +typedef struct zio_gbh { + blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; + grub_uint64_t zg_filler[SPA_GBH_FILLER]; + zio_eck_t zg_tail; +} zio_gbh_phys_t; + +enum zio_checksum { + ZIO_CHECKSUM_INHERIT = 0, + ZIO_CHECKSUM_ON, + ZIO_CHECKSUM_OFF, + ZIO_CHECKSUM_LABEL, + ZIO_CHECKSUM_GANG_HEADER, + ZIO_CHECKSUM_ZILOG, + ZIO_CHECKSUM_FLETCHER_2, + ZIO_CHECKSUM_FLETCHER_4, + ZIO_CHECKSUM_SHA256, + ZIO_CHECKSUM_ZILOG2, + ZIO_CHECKSUM_FUNCTIONS +}; + +#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_2 +#define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON + +enum zio_compress { + ZIO_COMPRESS_INHERIT = 0, + ZIO_COMPRESS_ON, + ZIO_COMPRESS_OFF, + ZIO_COMPRESS_LZJB, + ZIO_COMPRESS_EMPTY, + ZIO_COMPRESS_GZIP, + ZIO_COMPRESS_FUNCTIONS +}; + +#endif /* _ZIO_H */ diff --git a/include/grub/zfs/zio_checksum.h b/include/grub/zfs/zio_checksum.h new file mode 100644 index 000000000..b4d6382af --- /dev/null +++ b/include/grub/zfs/zio_checksum.h @@ -0,0 +1,50 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_ZIO_CHECKSUM_H +#define _SYS_ZIO_CHECKSUM_H + +/* + * Signature for checksum functions. + */ +typedef void zio_checksum_t(const void *data, grub_uint64_t size, + grub_zfs_endian_t endian, zio_cksum_t *zcp); + +/* + * Information about each checksum function. + */ +typedef struct zio_checksum_info { + zio_checksum_t *ci_func; /* checksum function for each byteorder */ + int ci_correctable; /* number of correctable bits */ + int ci_eck; /* uses zio embedded checksum? */ + char *ci_name; /* descriptive name */ +} zio_checksum_info_t; + +extern void zio_checksum_SHA256 (const void *, grub_uint64_t, + grub_zfs_endian_t endian, zio_cksum_t *); +extern void fletcher_2 (const void *, grub_uint64_t, grub_zfs_endian_t endian, + zio_cksum_t *); +extern void fletcher_4 (const void *, grub_uint64_t, grub_zfs_endian_t endian, + zio_cksum_t *); + +#endif /* _SYS_ZIO_CHECKSUM_H */ From 54207d4b6cd6f8f262e320e453da9462cd046105 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 1 Dec 2010 22:55:26 +0100 Subject: [PATCH 0427/1414] Update GPL for ZFS code to version 3, move copyright lines for Vladimir and me to FSF (covered by our assignments) --- grub-core/fs/zfs/zfs.c | 11 ++++------- grub-core/fs/zfs/zfs_fletcher.c | 10 ++++------ grub-core/fs/zfs/zfs_lzjb.c | 10 ++++------ grub-core/fs/zfs/zfs_sha256.c | 10 ++++------ grub-core/fs/zfs/zfsinfo.c | 10 ++++------ include/grub/zfs/dmu.h | 9 ++++----- include/grub/zfs/dmu_objset.h | 9 ++++----- include/grub/zfs/dnode.h | 9 ++++----- include/grub/zfs/dsl_dataset.h | 9 ++++----- include/grub/zfs/dsl_dir.h | 9 ++++----- include/grub/zfs/sa_impl.h | 9 ++++----- include/grub/zfs/spa.h | 10 ++++------ include/grub/zfs/uberblock_impl.h | 9 ++++----- include/grub/zfs/vdev_impl.h | 9 ++++----- include/grub/zfs/zap_impl.h | 9 ++++----- include/grub/zfs/zap_leaf.h | 9 ++++----- include/grub/zfs/zfs.h | 10 ++++------ include/grub/zfs/zfs_acl.h | 9 ++++----- include/grub/zfs/zfs_znode.h | 9 ++++----- include/grub/zfs/zil.h | 9 ++++----- include/grub/zfs/zio.h | 9 ++++----- include/grub/zfs/zio_checksum.h | 9 ++++----- 22 files changed, 88 insertions(+), 118 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index ce735a311..8901af76f 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1,23 +1,20 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010 Free Software Foundation, Inc. * Copyright 2010 Sun Microsystems, Inc. - * Copyright (C) 2009 Vladimir Serbinenko - * Copyright (C) 2010 Robert Millan * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * The zfs plug-in routines for GRUB are: diff --git a/grub-core/fs/zfs/zfs_fletcher.c b/grub-core/fs/zfs/zfs_fletcher.c index eaed15a2c..7d27b053d 100644 --- a/grub-core/fs/zfs/zfs_fletcher.c +++ b/grub-core/fs/zfs/zfs_fletcher.c @@ -1,22 +1,20 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. * Copyright 2007 Sun Microsystems, Inc. - * Copyright (C) 2009 Vladimir Serbinenko * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ #include diff --git a/grub-core/fs/zfs/zfs_lzjb.c b/grub-core/fs/zfs/zfs_lzjb.c index 0965d2d1f..62b5ea6a0 100644 --- a/grub-core/fs/zfs/zfs_lzjb.c +++ b/grub-core/fs/zfs/zfs_lzjb.c @@ -1,22 +1,20 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. * Copyright 2007 Sun Microsystems, Inc. - * Copyright (C) 2009 Vladimir Serbinenko * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ #include diff --git a/grub-core/fs/zfs/zfs_sha256.c b/grub-core/fs/zfs/zfs_sha256.c index 3dc79268a..ba510cf69 100644 --- a/grub-core/fs/zfs/zfs_sha256.c +++ b/grub-core/fs/zfs/zfs_sha256.c @@ -1,22 +1,20 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. * Copyright 2007 Sun Microsystems, Inc. - * Copyright (C) 2009 Vladimir Serbinenko * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ #include diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index a9a13507e..33065892a 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -1,22 +1,20 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. * Copyright 2008 Sun Microsystems, Inc. - * Copyright (C) 2009 Vladimir Serbinenko * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ #include diff --git a/include/grub/zfs/dmu.h b/include/grub/zfs/dmu.h index 7faa7088b..bee317e8a 100644 --- a/include/grub/zfs/dmu.h +++ b/include/grub/zfs/dmu.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/dmu_objset.h b/include/grub/zfs/dmu_objset.h index aa1f4ab19..57d21db5c 100644 --- a/include/grub/zfs/dmu_objset.h +++ b/include/grub/zfs/dmu_objset.h @@ -3,19 +3,18 @@ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * Copyright (C) 2010 Robert Millan * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/dnode.h b/include/grub/zfs/dnode.h index 6b0e18427..279c5451e 100644 --- a/include/grub/zfs/dnode.h +++ b/include/grub/zfs/dnode.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/dsl_dataset.h b/include/grub/zfs/dsl_dataset.h index de0dc54a8..c17bf801e 100644 --- a/include/grub/zfs/dsl_dataset.h +++ b/include/grub/zfs/dsl_dataset.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/dsl_dir.h b/include/grub/zfs/dsl_dir.h index 717f3592b..41d77c790 100644 --- a/include/grub/zfs/dsl_dir.h +++ b/include/grub/zfs/dsl_dir.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/sa_impl.h b/include/grub/zfs/sa_impl.h index 8aa6e2e08..a2b728d37 100644 --- a/include/grub/zfs/sa_impl.h +++ b/include/grub/zfs/sa_impl.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h index 36b8e6708..22ee03b15 100644 --- a/include/grub/zfs/spa.h +++ b/include/grub/zfs/spa.h @@ -1,22 +1,20 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. * Copyright 2010 Sun Microsystems, Inc. - * Copyright (C) 2009 Vladimir Serbinenko * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ #ifndef GRUB_ZFS_SPA_HEADER diff --git a/include/grub/zfs/uberblock_impl.h b/include/grub/zfs/uberblock_impl.h index 9afc565c9..1bf7f2b07 100644 --- a/include/grub/zfs/uberblock_impl.h +++ b/include/grub/zfs/uberblock_impl.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/vdev_impl.h b/include/grub/zfs/vdev_impl.h index 6e9002ffc..9b5f0a7a8 100644 --- a/include/grub/zfs/vdev_impl.h +++ b/include/grub/zfs/vdev_impl.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zap_impl.h b/include/grub/zfs/zap_impl.h index b229a0657..e42727ab6 100644 --- a/include/grub/zfs/zap_impl.h +++ b/include/grub/zfs/zap_impl.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zap_leaf.h b/include/grub/zfs/zap_leaf.h index 9734456f0..1ef654054 100644 --- a/include/grub/zfs/zap_leaf.h +++ b/include/grub/zfs/zap_leaf.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 153c28708..057692573 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -1,21 +1,19 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * Copyright (C) 2009 Vladimir Serbinenko + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. diff --git a/include/grub/zfs/zfs_acl.h b/include/grub/zfs/zfs_acl.h index 65d3fdadc..277738279 100644 --- a/include/grub/zfs/zfs_acl.h +++ b/include/grub/zfs/zfs_acl.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zfs_znode.h b/include/grub/zfs/zfs_znode.h index 87bc3f9fc..efd6d10a6 100644 --- a/include/grub/zfs/zfs_znode.h +++ b/include/grub/zfs/zfs_znode.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zil.h b/include/grub/zfs/zil.h index 4ae8daf63..45d16f402 100644 --- a/include/grub/zfs/zil.h +++ b/include/grub/zfs/zil.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 2b177a2ce..797d4f9b3 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. diff --git a/include/grub/zfs/zio_checksum.h b/include/grub/zfs/zio_checksum.h index b4d6382af..0ef5a3ec7 100644 --- a/include/grub/zfs/zio_checksum.h +++ b/include/grub/zfs/zio_checksum.h @@ -2,19 +2,18 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * - * This program is free software; you can redistribute it and/or modify + * 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 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with GRUB. If not, see . */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. From a3d1fcfb1047d9ccc9ca60027766ed886af52cad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 22:59:51 +0100 Subject: [PATCH 0428/1414] Fix 2 warnings --- grub-core/fs/btrfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 65d298e74..2410b4550 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -334,6 +334,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, unsigned i; struct grub_btrfs_internal_node node, node_last; int have_last = 0; + grub_memset (node_last, 0, sizeof (node_last)); for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) { err = grub_btrfs_read_logical (data, disk, addr @@ -752,7 +753,7 @@ grub_btrfs_dir (grub_device_t device, grub_size_t allocated = 0; struct grub_btrfs_dir_item *direl = NULL; struct grub_btrfs_leaf_descriptor desc; - int r; + int r = 0; grub_uint64_t tree; grub_uint8_t type; From ac5dcabe67536ffdb945fbf99426878e458a6ca6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Dec 2010 23:16:19 +0100 Subject: [PATCH 0429/1414] Fix incorrect statement from previous commit --- grub-core/fs/btrfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 2410b4550..67aa768ce 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -334,7 +334,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, unsigned i; struct grub_btrfs_internal_node node, node_last; int have_last = 0; - grub_memset (node_last, 0, sizeof (node_last)); + grub_memset (&node_last, 0, sizeof (node_last)); for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) { err = grub_btrfs_read_logical (data, disk, addr From 1f60e3533163404e2b9e2dc0b98f42ab352b73ac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 00:03:19 +0100 Subject: [PATCH 0430/1414] initialise the type of search for root --- grub-core/fs/btrfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 67aa768ce..6c6a6f9f8 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -622,6 +622,8 @@ find_path (struct grub_btrfs_data *data, *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; *tree = data->sblock.root_tree; key->object_id = data->sblock.root_dir_objectid; + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; while (1) { From 9b4cb862f889a922c23f68f89403b0565d66bbdc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 00:11:14 +0100 Subject: [PATCH 0431/1414] handle directories correctly --- grub-core/fs/btrfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 6c6a6f9f8..1afd8fbb4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -726,9 +726,11 @@ find_path (struct grub_btrfs_data *data, break; } case GRUB_BTRFS_ITEM_TYPE_INODE_ITEM: - if (*slash) + if (*slash && *type == GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); *key = cdirel->key; + if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; break; default: return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", From 93e0c7a7c20dc469e3f30631fdf444d96f07d85b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 13:23:20 +0100 Subject: [PATCH 0432/1414] Fix subvolume handling --- grub-core/fs/btrfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 1afd8fbb4..7ad2d40ff 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -702,13 +702,14 @@ find_path (struct grub_btrfs_data *data, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "symlinks not supported"); } - + switch (cdirel->key.type) { case GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM: { struct grub_btrfs_root_item ri; - err = lower_bound (data, disk, &cdirel->key, &key_out, *tree, + err = lower_bound (data, disk, &cdirel->key, &key_out, + data->sblock.root_tree, &elemaddr, &elemsize, NULL); if (err) return err; From d9865a25f7416678d78b1629444f2d674ff0466f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 13:31:50 +0100 Subject: [PATCH 0433/1414] Implicitly skip /default prefix --- grub-core/fs/btrfs.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7ad2d40ff..dd9e41149 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -611,13 +611,16 @@ find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, grub_uint64_t *tree, grub_uint8_t *type) { - const char *slash; + const char *slash = path; grub_err_t err; grub_disk_addr_t elemaddr; grub_size_t elemsize; grub_size_t allocated = 0; struct grub_btrfs_dir_item *direl = NULL; struct grub_btrfs_key key_out; + int skip_default = 1; + const char *ctoken; + grub_size_t ctokenlen; *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; *tree = data->sblock.root_tree; @@ -627,20 +630,29 @@ find_path (struct grub_btrfs_data *data, while (1) { - while (path[0] == '/') - path++; - if (!path[0]) - break; + if (!skip_default) + { + while (path[0] == '/') + path++; + if (!path[0]) + break; + slash = grub_strchr (path, '/'); + if (!slash) + slash = path + grub_strlen (path); + ctoken = path; + ctokenlen = slash - path; + } + else + { + ctoken = "default"; + ctokenlen = sizeof ("default") - 1; + } if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; - key->offset = 0; - slash = grub_strchr (path, '/'); - if (!slash) - slash = path + grub_strlen (path); - key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, path, slash - path)); + key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); err = lower_bound (data, disk, key, &key_out, *tree, &elemaddr, &elemsize, NULL); @@ -683,7 +695,7 @@ find_path (struct grub_btrfs_data *data, char c; c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; - if (grub_strncmp (cdirel->name, path, slash - path) == 0) + if (grub_strncmp (cdirel->name, ctoken, ctokenlen) == 0) break; cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; } @@ -694,7 +706,9 @@ find_path (struct grub_btrfs_data *data, return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); } - path = slash; + if (!skip_default) + path = slash; + skip_default = 0; *type = cdirel->type; if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) { From eb82b8569ad2e9ffff50669c253c6bda1724b40e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 13:32:24 +0100 Subject: [PATCH 0434/1414] Remove leftover unused attribute --- grub-core/fs/btrfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index dd9e41149..052ef1a93 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -759,8 +759,7 @@ find_path (struct grub_btrfs_data *data, } static grub_err_t -grub_btrfs_dir (grub_device_t device, - const char *path __attribute__ ((unused)), +grub_btrfs_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, const struct grub_dirhook_info *info)) { From 98042add0cded2addc7658afb86beef7535d4910 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 13:57:07 +0100 Subject: [PATCH 0435/1414] Fix handling of non-leaf next --- grub-core/fs/btrfs.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 052ef1a93..d508d75b9 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -215,7 +215,7 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, grub_disk_addr_t addr, unsigned i, unsigned m, int l) { desc->depth++; - if (desc->allocated > desc->depth) + if (desc->allocated < desc->depth) { void *newdata; desc->allocated *= 2; @@ -238,21 +238,17 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, grub_disk_addr_t *outaddr, grub_size_t *outsize, struct grub_btrfs_key *key_out) { - int i; grub_err_t err; struct grub_btrfs_leaf_node leaf; - if (desc->depth == 0) - return 0; - for (i = desc->depth - 1; i >= 0; i--) + for (; desc->depth > 0; desc->depth--) { - desc->data[i].iter++; - if (desc->data[i].iter + desc->data[desc->depth - 1].iter++; + if (desc->data[desc->depth - 1].iter < desc->data[desc->depth - 1].maxiter) break; - desc->depth--; } - if (i == -1) + if (desc->depth == 0) return 0; while (!desc->data[desc->depth - 1].leaf) { @@ -366,13 +362,13 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, } if (have_last) { - addr = grub_le_to_cpu64 (node_last.blockn); err = GRUB_ERR_NONE; if (desc) err = save_ref (desc, addr - sizeof (head), i - 1, grub_le_to_cpu32 (head.nitems), 0); if (err) return err; + addr = grub_le_to_cpu64 (node_last.blockn); goto reiter; } *outsize = 0; From 228cfb40bf9f6fa70cdb6c8aa7304efe9f558870 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 14:26:46 +0100 Subject: [PATCH 0436/1414] support bind and subvolume mount --- grub-core/kern/emu/getroot.c | 23 ++++++++--------------- grub-core/kern/emu/misc.c | 28 ++++++++++++++++++++++++++++ include/grub/emu/misc.h | 2 ++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index f51dcd770..373834127 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -103,8 +103,8 @@ xgetcwd (void) can't deal with the multiple-device case yet, but in the meantime, we can at least cope with the single-device case by scanning /proc/self/mountinfo. */ -static char * -find_root_device_from_mountinfo (const char *dir) +char * +grub_find_root_device_from_mountinfo (const char *dir, char **relroot) { FILE *fp; char *buf = NULL; @@ -115,6 +115,9 @@ find_root_device_from_mountinfo (const char *dir) if (! fp) return NULL; /* fall through to other methods */ + if (relroot) + *relroot = NULL; + while (getline (&buf, &len, fp) > 0) { int mnt_id, parent_mnt_id; @@ -131,9 +134,6 @@ find_root_device_from_mountinfo (const char *dir) &count) < 6) continue; - if (strcmp (enc_root, "/") != 0) - continue; /* only a subtree is mounted */ - enc_path_len = strlen (enc_path); if (strncmp (dir, enc_path, enc_path_len) != 0 || (dir[enc_path_len] && dir[enc_path_len] != '/')) @@ -147,9 +147,6 @@ find_root_device_from_mountinfo (const char *dir) free (ret); ret = NULL; - if (major != 0) - continue; /* not a virtual device */ - sep = strstr (buf + count, " - "); if (!sep) continue; @@ -158,13 +155,9 @@ find_root_device_from_mountinfo (const char *dir) if (sscanf (sep, "%s %s", fstype, device) != 2) continue; - if (stat (device, &st) < 0) - continue; - - if (!S_ISBLK (st.st_mode)) - continue; /* not a block device */ - ret = strdup (device); + if (relroot) + *relroot = strdup (enc_root); } free (buf); @@ -531,7 +524,7 @@ grub_guess_root_device (const char *dir) struct stat st; #ifdef __linux__ - os_dev = find_root_device_from_mountinfo (dir); + os_dev = grub_find_root_device_from_mountinfo (dir, NULL); if (os_dev) return os_dev; #endif /* __linux__ */ diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index c8b95443b..44c40b010 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -415,6 +415,18 @@ grub_make_system_path_relative_to_its_root (const char *path) if (offset == 0) { free (buf); +#ifdef __linux__ + { + char *bind; + grub_free (grub_find_root_device_from_mountinfo (buf2, &bind)); + if (bind && bind[0] && bind[1]) + { + buf3 = bind; + goto parsedir; + } + grub_free (bind); + } +#endif free (buf2); #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) if (poolfs) @@ -437,6 +449,21 @@ grub_make_system_path_relative_to_its_root (const char *path) } free (buf); buf3 = xstrdup (buf2 + offset); + buf2[offset] = 0; +#ifdef __linux__ + { + char *bind; + grub_free (grub_find_root_device_from_mountinfo (buf2, &bind)); + if (bind && bind[0] && bind[1]) + { + char *temp = buf3; + buf3 = grub_xasprintf ("%s%s%s", bind, buf3[0] == '/' ?"":"/", buf3); + grub_free (temp); + } + grub_free (bind); + } +#endif + free (buf2); #ifdef __CYGWIN__ @@ -452,6 +479,7 @@ grub_make_system_path_relative_to_its_root (const char *path) } #endif + parsedir: /* Remove trailing slashes, return empty string if root directory. */ len = strlen (buf3); while (len > 0 && buf3[len - 1] == '/') diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index ef0d18300..d4ebcb0d1 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -78,4 +78,6 @@ extern char * canonicalize_file_name (const char *path); int grub_device_mapper_supported (void); #endif +char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot); + #endif /* GRUB_EMU_MISC_H */ From 8006f6779eed5e840690d86d997bd5dc211713f3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 15:08:46 +0100 Subject: [PATCH 0437/1414] Fix in-extent reading --- grub-core/fs/btrfs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index d508d75b9..ac61452db 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -912,6 +912,7 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) grub_disk_addr_t elemaddr; grub_size_t elemsize; struct grub_btrfs_key key_in, key_out; + grub_off_t extoff; while (len) { @@ -955,6 +956,7 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) grub_le_to_cpu64 (extent->size)); csize = grub_le_to_cpu64 (extent->size) + grub_le_to_cpu64 (key_out.offset) - pos; + extoff = pos - grub_le_to_cpu64 (key_out.offset); if (csize > len) csize = len; @@ -983,7 +985,7 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) switch (extent->type) { case GRUB_BTRFS_EXTENT_INLINE: - grub_memcpy (buf, extent->inl, csize); + grub_memcpy (buf, extent->inl + extoff, csize); grub_free (extent); break; case GRUB_BTRFS_EXTENT_REGULAR: @@ -993,7 +995,8 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) break; } err = grub_btrfs_read_logical (data, file->device->disk, - grub_le_to_cpu64 (extent->laddr), + grub_le_to_cpu64 (extent->laddr) + + extoff, buf, csize); grub_free (extent); if (err) From a43c4bc55f1df3fb5792548bd3045c184f57ab1e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 2 Dec 2010 15:28:29 +0100 Subject: [PATCH 0438/1414] buffer extent for performance --- grub-core/fs/btrfs.c | 106 +++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ac61452db..2e32248b4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -70,6 +70,8 @@ struct grub_btrfs_data unsigned int sblock_number; grub_uint64_t tree; grub_uint64_t inode; + grub_uint64_t extstart; + struct grub_btrfs_extent_data *extent; }; struct grub_btrfs_key @@ -557,7 +559,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, static struct grub_btrfs_data * grub_btrfs_mount (grub_disk_t disk) { - struct grub_btrfs_data *data = grub_malloc (sizeof (*data)); + struct grub_btrfs_data *data = grub_zalloc (sizeof (*data)); unsigned i; grub_err_t err = GRUB_ERR_NONE; @@ -899,7 +901,10 @@ grub_btrfs_open (struct grub_file *file, const char *name) static grub_err_t grub_btrfs_close (grub_file_t file) { - grub_free (file->data); + struct grub_btrfs_data *data = file->data; + + grub_free (data->extent); + grub_free (data); return GRUB_ERR_NONE; } @@ -909,65 +914,63 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_btrfs_data *data = file->data; grub_off_t pos = file->offset; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - struct grub_btrfs_key key_in, key_out; - grub_off_t extoff; while (len) { grub_size_t csize; - struct grub_btrfs_extent_data *extent; grub_err_t err; - key_in.object_id = data->inode; - key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; - key_in.offset = grub_cpu_to_le64 (pos); - err = lower_bound (data, file->device->disk, &key_in, &key_out, - data->tree, - &elemaddr, &elemsize, NULL); - if (err) - return -1; - if (key_out.object_id != data->inode - || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) + grub_off_t extoff; + if (!data->extent || data->extstart > pos || + grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) { - grub_error (GRUB_ERR_BAD_FS, "extent not found"); - return -1; - } - extent = grub_malloc (elemsize); - if (!extent) - return grub_errno; + struct grub_btrfs_key key_in, key_out; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_free (data->extent); + key_in.object_id = data->inode; + key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; + key_in.offset = grub_cpu_to_le64 (pos); + err = lower_bound (data, file->device->disk, &key_in, &key_out, + data->tree, + &elemaddr, &elemsize, NULL); + if (err) + return -1; + if (key_out.object_id != data->inode + || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) + { + grub_error (GRUB_ERR_BAD_FS, "extent not found"); + return -1; + } + data->extstart = grub_le_to_cpu64 (key_out.offset); + data->extent = grub_malloc (elemsize); + if (!data->extent) + return grub_errno; - err = grub_btrfs_read_logical (data, file->device->disk, elemaddr, - extent, elemsize); - if (err) - { - grub_free (extent); - return err; + err = grub_btrfs_read_logical (data, file->device->disk, elemaddr, + data->extent, elemsize); + if (err) + return err; + if (grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) + return grub_error (GRUB_ERR_BAD_FS, "extent not found"); + grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" + PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (key_out.offset), + grub_le_to_cpu64 (data->extent->size)); } - if (grub_le_to_cpu64 (extent->size) + grub_le_to_cpu64 (key_out.offset) - <= pos) - { - grub_free (extent); - return grub_error (GRUB_ERR_BAD_FS, "extent not found"); - } - grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" - PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (key_out.offset), - grub_le_to_cpu64 (extent->size)); - csize = grub_le_to_cpu64 (extent->size) - + grub_le_to_cpu64 (key_out.offset) - pos; - extoff = pos - grub_le_to_cpu64 (key_out.offset); + csize = grub_le_to_cpu64 (data->extent->size) + + grub_le_to_cpu64 (data->extstart) - pos; + extoff = pos - data->extstart; if (csize > len) csize = len; - if (extent->encryption) + if (data->extent->encryption) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encryption not supported"); return -1; } - if (extent->compression) + if (data->extent->compression) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "compression not supported"); @@ -975,37 +978,34 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) } - if (extent->encoding) + if (data->extent->encoding) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encoding not supported"); return -1; } - switch (extent->type) + switch (data->extent->type) { case GRUB_BTRFS_EXTENT_INLINE: - grub_memcpy (buf, extent->inl + extoff, csize); - grub_free (extent); + grub_memcpy (buf, data->extent->inl + extoff, csize); break; case GRUB_BTRFS_EXTENT_REGULAR: - if (!extent->laddr) + if (!data->extent->laddr) { grub_memset (buf, 0, csize); break; } err = grub_btrfs_read_logical (data, file->device->disk, - grub_le_to_cpu64 (extent->laddr) + grub_le_to_cpu64 (data->extent->laddr) + extoff, buf, csize); - grub_free (extent); if (err) return -1; break; default: - grub_free (extent); grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported extent type 0x%x", extent->type); + "unsupported extent type 0x%x", data->extent->type); return -1; } buf += csize; From c53c723762cc4a544346b230eadddd15161b1e26 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 3 Dec 2010 08:55:57 +0530 Subject: [PATCH 0439/1414] print line number on error --- util/grub-script-check.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util/grub-script-check.c b/util/grub-script-check.c index a872a0400..2d1b31c9a 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -73,6 +73,7 @@ main (int argc, char *argv[]) { char *argument; char *input; + int lineno = 0; FILE *file = 0; int verbose = 0; int found_input = 0; @@ -111,6 +112,7 @@ main (int argc, char *argv[]) cmdline[i] = '\0'; } + lineno++; *line = grub_strdup (cmdline); free (cmdline); @@ -189,5 +191,11 @@ main (int argc, char *argv[]) if (file) fclose (file); - return (found_input && script == 0); + if (found_input && script == 0) + { + fprintf (stderr, "error: line no: %u\n", lineno); + return 1; + } + + return 0; } From 34018a7d1fafb91778195fc6aa6970b9aac3ba19 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Dec 2010 10:44:47 +0100 Subject: [PATCH 0440/1414] symlink support --- grub-core/fs/btrfs.c | 367 +++++++++++++++++++++++++++---------------- 1 file changed, 235 insertions(+), 132 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 2e32248b4..5046b8a28 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -70,7 +70,11 @@ struct grub_btrfs_data unsigned int sblock_number; grub_uint64_t tree; grub_uint64_t inode; + + /* Cached extent data. */ grub_uint64_t extstart; + grub_uint64_t extino; + grub_uint64_t exttree; struct grub_btrfs_extent_data *extent; }; @@ -603,6 +607,139 @@ grub_btrfs_mount (grub_disk_t disk) return NULL; } +static grub_err_t +grub_btrfs_read_inode (struct grub_btrfs_data *data, grub_disk_t disk, + struct grub_btrfs_inode *inode, grub_uint64_t num, + grub_uint64_t tree) +{ + struct grub_btrfs_key key_in, key_out; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_err_t err; + + key_in.object_id = num; + key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; + key_in.offset = 0; + + err = lower_bound (data,disk, &key_in, &key_out, tree, + &elemaddr, &elemsize, NULL); + if (err) + return err; + if (num != key_out.object_id + || key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_ITEM) + return grub_error (GRUB_ERR_BAD_FS, "inode not found"); + + return grub_btrfs_read_logical (data, disk, elemaddr, inode, sizeof (*inode)); +} + +static grub_ssize_t +grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_disk_t disk, + grub_uint64_t ino, grub_uint64_t tree, + grub_off_t pos0, char *buf, grub_size_t len) +{ + grub_off_t pos = pos0; + while (len) + { + grub_size_t csize; + grub_err_t err; + grub_off_t extoff; + if (!data->extent || data->extstart > pos || data->extino != ino + || data->exttree != tree + || grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) + { + struct grub_btrfs_key key_in, key_out; + grub_disk_addr_t elemaddr; + grub_size_t elemsize; + grub_free (data->extent); + key_in.object_id = ino; + key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; + key_in.offset = grub_cpu_to_le64 (pos); + err = lower_bound (data, disk, &key_in, &key_out, tree, + &elemaddr, &elemsize, NULL); + if (err) + return -1; + if (key_out.object_id != ino + || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) + { + grub_error (GRUB_ERR_BAD_FS, "extent not found"); + return -1; + } + data->extstart = grub_le_to_cpu64 (key_out.offset); + data->extent = grub_malloc (elemsize); + data->extino = ino; + data->exttree = tree; + if (!data->extent) + return grub_errno; + + err = grub_btrfs_read_logical (data, disk, elemaddr, + data->extent, elemsize); + if (err) + return err; + if (grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) + return grub_error (GRUB_ERR_BAD_FS, "extent not found"); + grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" + PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (key_out.offset), + grub_le_to_cpu64 (data->extent->size)); + } + csize = grub_le_to_cpu64 (data->extent->size) + + grub_le_to_cpu64 (data->extstart) - pos; + extoff = pos - data->extstart; + if (csize > len) + csize = len; + + if (data->extent->encryption) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "encryption not supported"); + return -1; + } + + if (data->extent->compression) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "compression not supported"); + return -1; + } + + + if (data->extent->encoding) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "encoding not supported"); + return -1; + } + + switch (data->extent->type) + { + case GRUB_BTRFS_EXTENT_INLINE: + grub_memcpy (buf, data->extent->inl + extoff, csize); + break; + case GRUB_BTRFS_EXTENT_REGULAR: + if (!data->extent->laddr) + { + grub_memset (buf, 0, csize); + break; + } + err = grub_btrfs_read_logical (data, disk, + grub_le_to_cpu64 (data->extent->laddr) + + extoff, + buf, csize); + if (err) + return -1; + break; + default: + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported extent type 0x%x", data->extent->type); + return -1; + } + buf += csize; + pos += csize; + len -= csize; + } + return pos - pos0; +} + static grub_err_t find_path (struct grub_btrfs_data *data, grub_disk_t disk, @@ -616,15 +753,17 @@ find_path (struct grub_btrfs_data *data, grub_size_t allocated = 0; struct grub_btrfs_dir_item *direl = NULL; struct grub_btrfs_key key_out; - int skip_default = 1; + int skip_default; const char *ctoken; grub_size_t ctokenlen; + char *path_alloc = NULL; *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; *tree = data->sblock.root_tree; key->object_id = data->sblock.root_dir_objectid; key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = 0; + skip_default = 1; while (1) { @@ -647,7 +786,10 @@ find_path (struct grub_btrfs_data *data, } if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + { + grub_free (path_alloc); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); @@ -657,11 +799,13 @@ find_path (struct grub_btrfs_data *data, if (err) { grub_free (direl); + grub_free (path_alloc); return err; } if (key_cmp (key, &key_out) != 0) { grub_free (direl); + grub_free (path_alloc); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); } @@ -672,7 +816,10 @@ find_path (struct grub_btrfs_data *data, grub_free (direl); direl = grub_malloc (allocated + 1); if (!direl) - return grub_errno; + { + grub_free (path_alloc); + return grub_errno; + } } err = grub_btrfs_read_logical (data, disk, elemaddr, @@ -680,6 +827,7 @@ find_path (struct grub_btrfs_data *data, if (err) { grub_free (direl); + grub_free (path_alloc); return err; } @@ -701,19 +849,60 @@ find_path (struct grub_btrfs_data *data, >= (grub_ssize_t) elemsize) { grub_free (direl); + grub_free (path_alloc); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); } if (!skip_default) path = slash; skip_default = 0; - *type = cdirel->type; - if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) + if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) { - grub_free (direl); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "symlinks not supported"); + struct grub_btrfs_inode inode; + char *tmp; + err = grub_btrfs_read_inode (data, disk, &inode, + cdirel->key.object_id, *tree); + if (err) + { + grub_free (direl); + grub_free (path_alloc); + return err; + } + tmp = grub_malloc (grub_le_to_cpu64 (inode.size) + + grub_strlen (path) + 1); + if (!tmp) + { + grub_free (direl); + grub_free (path_alloc); + return grub_errno; + } + + if (grub_btrfs_extent_read (data, disk, cdirel->key.object_id, + *tree, 0, tmp, + grub_le_to_cpu64 (inode.size)) + != (grub_ssize_t) grub_le_to_cpu64 (inode.size)) + { + grub_free (direl); + grub_free (path_alloc); + grub_free (tmp); + return grub_errno; + } + grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, + grub_strlen (path) + 1); + grub_free (path_alloc); + path = path_alloc = tmp; + if (path[0] == '/') + { + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; + *tree = data->sblock.root_tree; + key->object_id = data->sblock.root_dir_objectid; + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->offset = 0; + skip_default = 1; + } + continue; } + *type = cdirel->type; switch (cdirel->key.type) { @@ -724,14 +913,26 @@ find_path (struct grub_btrfs_data *data, data->sblock.root_tree, &elemaddr, &elemsize, NULL); if (err) - return err; + { + grub_free (direl); + grub_free (path_alloc); + return err; + } if (cdirel->key.object_id != key_out.object_id || cdirel->key.type != key_out.type) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + { + grub_free (direl); + grub_free (path_alloc); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + } err = grub_btrfs_read_logical (data, disk, elemaddr, &ri, sizeof (ri)); if (err) - return err; + { + grub_free (direl); + grub_free (path_alloc); + return err; + } key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = 0; key->object_id = GRUB_BTRFS_OBJECT_ID_CHUNK; @@ -740,19 +941,24 @@ find_path (struct grub_btrfs_data *data, } case GRUB_BTRFS_ITEM_TYPE_INODE_ITEM: if (*slash && *type == GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + { + grub_free (direl); + grub_free (path_alloc); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + } *key = cdirel->key; if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; + key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; break; default: + grub_free (path_alloc); + grub_free (direl); return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", cdirel->key.type); } } grub_free (direl); - return GRUB_ERR_NONE; } @@ -857,12 +1063,10 @@ static grub_err_t grub_btrfs_open (struct grub_file *file, const char *name) { struct grub_btrfs_data *data = grub_btrfs_mount (file->device->disk); - struct grub_btrfs_key key_in, key_out; grub_err_t err; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; struct grub_btrfs_inode inode; grub_uint8_t type; + struct grub_btrfs_key key_in; if (!data) return grub_errno; @@ -874,28 +1078,24 @@ grub_btrfs_open (struct grub_file *file, const char *name) return err; } if (type != GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); + { + grub_free (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); + } + data->inode = key_in.object_id; - key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; - - err = lower_bound (data, file->device->disk, &key_in, &key_out, - data->tree, - &elemaddr, &elemsize, NULL); + err = grub_btrfs_read_inode (data, file->device->disk, &inode, data->inode, + data->tree); if (err) - return err; - if (data->inode != key_out.object_id - || key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_ITEM) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); - - err = grub_btrfs_read_logical (data, file->device->disk, elemaddr, - &inode, sizeof (inode)); - if (err) - return err; + { + grub_free (data); + return err; + } file->data = data; file->size = grub_le_to_cpu64 (inode.size); - return GRUB_ERR_NONE; + return err; } static grub_err_t @@ -913,106 +1113,9 @@ static grub_ssize_t grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_btrfs_data *data = file->data; - grub_off_t pos = file->offset; - while (len) - { - grub_size_t csize; - grub_err_t err; - grub_off_t extoff; - if (!data->extent || data->extstart > pos || - grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) - { - struct grub_btrfs_key key_in, key_out; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - grub_free (data->extent); - key_in.object_id = data->inode; - key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; - key_in.offset = grub_cpu_to_le64 (pos); - err = lower_bound (data, file->device->disk, &key_in, &key_out, - data->tree, - &elemaddr, &elemsize, NULL); - if (err) - return -1; - if (key_out.object_id != data->inode - || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) - { - grub_error (GRUB_ERR_BAD_FS, "extent not found"); - return -1; - } - data->extstart = grub_le_to_cpu64 (key_out.offset); - data->extent = grub_malloc (elemsize); - if (!data->extent) - return grub_errno; - - err = grub_btrfs_read_logical (data, file->device->disk, elemaddr, - data->extent, elemsize); - if (err) - return err; - if (grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) - return grub_error (GRUB_ERR_BAD_FS, "extent not found"); - grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" - PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (key_out.offset), - grub_le_to_cpu64 (data->extent->size)); - } - csize = grub_le_to_cpu64 (data->extent->size) - + grub_le_to_cpu64 (data->extstart) - pos; - extoff = pos - data->extstart; - if (csize > len) - csize = len; - - if (data->extent->encryption) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "encryption not supported"); - return -1; - } - - if (data->extent->compression) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "compression not supported"); - return -1; - } - - - if (data->extent->encoding) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "encoding not supported"); - return -1; - } - - switch (data->extent->type) - { - case GRUB_BTRFS_EXTENT_INLINE: - grub_memcpy (buf, data->extent->inl + extoff, csize); - break; - case GRUB_BTRFS_EXTENT_REGULAR: - if (!data->extent->laddr) - { - grub_memset (buf, 0, csize); - break; - } - err = grub_btrfs_read_logical (data, file->device->disk, - grub_le_to_cpu64 (data->extent->laddr) - + extoff, - buf, csize); - if (err) - return -1; - break; - default: - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported extent type 0x%x", data->extent->type); - return -1; - } - buf += csize; - pos += csize; - len -= csize; - } - return pos - file->offset; + return grub_btrfs_extent_read (data, file->device->disk, data->inode, + data->tree, file->offset, buf, len); } static grub_err_t From 0e761d3dbd9b20032dcde44b3caf0ce3dcbab191 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Dec 2010 11:30:24 +0100 Subject: [PATCH 0441/1414] Rename some btrfs variables for more uniformity --- grub-core/fs/btrfs.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 5046b8a28..ad7b10826 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -26,10 +26,10 @@ #include #include -#define BTRFS_SIGNATURE "_BHRfS_M" +#define GRUB_BTRFS_SIGNATURE "_BHRfS_M" -typedef grub_uint8_t btrfs_checksum_t[0x20]; -typedef grub_uint16_t btrfs_uuid_t[8]; +typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; +typedef grub_uint16_t grub_btrfs_uuid_t[8]; struct grub_btrfs_device { @@ -37,12 +37,12 @@ struct grub_btrfs_device grub_uint8_t dummy[0x62 - 8]; } __attribute__ ((packed)); -struct btrfs_superblock +struct grub_btrfs_superblock { - btrfs_checksum_t checksum; - btrfs_uuid_t uuid; + grub_btrfs_checksum_t checksum; + grub_btrfs_uuid_t uuid; grub_uint8_t dummy[0x10]; - grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1]; + grub_uint8_t signature[sizeof (GRUB_BTRFS_SIGNATURE) - 1]; grub_uint64_t generation; grub_uint64_t root_tree; grub_uint64_t chunk_tree; @@ -57,8 +57,8 @@ struct btrfs_superblock struct btrfs_header { - btrfs_checksum_t checksum; - btrfs_uuid_t uuid; + grub_btrfs_checksum_t checksum; + grub_btrfs_uuid_t uuid; grub_uint8_t dummy[0x30]; grub_uint32_t nitems; grub_uint8_t level; @@ -66,7 +66,7 @@ struct btrfs_header struct grub_btrfs_data { - struct btrfs_superblock sblock; + struct grub_btrfs_superblock sblock; unsigned int sblock_number; grub_uint64_t tree; grub_uint64_t inode; @@ -105,7 +105,7 @@ struct grub_btrfs_chunk_stripe { grub_uint64_t device_id; grub_uint64_t offset; - btrfs_uuid_t device_uuid; + grub_btrfs_uuid_t device_uuid; } __attribute__ ((packed)); struct grub_btrfs_leaf_node @@ -118,7 +118,7 @@ struct grub_btrfs_leaf_node struct grub_btrfs_internal_node { struct grub_btrfs_key key; - grub_uint64_t blockn; + grub_uint64_t addr; grub_uint64_t dummy; } __attribute__ ((packed)); @@ -271,12 +271,12 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, return -err; err = grub_btrfs_read_logical (data, disk, - grub_le_to_cpu64 (node.blockn), &head, + grub_le_to_cpu64 (node.addr), &head, sizeof (head)); if (err) return -err; - save_ref (desc, grub_le_to_cpu64 (node.blockn), 0, + save_ref (desc, grub_le_to_cpu64 (node.addr), 0, grub_le_to_cpu32 (head.nitems), !head.level); } err = grub_btrfs_read_logical (data, disk, @@ -358,7 +358,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, grub_le_to_cpu32 (head.nitems), 0); if (err) return err; - addr = grub_le_to_cpu64 (node.blockn); + addr = grub_le_to_cpu64 (node.addr); goto reiter; } if (key_cmp (&node.key, key_in) > 0) @@ -374,7 +374,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, grub_le_to_cpu32 (head.nitems), 0); if (err) return err; - addr = grub_le_to_cpu64 (node_last.blockn); + addr = grub_le_to_cpu64 (node_last.addr); goto reiter; } *outsize = 0; @@ -572,14 +572,14 @@ grub_btrfs_mount (grub_disk_t disk) for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) { - struct btrfs_superblock sblock; + struct grub_btrfs_superblock sblock; err = grub_disk_read (disk, superblock_sectors[i], 0, sizeof (sblock), &sblock); if (err == GRUB_ERR_OUT_OF_RANGE) break; - if (grub_memcmp ((char *) sblock.signature, BTRFS_SIGNATURE, - sizeof (BTRFS_SIGNATURE) - 1)) + if (grub_memcmp ((char *) sblock.signature, GRUB_BTRFS_SIGNATURE, + sizeof (GRUB_BTRFS_SIGNATURE) - 1)) break; if (i == 0 || grub_le_to_cpu64 (sblock.generation) > grub_le_to_cpu64 (data->sblock.generation)) From db51e201fc37f0d2b16d7b4748a9c3c9950e7389 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Dec 2010 16:56:49 +0100 Subject: [PATCH 0442/1414] symlink loop detection. btrfs-raid0 and raid1 support --- grub-core/fs/btrfs.c | 432 +++++++++++++++++++++++++++++-------------- 1 file changed, 295 insertions(+), 137 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ad7b10826..f8fbf95e9 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -49,7 +49,7 @@ struct grub_btrfs_superblock grub_uint8_t dummy2[0x20]; grub_uint64_t root_dir_objectid; grub_uint8_t dummy3[0x41]; - struct grub_btrfs_device this_device; + struct grub_btrfs_device this_device; char label[0x100]; grub_uint8_t dummy4[0x100]; grub_uint8_t bootstrap_mapping[0x800]; @@ -64,13 +64,22 @@ struct btrfs_header grub_uint8_t level; } __attribute__ ((packed)); +struct grub_btrfs_device_desc +{ + grub_device_t dev; + grub_uint64_t id; +}; + struct grub_btrfs_data { struct grub_btrfs_superblock sblock; - unsigned int sblock_number; grub_uint64_t tree; grub_uint64_t inode; + struct grub_btrfs_device_desc *devices_attached; + unsigned n_devices_attached; + unsigned n_devices_allocated; + /* Cached extent data. */ grub_uint64_t extstart; grub_uint64_t extino; @@ -96,9 +105,15 @@ struct grub_btrfs_chunk_item grub_uint64_t size; grub_uint64_t dummy; grub_uint64_t stripe_length; - grub_uint8_t dummy2[0x14]; + grub_uint64_t type; +#define GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE 0x07 +#define GRUB_BTRFS_CHUNK_TYPE_SINGLE 0x00 +#define GRUB_BTRFS_CHUNK_TYPE_RAID0 0x08 +#define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 +#define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 + grub_uint8_t dummy2[0xc]; grub_uint16_t nstripes; - grub_uint16_t dummy3; + grub_uint16_t nsubstripes; } __attribute__ ((packed)); struct grub_btrfs_chunk_stripe @@ -187,8 +202,37 @@ static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, - grub_disk_t disk, grub_disk_addr_t addr, - void *buf, grub_size_t size); + grub_disk_addr_t addr, void *buf, grub_size_t size); + +static grub_err_t +read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) +{ + unsigned i; + grub_err_t err = GRUB_ERR_NONE; + for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) + { + struct grub_btrfs_superblock sblock; + err = grub_disk_read (disk, superblock_sectors[i], 0, + sizeof (sblock), &sblock); + if (err == GRUB_ERR_OUT_OF_RANGE) + break; + + if (grub_memcmp ((char *) sblock.signature, GRUB_BTRFS_SIGNATURE, + sizeof (GRUB_BTRFS_SIGNATURE) - 1) != 0) + break; + if (i == 0 || grub_le_to_cpu64 (sblock.generation) + > grub_le_to_cpu64 (sb->generation)) + grub_memcpy (sb, &sblock, sizeof (sblock)); + } + + if ((err == GRUB_ERR_OUT_OF_RANGE || !err) && i == 0) + return grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); + + if (err == GRUB_ERR_OUT_OF_RANGE) + grub_errno = err = GRUB_ERR_NONE; + + return err; +} static int key_cmp (const struct grub_btrfs_key *a, const struct grub_btrfs_key *b) @@ -239,7 +283,7 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, } static int -next (struct grub_btrfs_data *data, grub_disk_t disk, +next (struct grub_btrfs_data *data, struct grub_btrfs_leaf_descriptor *desc, grub_disk_addr_t *outaddr, grub_size_t *outsize, struct grub_btrfs_key *key_out) @@ -261,8 +305,7 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, struct grub_btrfs_internal_node node; struct btrfs_header head; - err = grub_btrfs_read_logical (data, disk, - desc->data[desc->depth - 1].iter + err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter * sizeof (node) + sizeof (struct btrfs_header) + desc->data[desc->depth - 1].addr, &node, @@ -270,8 +313,7 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, if (err) return -err; - err = grub_btrfs_read_logical (data, disk, - grub_le_to_cpu64 (node.addr), &head, + err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), &head, sizeof (head)); if (err) return -err; @@ -279,8 +321,7 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, save_ref (desc, grub_le_to_cpu64 (node.addr), 0, grub_le_to_cpu32 (head.nitems), !head.level); } - err = grub_btrfs_read_logical (data, disk, - desc->data[desc->depth - 1].iter + err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter * sizeof (leaf) + sizeof (struct btrfs_header) + desc->data[desc->depth - 1].addr, &leaf, @@ -295,7 +336,7 @@ next (struct grub_btrfs_data *data, grub_disk_t disk, } static grub_err_t -lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, +lower_bound (struct grub_btrfs_data *data, const struct grub_btrfs_key *key_in, struct grub_btrfs_key *key_out, grub_disk_addr_t root, @@ -327,7 +368,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, reiter: depth++; /* FIXME: preread few nodes into buffer. */ - err = grub_btrfs_read_logical (data, disk, addr, &head, sizeof (head)); + err = grub_btrfs_read_logical (data, addr, &head, sizeof (head)); if (err) return err; addr += sizeof (head); @@ -339,8 +380,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, grub_memset (&node_last, 0, sizeof (node_last)); for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) { - err = grub_btrfs_read_logical (data, disk, addr - + i * sizeof (node), + err = grub_btrfs_read_logical (data, addr + i * sizeof (node), &node, sizeof (node)); if (err) return err; @@ -391,7 +431,7 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, int have_last = 0; for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) { - err = grub_btrfs_read_logical (data, disk, addr + i * sizeof (leaf), + err = grub_btrfs_read_logical (data, addr + i * sizeof (leaf), &leaf, sizeof (leaf)); if (err) return err; @@ -440,9 +480,83 @@ lower_bound (struct grub_btrfs_data *data, grub_disk_t disk, } } +static grub_device_t +find_device (struct grub_btrfs_data *data, grub_uint64_t id) +{ + grub_device_t dev_found = NULL; + auto int hook (const char *name); + int hook (const char *name) + { + grub_device_t dev; + grub_err_t err; + struct grub_btrfs_superblock sb; + dev = grub_device_open (name); + if (!dev) + return 0; + if (!dev->disk) + { + grub_device_close (dev); + return 0; + } + err = read_sblock (dev->disk, &sb); + if (err == GRUB_ERR_BAD_FS) + { + grub_device_close (dev); + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (err) + { + grub_device_close (dev); + grub_print_error (); + return 0; + } + if (grub_memcmp (data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0 + || sb.this_device.device_id != id) + { + grub_device_close (dev); + return 0; + } + + dev_found = dev; + return 1; + } + + unsigned i; + + for (i = 0; i < data->n_devices_attached; i++) + if (id == data->devices_attached[i].id) + return data->devices_attached[i].dev; + grub_device_iterate (hook); + if (!dev_found) + { + grub_error (GRUB_ERR_BAD_FS, "couldn't find a member device"); + return NULL; + } + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; + data->n_devices_allocated = 2 * data->n_devices_attached + 1; + data->devices_attached + = grub_realloc (tmp = data->devices_attached, + data->n_devices_allocated + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + grub_device_close (dev_found); + data->devices_attached = tmp; + return NULL; + } + } + data->devices_attached[data->n_devices_attached - 1].id = id; + data->devices_attached[data->n_devices_attached - 1].dev = dev_found; + return dev_found; +} + static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, - grub_disk_t disk, grub_disk_addr_t addr, + grub_disk_addr_t addr, void *buf, grub_size_t size) { while (size > 0) @@ -451,14 +565,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, struct grub_btrfs_key *key; struct grub_btrfs_chunk_item *chunk; struct grub_btrfs_chunk_stripe *stripe; - grub_size_t csize; + grub_ssize_t csize; grub_err_t err; - grub_disk_addr_t paddr; - grub_uint64_t stripen; - grub_uint32_t stripe_length; - grub_uint32_t stripe_offset; struct grub_btrfs_key key_out; int challoc = 0; + grub_device_t dev; for (ptr = data->sblock.bootstrap_mapping; ptr < data->sblock.bootstrap_mapping + sizeof (data->sblock.bootstrap_mapping) @@ -485,8 +596,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, key_in.object_id = GRUB_BTRFS_OBJECT_ID_CHUNK; key_in.type = GRUB_BTRFS_ITEM_TYPE_CHUNK; key_in.offset = addr; - err = lower_bound (data, disk, - &key_in, &key_out, + err = lower_bound (data, &key_in, &key_out, grub_le_to_cpu64 (data->sblock.chunk_tree), &chaddr, &chsize, NULL); if (err) @@ -502,55 +612,99 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, return grub_errno; challoc = 1; - err = grub_btrfs_read_logical (data, disk, chaddr, - chunk, chsize); + err = grub_btrfs_read_logical (data, chaddr, chunk, chsize); if (err) { grub_free (chunk); return err; } - - if (!(addr < grub_le_to_cpu64 (key->offset) - + grub_le_to_cpu64 (chunk->size))) - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find the chunk descriptor"); chunk_found: - stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - NULL); - stripen = grub_divmod64 (addr - grub_le_to_cpu64 (key->offset), - stripe_length, &stripe_offset); - stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); - stripe += stripen; - csize = grub_le_to_cpu64 (key->offset) + grub_le_to_cpu64 (chunk->size) - - addr; - if (csize > size) - csize = size; - if (grub_le_to_cpu64 (stripe->device_id) != grub_le_to_cpu64 (data->sblock.this_device.device_id)) - { - if (challoc) - grub_free (chunk); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "multidevice isn't implemented yet"); - } - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T " (%d stripes of %" - 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), - grub_le_to_cpu16 (chunk->nstripes), - grub_le_to_cpu64 (chunk->stripe_length), - stripen, - stripe->offset); - paddr = stripe->offset + stripe_offset; + { + grub_uint32_t stripen; + grub_uint32_t stripe_offset; + grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); + grub_disk_addr_t paddr; - grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, - addr); - err = grub_disk_read (disk, paddr >> GRUB_DISK_SECTOR_BITS, - paddr & (GRUB_DISK_SECTOR_SIZE - 1), csize, buf); + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + switch (grub_le_to_cpu64 (chunk->type) + & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE) + { + case GRUB_BTRFS_CHUNK_TYPE_SINGLE: + { + grub_uint32_t stripe_length; + 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; + } + case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: + case GRUB_BTRFS_CHUNK_TYPE_RAID1: + /* FIXME: Use redundancy. */ + { + grub_uint32_t stripe_length; + stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + NULL); + stripen = 0; + stripe_offset = off; + csize = stripe_length - off; + break; + } + case GRUB_BTRFS_CHUNK_TYPE_RAID0: + { + grub_uint64_t middle, high; + grub_uint32_t low; + middle = grub_divmod64 (off, + grub_le_to_cpu64 (chunk->stripe_length), + &low); + + high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes), + &stripen); + stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) + * high; + csize = grub_le_to_cpu64 (chunk->stripe_length) - low; + break; + } + default: + grub_printf ("unsupported RAID flags %" PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (chunk->type)); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported RAID flags %" PRIxGRUB_UINT64_T, + grub_le_to_cpu64 (chunk->type)); + } + stripe += stripen; + if (csize <= 0) + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + if ((grub_size_t) csize > size) + csize = size; + dev = find_device (data, stripe->device_id); + if (!dev) + return grub_errno; + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT32_T + " maps to 0x%" PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu64 (chunk->stripe_length), + stripen, + stripe->offset); + paddr = stripe->offset + stripe_offset; + + grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T + " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, + addr); + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), csize, buf); + if (err) + return err; + } size -= csize; buf = (grub_uint8_t *) buf + csize; addr += csize; @@ -561,54 +715,57 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, } static struct grub_btrfs_data * -grub_btrfs_mount (grub_disk_t disk) +grub_btrfs_mount (grub_device_t dev) { - struct grub_btrfs_data *data = grub_zalloc (sizeof (*data)); - unsigned i; - grub_err_t err = GRUB_ERR_NONE; + struct grub_btrfs_data *data; + grub_err_t err; + if (!dev->disk) + { + grub_error (GRUB_ERR_BAD_FS, "not BtrFS"); + return NULL; + } + + data = grub_zalloc (sizeof (*data)); if (! data) return NULL; - for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) + err = read_sblock (dev->disk, &data->sblock); + if (err) { - struct grub_btrfs_superblock sblock; - err = grub_disk_read (disk, superblock_sectors[i], 0, - sizeof (sblock), &sblock); - if (err == GRUB_ERR_OUT_OF_RANGE) - break; - - if (grub_memcmp ((char *) sblock.signature, GRUB_BTRFS_SIGNATURE, - sizeof (GRUB_BTRFS_SIGNATURE) - 1)) - break; - if (i == 0 || grub_le_to_cpu64 (sblock.generation) - > grub_le_to_cpu64 (data->sblock.generation)) - { - grub_memcpy (&data->sblock, &sblock, sizeof (sblock)); - data->sblock_number = i; - } + grub_free (data); + return NULL; } - if ((err == GRUB_ERR_OUT_OF_RANGE || !err) && i == 0) + data->n_devices_allocated = 16; + data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) + * data->n_devices_allocated); + if (!data->devices_attached) { - grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); - goto fail; + grub_free (data); + return NULL; } - - if (err == GRUB_ERR_OUT_OF_RANGE) - grub_errno = err = GRUB_ERR_NONE; - - grub_dprintf ("btrfs", "using superblock %d\n", data->sblock_number); + data->n_devices_attached = 1; + data->devices_attached[0].dev = dev; + data->devices_attached[0].id = data->sblock.this_device.device_id; return data; +} - fail: +static void +grub_btrfs_unmount (struct grub_btrfs_data *data) +{ + unsigned i; + /* The device 0 is closed one layer upper. */ + for (i = 1; i < data->n_devices_attached; i++) + grub_device_close (data->devices_attached[i].dev); + grub_free (data->devices_attached); + grub_free (data->extent); grub_free (data); - return NULL; } static grub_err_t -grub_btrfs_read_inode (struct grub_btrfs_data *data, grub_disk_t disk, +grub_btrfs_read_inode (struct grub_btrfs_data *data, struct grub_btrfs_inode *inode, grub_uint64_t num, grub_uint64_t tree) { @@ -621,7 +778,7 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, grub_disk_t disk, key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; key_in.offset = 0; - err = lower_bound (data,disk, &key_in, &key_out, tree, + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL); if (err) return err; @@ -629,11 +786,11 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, grub_disk_t disk, || key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_ITEM) return grub_error (GRUB_ERR_BAD_FS, "inode not found"); - return grub_btrfs_read_logical (data, disk, elemaddr, inode, sizeof (*inode)); + return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode)); } static grub_ssize_t -grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_disk_t disk, +grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_uint64_t ino, grub_uint64_t tree, grub_off_t pos0, char *buf, grub_size_t len) { @@ -654,7 +811,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_disk_t disk, key_in.object_id = ino; key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; key_in.offset = grub_cpu_to_le64 (pos); - err = lower_bound (data, disk, &key_in, &key_out, tree, + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL); if (err) return -1; @@ -671,7 +828,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_disk_t disk, if (!data->extent) return grub_errno; - err = grub_btrfs_read_logical (data, disk, elemaddr, + err = grub_btrfs_read_logical (data, elemaddr, data->extent, elemsize); if (err) return err; @@ -721,7 +878,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_disk_t disk, grub_memset (buf, 0, csize); break; } - err = grub_btrfs_read_logical (data, disk, + err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + extoff, buf, csize); @@ -742,7 +899,6 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_disk_t disk, static grub_err_t find_path (struct grub_btrfs_data *data, - grub_disk_t disk, const char *path, struct grub_btrfs_key *key, grub_uint64_t *tree, grub_uint8_t *type) { @@ -757,6 +913,7 @@ find_path (struct grub_btrfs_data *data, const char *ctoken; grub_size_t ctokenlen; char *path_alloc = NULL; + unsigned symlinks_max = 32; *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; *tree = data->sblock.root_tree; @@ -794,7 +951,7 @@ find_path (struct grub_btrfs_data *data, key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); - err = lower_bound (data, disk, key, &key_out, *tree, + err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, NULL); if (err) { @@ -822,8 +979,7 @@ find_path (struct grub_btrfs_data *data, } } - err = grub_btrfs_read_logical (data, disk, elemaddr, - direl, elemsize); + err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize); if (err) { grub_free (direl); @@ -860,7 +1016,15 @@ find_path (struct grub_btrfs_data *data, { struct grub_btrfs_inode inode; char *tmp; - err = grub_btrfs_read_inode (data, disk, &inode, + if (--symlinks_max == 0) + { + grub_free (direl); + grub_free (path_alloc); + return grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + } + + err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, *tree); if (err) { @@ -877,7 +1041,7 @@ find_path (struct grub_btrfs_data *data, return grub_errno; } - if (grub_btrfs_extent_read (data, disk, cdirel->key.object_id, + if (grub_btrfs_extent_read (data, cdirel->key.object_id, *tree, 0, tmp, grub_le_to_cpu64 (inode.size)) != (grub_ssize_t) grub_le_to_cpu64 (inode.size)) @@ -909,7 +1073,7 @@ find_path (struct grub_btrfs_data *data, case GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM: { struct grub_btrfs_root_item ri; - err = lower_bound (data, disk, &cdirel->key, &key_out, + err = lower_bound (data, &cdirel->key, &key_out, data->sblock.root_tree, &elemaddr, &elemsize, NULL); if (err) @@ -925,7 +1089,7 @@ find_path (struct grub_btrfs_data *data, grub_free (path_alloc); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); } - err = grub_btrfs_read_logical (data, disk, elemaddr, + err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri)); if (err) { @@ -967,7 +1131,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, const struct grub_dirhook_info *info)) { - struct grub_btrfs_data *data = grub_btrfs_mount (device->disk); + struct grub_btrfs_data *data = grub_btrfs_mount (device); struct grub_btrfs_key key_in, key_out; grub_err_t err; grub_disk_addr_t elemaddr; @@ -982,21 +1146,20 @@ grub_btrfs_dir (grub_device_t device, const char *path, if (!data) return grub_errno; - err = find_path (data, device->disk, path, &key_in, &tree, &type); + err = find_path (data, path, &key_in, &tree, &type); if (err) return err; if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); - err = lower_bound (data, device->disk, &key_in, &key_out, - tree, + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, &desc); if (err) return err; if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM || key_out.object_id != key_in.object_id) { - r = next (data, device->disk, &desc, &elemaddr, &elemsize, &key_out); + r = next (data, &desc, &elemaddr, &elemsize, &key_out); if (r <= 0) { free_iterator (&desc); @@ -1025,8 +1188,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, } } - err = grub_btrfs_read_logical (data, device->disk, elemaddr, - direl, elemsize); + err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize); if (err) return err; @@ -1046,7 +1208,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, goto out; cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; } - r = next (data, device->disk, &desc, &elemaddr, &elemsize, &key_out); + r = next (data, &desc, &elemaddr, &elemsize, &key_out); } while (r > 0); @@ -1054,7 +1216,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, grub_free (direl); free_iterator (&desc); - grub_free (data); + grub_btrfs_unmount (data); return -r; } @@ -1062,7 +1224,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, static grub_err_t grub_btrfs_open (struct grub_file *file, const char *name) { - struct grub_btrfs_data *data = grub_btrfs_mount (file->device->disk); + struct grub_btrfs_data *data = grub_btrfs_mount (file->device); grub_err_t err; struct grub_btrfs_inode inode; grub_uint8_t type; @@ -1071,24 +1233,23 @@ grub_btrfs_open (struct grub_file *file, const char *name) if (!data) return grub_errno; - err = find_path (data, file->device->disk, name, &key_in, &data->tree, &type); + err = find_path (data, name, &key_in, &data->tree, &type); if (err) { - grub_free (data); + grub_btrfs_unmount (data); return err; } if (type != GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) { - grub_free (data); + grub_btrfs_unmount (data); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); } data->inode = key_in.object_id; - err = grub_btrfs_read_inode (data, file->device->disk, &inode, data->inode, - data->tree); + err = grub_btrfs_read_inode (data, &inode, data->inode, data->tree); if (err) { - grub_free (data); + grub_btrfs_unmount (data); return err; } @@ -1101,10 +1262,7 @@ grub_btrfs_open (struct grub_file *file, const char *name) static grub_err_t grub_btrfs_close (grub_file_t file) { - struct grub_btrfs_data *data = file->data; - - grub_free (data->extent); - grub_free (data); + grub_btrfs_unmount (file->data); return GRUB_ERR_NONE; } @@ -1114,7 +1272,7 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_btrfs_data *data = file->data; - return grub_btrfs_extent_read (data, file->device->disk, data->inode, + return grub_btrfs_extent_read (data, data->inode, data->tree, file->offset, buf, len); } @@ -1125,7 +1283,7 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) *uuid = NULL; - data = grub_btrfs_mount (device->disk); + data = grub_btrfs_mount (device); if (! data) return grub_errno; @@ -1139,7 +1297,7 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); - grub_free (data); + grub_btrfs_unmount (data); return grub_errno; } @@ -1151,13 +1309,13 @@ grub_btrfs_label (grub_device_t device, char **label) *label = NULL; - data = grub_btrfs_mount (device->disk); + data = grub_btrfs_mount (device); if (! data) return grub_errno; *label = grub_strndup (data->sblock.label, sizeof (data->sblock.label)); - grub_free (data); + grub_btrfs_unmount (data); return grub_errno; } From 6333f1e9b680a8eefca82bfcdfd3afe66547ab29 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Dec 2010 18:11:10 +0100 Subject: [PATCH 0443/1414] Add RAID10 support --- grub-core/fs/btrfs.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index f8fbf95e9..e6bab83aa 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -111,6 +111,7 @@ struct grub_btrfs_chunk_item #define GRUB_BTRFS_CHUNK_TYPE_RAID0 0x08 #define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 #define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 +#define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 grub_uint8_t dummy2[0xc]; grub_uint16_t nstripes; grub_uint16_t nsubstripes; @@ -668,9 +669,26 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, csize = grub_le_to_cpu64 (chunk->stripe_length) - low; break; } + case GRUB_BTRFS_CHUNK_TYPE_RAID10: + /* FIXME: Use redundancy. */ + { + grub_uint64_t middle, high; + grub_uint32_t low; + middle = grub_divmod64 (off, + grub_le_to_cpu64 (chunk->stripe_length), + &low); + + high = grub_divmod64 (middle, + grub_le_to_cpu16 (chunk->nsubstripes), + &stripen); + stripen *= grub_le_to_cpu16 (chunk->nstripes) + / grub_le_to_cpu16 (chunk->nsubstripes); + stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) + * high; + csize = grub_le_to_cpu64 (chunk->stripe_length) - low; + break; + } default: - grub_printf ("unsupported RAID flags %" PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (chunk->type)); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported RAID flags %" PRIxGRUB_UINT64_T, grub_le_to_cpu64 (chunk->type)); From 3be8e5ea96264c2d0df38b63ff13596c634522dd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 3 Dec 2010 21:42:13 +0100 Subject: [PATCH 0444/1414] BtrFS zlib compression support --- Makefile.util.def | 1 + grub-core/fs/btrfs.c | 57 +++++++++++++-- grub-core/io/gzio.c | 157 +++++++++++++++++++++++++++++++---------- include/grub/deflate.h | 26 +++++++ 4 files changed, 197 insertions(+), 44 deletions(-) create mode 100644 include/grub/deflate.h diff --git a/Makefile.util.def b/Makefile.util.def index 4d642a2b6..f3cd1d234 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -95,6 +95,7 @@ library = { common = grub-core/script/main.c; common = grub-core/script/script.c; common = grub-core/script/argv.c; + common = grub-core/io/gzio.c; }; program = { diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index e6bab83aa..7e31fa3f1 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_BTRFS_SIGNATURE "_BHRfS_M" @@ -84,6 +85,7 @@ struct grub_btrfs_data grub_uint64_t extstart; grub_uint64_t extino; grub_uint64_t exttree; + grub_size_t extsize; struct grub_btrfs_extent_data *extent; }; @@ -187,13 +189,20 @@ struct grub_btrfs_extent_data union { char inl[0]; - grub_uint64_t laddr; + struct + { + grub_uint64_t laddr; + grub_uint64_t compressed_size; + grub_uint64_t offset; + }; }; } __attribute__ ((packed)); #define GRUB_BTRFS_EXTENT_INLINE 0 #define GRUB_BTRFS_EXTENT_REGULAR 1 +#define GRUB_BTRFS_COMPRESSION_NONE 0 +#define GRUB_BTRFS_COMPRESSION_ZLIB 1 #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 @@ -840,6 +849,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, return -1; } data->extstart = grub_le_to_cpu64 (key_out.offset); + data->extsize = elemsize; data->extent = grub_malloc (elemsize); data->extino = ino; data->exttree = tree; @@ -870,14 +880,15 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, return -1; } - if (data->extent->compression) + if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE + && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "compression not supported"); + "compression type 0x%x not supported", + data->extent->compression); return -1; } - if (data->extent->encoding) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, @@ -888,7 +899,17 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, switch (data->extent->type) { case GRUB_BTRFS_EXTENT_INLINE: - grub_memcpy (buf, data->extent->inl + extoff, csize); + if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) + { + if (grub_zlib_decompress (data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) + != (grub_ssize_t) csize) + return -1; + } + else + grub_memcpy (buf, data->extent->inl + extoff, csize); break; case GRUB_BTRFS_EXTENT_REGULAR: if (!data->extent->laddr) @@ -896,6 +917,32 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_memset (buf, 0, csize); break; } + if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) + { + char *tmp; + grub_uint64_t zsize; + zsize = grub_le_to_cpu64 (data->extent->compressed_size); + tmp = grub_malloc (zsize); + if (!tmp) + return -1; + err = grub_btrfs_read_logical (data, + grub_le_to_cpu64 (data->extent->laddr), + tmp, zsize); + if (err) + { + grub_free (tmp); + return -1; + } + if (grub_zlib_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize) != (grub_ssize_t) csize) + { + grub_free (tmp); + return -1; + } + grub_free (tmp); + break; + } err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + extoff, diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 43b67c373..248a1750e 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * Window Size @@ -58,6 +59,9 @@ struct grub_gzio { /* The underlying file object. */ grub_file_t file; + /* 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; /* The offset at which the data starts in the underlying file. */ grub_off_t data_offset; /* The type of current block. */ @@ -100,7 +104,7 @@ typedef struct grub_gzio *grub_gzio_t; static struct grub_fs grub_gzio_fs; /* Function prototypes */ -static void initialize_tables (grub_file_t file); +static void initialize_tables (grub_gzio_t); /* Eat variable-length header fields. */ static int @@ -162,7 +166,7 @@ typedef unsigned short ush; typedef unsigned long ulg; static int -test_header (grub_file_t file) +test_gzip_header (grub_file_t file) { struct { grub_uint16_t magic; @@ -226,7 +230,7 @@ test_header (grub_file_t file) But how can we know the real original size? */ file->size = grub_le_to_cpu32 (orig_len); - initialize_tables (file); + initialize_tables (gzio); return 1; } @@ -366,13 +370,18 @@ static ush mask_bits[] = 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; -#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(file))<>=(n);k-=(n);} while (0) static int -get_byte (grub_file_t file) +get_byte (grub_gzio_t gzio) { - grub_gzio_t gzio = file->data; + if (gzio->mem_input) + { + if (gzio->mem_input_off < gzio->mem_input_size) + return gzio->mem_input[gzio->mem_input_off++]; + return 0; + } if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset || gzio->inbuf_d == INBUFSIZ) @@ -384,11 +393,26 @@ get_byte (grub_file_t file) return gzio->inbuf[gzio->inbuf_d++]; } +static void +gzio_seek (grub_gzio_t gzio, grub_off_t off) +{ + if (gzio->mem_input) + { + if (off > gzio->mem_input_size) + grub_error (GRUB_ERR_OUT_OF_RANGE, + "attempt to seek outside of the file"); + else + gzio->mem_input_off = gzio->data_offset; + } + else + grub_file_seek (gzio->file, off); +} + /* more function prototypes */ static int huft_build (unsigned *, unsigned, unsigned, ush *, ush *, struct huft **, int *); static int huft_free (struct huft *); -static int inflate_codes_in_window (grub_file_t); +static int inflate_codes_in_window (grub_gzio_t); /* Given a list of code lengths and a maximum table size, make a set of @@ -615,7 +639,7 @@ huft_free (struct huft *t) */ static int -inflate_codes_in_window (grub_file_t file) +inflate_codes_in_window (grub_gzio_t gzio) { register unsigned e; /* table entry flag/number of extra bits */ unsigned n, d; /* length and index for copy */ @@ -624,7 +648,6 @@ inflate_codes_in_window (grub_file_t file) unsigned ml, md; /* masks for bl and bd bits */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ - grub_gzio_t gzio = file->data; /* make local copies of globals */ d = gzio->inflate_d; @@ -752,11 +775,10 @@ inflate_codes_in_window (grub_file_t file) /* get header for an inflated type 0 (stored) block. */ static void -init_stored_block (grub_file_t file) +init_stored_block (grub_gzio_t gzio) { register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ - grub_gzio_t gzio = file->data; /* make local copies of globals */ b = gzio->bb; /* initialize bit buffer */ @@ -786,11 +808,10 @@ init_stored_block (grub_file_t file) Huffman tables. */ static void -init_fixed_block (grub_file_t file) +init_fixed_block (grub_gzio_t gzio) { int i; /* temporary variable */ unsigned l[288]; /* length list for huft_build */ - grub_gzio_t gzio = file->data; /* set up literal table */ for (i = 0; i < 144; i++) @@ -833,7 +854,7 @@ init_fixed_block (grub_file_t file) /* get header for an inflated type 2 (dynamic Huffman codes) block. */ static void -init_dynamic_block (grub_file_t file) +init_dynamic_block (grub_gzio_t gzio) { int i; /* temporary variables */ unsigned j; @@ -846,7 +867,6 @@ init_dynamic_block (grub_file_t file) unsigned ll[286 + 30]; /* literal/length and distance code lengths */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ - grub_gzio_t gzio = file->data; /* make local bit buffer */ b = gzio->bb; @@ -977,11 +997,10 @@ init_dynamic_block (grub_file_t file) static void -get_new_block (grub_file_t file) +get_new_block (grub_gzio_t gzio) { register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ - grub_gzio_t gzio = file->data; /* make local bit buffer */ b = gzio->bb; @@ -1004,13 +1023,13 @@ get_new_block (grub_file_t file) switch (gzio->block_type) { case INFLATE_STORED: - init_stored_block (file); + init_stored_block (gzio); break; case INFLATE_FIXED: - init_fixed_block (file); + init_fixed_block (gzio); break; case INFLATE_DYNAMIC: - init_dynamic_block (file); + init_dynamic_block (gzio); break; default: break; @@ -1019,10 +1038,8 @@ get_new_block (grub_file_t file) static void -inflate_window (grub_file_t file) +inflate_window (grub_gzio_t gzio) { - grub_gzio_t gzio = file->data; - /* initialize window */ gzio->wp = 0; @@ -1037,7 +1054,7 @@ inflate_window (grub_file_t file) if (gzio->last_block) break; - get_new_block (file); + get_new_block (gzio); } if (gzio->block_type > INFLATE_DYNAMIC) @@ -1060,7 +1077,7 @@ inflate_window (grub_file_t file) while (gzio->block_len && w < WSIZE && grub_errno == GRUB_ERR_NONE) { - gzio->slide[w++] = get_byte (file); + gzio->slide[w++] = get_byte (gzio); gzio->block_len--; } @@ -1073,7 +1090,7 @@ inflate_window (grub_file_t file) * Expand other kind of block. */ - if (inflate_codes_in_window (file)) + if (inflate_codes_in_window (gzio)) { huft_free (gzio->tl); huft_free (gzio->td); @@ -1089,12 +1106,10 @@ inflate_window (grub_file_t file) static void -initialize_tables (grub_file_t file) +initialize_tables (grub_gzio_t gzio) { - grub_gzio_t gzio = file->data; - gzio->saved_offset = 0; - grub_file_seek (gzio->file, gzio->data_offset); + gzio_seek (gzio, gzio->data_offset); /* Initialize the bit buffer. */ gzio->bk = 0; @@ -1139,7 +1154,7 @@ grub_gzio_open (grub_file_t io) file->fs = &grub_gzio_fs; file->not_easly_seekable = 1; - if (! test_header (file)) + if (! test_gzip_header (file)) { grub_free (gzio); grub_free (file); @@ -1155,16 +1170,49 @@ grub_gzio_open (grub_file_t io) return file; } +static int +test_zlib_header (grub_gzio_t gzio) +{ + grub_uint8_t cmf, flg; + + cmf = get_byte (gzio); + flg = get_byte (gzio); + + /* Check that compression method is DEFLATE. */ + if ((cmf & 0xf) != DEFLATED) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "unsupported gzip format"); + return 0; + } + + if ((cmf * 256 + flg) % 31) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "unsupported gzip format"); + return 0; + } + + /* Dictionary isn't supported. */ + if (flg & 0x20) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "unsupported gzip format"); + return 0; + } + + gzio->data_offset = 2; + initialize_tables (gzio); + + return 1; +} + static grub_ssize_t -grub_gzio_read (grub_file_t file, char *buf, grub_size_t len) +grub_gzio_read_real (grub_gzio_t gzio, grub_off_t offset, + char *buf, grub_size_t len) { grub_ssize_t ret = 0; - grub_gzio_t gzio = file->data; - grub_off_t offset; /* Do we reset decompression to the beginning of the file? */ - if (gzio->saved_offset > file->offset + WSIZE) - initialize_tables (file); + if (gzio->saved_offset > offset + WSIZE) + initialize_tables (gzio); /* * This loop operates upon uncompressed data only. The only @@ -1172,15 +1220,13 @@ grub_gzio_read (grub_file_t file, char *buf, grub_size_t len) * window is within the range of data it needs. */ - offset = file->offset; - while (len > 0 && grub_errno == GRUB_ERR_NONE) { register grub_size_t size; register char *srcaddr; while (offset >= gzio->saved_offset) - inflate_window (file); + inflate_window (gzio); srcaddr = (char *) ((offset & (WSIZE - 1)) + gzio->slide); size = gzio->saved_offset - offset; @@ -1201,6 +1247,12 @@ grub_gzio_read (grub_file_t file, char *buf, grub_size_t len) return ret; } +static grub_ssize_t +grub_gzio_read (grub_file_t file, char *buf, grub_size_t len) +{ + return grub_gzio_read_real (file->data, file->offset, buf, len); +} + /* Release everything, including the underlying file object. */ static grub_err_t grub_gzio_close (grub_file_t file) @@ -1218,6 +1270,33 @@ grub_gzio_close (grub_file_t file) return grub_errno; } +grub_ssize_t +grub_zlib_decompress (char *inbuf, grub_size_t insize, 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->mem_input = (grub_uint8_t *) inbuf; + gzio->mem_input_size = insize; + gzio->mem_input_off = 0; + + 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; +} + static struct grub_fs grub_gzio_fs = diff --git a/include/grub/deflate.h b/include/grub/deflate.h new file mode 100644 index 000000000..6ec4eaa99 --- /dev/null +++ b/include/grub/deflate.h @@ -0,0 +1,26 @@ +/* + * 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_DEFLATE_HEADER +#define GRUB_DEFLATE_HEADER 1 + +grub_ssize_t +grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, + char *outbuf, grub_size_t outsize); + +#endif From 7a6e93788cda1f9ead6b4fdb25ea72b7a434eddd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Dec 2010 00:40:44 +0100 Subject: [PATCH 0445/1414] ZFS zlib compression support --- grub-core/fs/zfs/zfs.c | 22 ++++++++++++++++++++-- include/grub/zfs/zio.h | 10 +++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8901af76f..d7bf2bc30 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -51,6 +51,7 @@ #include #include #include +#include #define ZPOOL_PROP_BOOTFS "bootfs" @@ -161,13 +162,30 @@ struct grub_zfs_data grub_disk_addr_t vdev_phys_sector; }; +static grub_err_t +zlib_decompress (void *s, void *d, + grub_size_t slen, grub_size_t dlen) +{ + if (grub_zlib_decompress (s, slen, 0, d, dlen) < 0) + return grub_errno; + return GRUB_ERR_NONE; +} + decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ {"off", NULL}, /* ZIO_COMPRESS_OFF */ {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */ {"empty", NULL}, /* ZIO_COMPRESS_EMPTY */ - {"gzip", NULL}, /* ZIO_COMPRESS_GZIP */ + {"gzip-1", zlib_decompress}, /* ZIO_COMPRESS_GZIP1 */ + {"gzip-2", zlib_decompress}, /* ZIO_COMPRESS_GZIP2 */ + {"gzip-3", zlib_decompress}, /* ZIO_COMPRESS_GZIP3 */ + {"gzip-4", zlib_decompress}, /* ZIO_COMPRESS_GZIP4 */ + {"gzip-5", zlib_decompress}, /* ZIO_COMPRESS_GZIP5 */ + {"gzip-6", zlib_decompress}, /* ZIO_COMPRESS_GZIP6 */ + {"gzip-7", zlib_decompress}, /* ZIO_COMPRESS_GZIP7 */ + {"gzip-8", zlib_decompress}, /* ZIO_COMPRESS_GZIP8 */ + {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ }; static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, @@ -525,7 +543,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, *buf = NULL; checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; - comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7; + comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; lsize = (BP_IS_HOLE(bp) ? 0 : (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) << SPA_MINBLOCKSHIFT)); diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 797d4f9b3..3dafb4028 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -77,7 +77,15 @@ enum zio_compress { ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_EMPTY, - ZIO_COMPRESS_GZIP, + ZIO_COMPRESS_GZIP1, + ZIO_COMPRESS_GZIP2, + ZIO_COMPRESS_GZIP3, + ZIO_COMPRESS_GZIP4, + ZIO_COMPRESS_GZIP5, + ZIO_COMPRESS_GZIP6, + ZIO_COMPRESS_GZIP7, + ZIO_COMPRESS_GZIP8, + ZIO_COMPRESS_GZIP9, ZIO_COMPRESS_FUNCTIONS }; From c5cf9f53a839f38405fd9fe10999c3231c30322a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 4 Dec 2010 01:59:06 +0100 Subject: [PATCH 0446/1414] Fix short symlinks --- grub-core/fs/zfs/zfs.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index d7bf2bc30..8f20085fa 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1306,22 +1306,27 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, break; *path = ch; -#if 0 - if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa && ch) + if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { char *oldpath = path, *oldpathbuf = path_buf; + grub_size_t bonuslen; + bonuslen = (grub_uint8_t *) (&dnode_path->dn.dn + 1) + - (grub_uint8_t *) DN_BONUS (&dnode_path->dn.dn); + if (bonuslen <= sizeof (znode_phys_t)) + err = grub_error (GRUB_ERR_BAD_FS, + "incorrect or unsupported symlink"); path = path_buf - = grub_malloc (sizeof (dnode_path->dn.dn.dn_bonus) - - sizeof (znode_phys_t) + grub_strlen (oldpath) + 1); + = grub_malloc (bonuslen - sizeof (znode_phys_t) + + grub_strlen (oldpath) + 1); if (!path_buf) { grub_free (oldpathbuf); return grub_errno; } - grub_memcpy (path, - (char *) DN_BONUS(&dnode_path->dn.dn) + sizeof (znode_phys_t), - sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)); - path [sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)] = 0; + grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) + + sizeof (znode_phys_t), + bonuslen - sizeof (znode_phys_t)); + path[bonuslen - sizeof (znode_phys_t)] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); @@ -1339,7 +1344,6 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (dn_new); } } -#endif } if (!err) From 24b7938b32e755f25302962895cb81093550533c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 4 Dec 2010 16:19:26 +0000 Subject: [PATCH 0447/1414] * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Use `>> 1' rather than `/ 2', as the latter requires -Wa,--divide which would require bumping our minimum binutils version. --- ChangeLog | 6 ++++++ grub-core/kern/i386/pc/startup.S | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 995799775..0c6e842de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-04 Colin Watson + + * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Use `>> 1' + rather than `/ 2', as the latter requires -Wa,--divide which would + require bumping our minimum binutils version. + 2010-12-03 BVK Chaitanya * util/grub-script-check.c (main): Print script line number on diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index d089a3e15..7aebc8b38 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -650,7 +650,7 @@ FUNCTION(grub_console_getkey) jae 2f movl %edx, %eax leal LOCAL(bypass_table), %edi - movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx + movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) >> 1), %ecx repne scasw jz 3f From fe79a8ad9db01795baccfc28525a5d75f03d0959 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 15:35:08 +0100 Subject: [PATCH 0448/1414] Fix fzap handling --- grub-core/fs/zfs/zfs.c | 4 +++- include/grub/zfs/zap_leaf.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8f20085fa..c47b4afc9 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -961,7 +961,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); return 0; } - for (idx = 0; idx < zap->zap_ptrtbl.zt_numblks; idx++) + for (idx = 0; idx < grub_zfs_to_cpu64 (zap->zap_num_leafs, + zap_dnode->endian); idx++) { blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; @@ -2553,6 +2554,7 @@ static struct grub_fs grub_zfs_fs = { GRUB_MOD_INIT (zfs) { + COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE); grub_fs_register (&grub_zfs_fs); #ifndef GRUB_UTIL my_mod = mod; diff --git a/include/grub/zfs/zap_leaf.h b/include/grub/zfs/zap_leaf.h index 1ef654054..5adfdc290 100644 --- a/include/grub/zfs/zap_leaf.h +++ b/include/grub/zfs/zap_leaf.h @@ -90,7 +90,7 @@ typedef union zap_leaf_chunk { { grub_uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; grub_uint64_t la_array64; - }; + } __attribute__ ((packed)); grub_uint16_t la_next; /* next blk or CHAIN_END */ } l_array; struct zap_leaf_free { From 47c3603cc8deeae7bf03bb7fc6756d9c58fe5e00 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 15:41:17 +0100 Subject: [PATCH 0449/1414] Add missing endianness conversions in fzap code --- grub-core/fs/zfs/zfs.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index c47b4afc9..62d7051ef 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -831,7 +831,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic"); for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h)], endian); - chunk != CHAIN_END; chunk = le->le_next) + chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian)) { if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) @@ -856,7 +856,8 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, struct zap_leaf_array *la; grub_uint8_t *ip; - if (le->le_int_size != 8 || le->le_value_length != 1) + if (le->le_int_size != 8 || grub_zfs_to_cpu16 (le->le_value_length, + endian) != 1) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); /* get the uint64_t property value */ @@ -875,9 +876,9 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, /* Verify if this is a fat zap header block */ static grub_err_t -zap_verify (zap_phys_t *zap) +zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) { - if (zap->zap_magic != (grub_uint64_t) ZAP_MAGIC) + if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); if (zap->zap_flags != 0) @@ -905,7 +906,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_err_t err; grub_zfs_endian_t leafendian; - err = zap_verify (zap); + err = zap_verify (zap, zap_dnode->endian); if (err) return err; @@ -916,7 +917,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "external pointer tables not supported"); idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift); - blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], zap_dnode->endian); /* Get the leaf block */ if ((1U << blksft) < sizeof (zap_leaf_phys_t)) @@ -945,7 +946,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_err_t err; grub_zfs_endian_t endian; - if (zap_verify (zap)) + if (zap_verify (zap, zap_dnode->endian)) return 0; /* get block id from index */ @@ -964,7 +965,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, for (idx = 0; idx < grub_zfs_to_cpu64 (zap->zap_num_leafs, zap_dnode->endian); idx++) { - blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], + zap_dnode->endian); err = dmu_read (zap_dnode, blkid, (void **) &l, &endian, data); if (err) @@ -999,8 +1001,11 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) + 1); - if (zap_leaf_array_get (l, endian, blksft, le->le_name_chunk, - le->le_name_length, buf)) + if (zap_leaf_array_get (l, endian, blksft, + grub_zfs_to_cpu16 (le->le_name_chunk, + endian), + grub_zfs_to_cpu16 (le->le_name_length, + endian), buf)) { grub_free (buf); continue; @@ -1012,7 +1017,9 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, continue; /* get the uint64_t property value */ - la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; + la = &ZAP_LEAF_CHUNK (l, blksft, + grub_zfs_to_cpu16 (le->le_value_chunk, + endian)).l_array; val = grub_be_to_cpu64 (la->la_array64); if (hook (buf, val)) return 1; From 069142f4c2cd0eab6528a4abfc955b308c47d113 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 16:08:26 +0100 Subject: [PATCH 0450/1414] Support long symlinks --- grub-core/fs/zfs/zfs.c | 47 +++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 62d7051ef..bf955a930 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1323,18 +1323,45 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, if (bonuslen <= sizeof (znode_phys_t)) err = grub_error (GRUB_ERR_BAD_FS, "incorrect or unsupported symlink"); - path = path_buf - = grub_malloc (bonuslen - sizeof (znode_phys_t) - + grub_strlen (oldpath) + 1); - if (!path_buf) + if (dnode_path->dn.dn.dn_flags & 1) { - grub_free (oldpathbuf); - return grub_errno; + void *sbuf; + grub_size_t ssize; + err = zio_read (dnode_path->dn.dn.dn_blkptr, + dnode_path->dn.endian, &sbuf, + &ssize, data); + if (err) + { + grub_free (oldpathbuf); + return err; + } + + path = path_buf = grub_malloc (ssize+ grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + grub_free (sbuf); + return grub_errno; + } + grub_memcpy (path, sbuf, ssize); + path[ssize] = 0; + grub_free (sbuf); + } + else + { + path = path_buf + = grub_malloc (bonuslen - sizeof (znode_phys_t) + + grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + return grub_errno; + } + grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) + + sizeof (znode_phys_t), + bonuslen - sizeof (znode_phys_t)); + path[bonuslen - sizeof (znode_phys_t)] = 0; } - grub_memcpy (path, (char *) DN_BONUS(&dnode_path->dn.dn) - + sizeof (znode_phys_t), - bonuslen - sizeof (znode_phys_t)); - path[bonuslen - sizeof (znode_phys_t)] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); From e5c63d9d4183e40f155e84f3313b9f1490064659 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 18:13:32 +0100 Subject: [PATCH 0451/1414] Fix handling of nvlist array --- grub-core/fs/zfs/zfs.c | 48 ++++++++++++++++++++++++-------------- grub-core/fs/zfs/zfsinfo.c | 2 +- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index bf955a930..670326a42 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1812,13 +1812,28 @@ grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) grub_size_t nelm, size; int found; - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, &size, &nelm); if (! found) return -1; return nelm; } +static int +get_nvlist_size (char *beg, char *limit) +{ + char *ptr; + grub_uint32_t encode_size; + + ptr = beg + 8; + + while (ptr < limit + && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) ptr))) + ptr += encode_size; /* goto the next nvpair */ + ptr += 8; + return (ptr > limit) ? -1 : (ptr - beg); +} + char * grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, grub_size_t index) @@ -1829,8 +1844,9 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, grub_size_t size; unsigned i; grub_size_t nelm; + int elemsize = 0; - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, &size, &nelm); if (!found) return 0; @@ -1844,33 +1860,31 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, for (i = 0; i < index; i++) { - grub_uint32_t encode_size; + int r; + r = get_nvlist_size (nvpairptr, nvpair + size); - /* skip the header, nvl_version, and nvl_nvflag */ - nvpairptr = nvpairptr + 4 * 2; - - while (nvpairptr < nvpair + size - && (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvpairptr))) - nvlist += encode_size; /* goto the next nvpair */ - - nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */ + if (r < 0) + { + grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); + return NULL; + } + nvpairptr += r; } - if (nvpairptr >= nvpair + size - || nvpairptr + grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) - >= nvpair + size) + elemsize = get_nvlist_size (nvpairptr, nvpair + size); + + if (elemsize < 0) { grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); return 0; } - ret = grub_zalloc (grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2)) - + 3 * sizeof (grub_uint32_t)); + ret = grub_zalloc (elemsize + sizeof (grub_uint32_t)); if (!ret) return 0; grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); - grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, size); + grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, elemsize); return ret; } diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 33065892a..735b8e983 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -139,7 +139,6 @@ print_vdev_info (char *nvlist, int tab) } grub_printf ("Mirror VDEV with %d children\n", nelm); print_state (nvlist, tab); - for (i = 0; i < nelm; i++) { char *child; @@ -159,6 +158,7 @@ print_vdev_info (char *nvlist, int tab) grub_free (child); } + return GRUB_ERR_NONE; } print_tabs (tab); From fdfde32aa4f1d4ce00d86cf481401cf215b8861e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 5 Dec 2010 21:17:24 +0100 Subject: [PATCH 0452/1414] striped zpool support --- Makefile.util.def | 1 + grub-core/fs/zfs/zfs.c | 659 +++++++++++++++++++++++++---------------- util/grub-fstest.c | 8 + 3 files changed, 412 insertions(+), 256 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 2dd7fe1e9..0e2e0afa8 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -71,6 +71,7 @@ library = { common = grub-core/fs/ufs.c; common = grub-core/fs/xfs.c; common = grub-core/fs/zfs/zfs.c; + common = grub-core/fs/zfs/zfsinfo.c; common = grub-core/fs/zfs/zfs_lzjb.c; common = grub-core/fs/zfs/zfs_sha256.c; common = grub-core/fs/zfs/zfs_fletcher.c; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 670326a42..3163e2e78 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -138,6 +138,15 @@ typedef struct dnode_end grub_zfs_endian_t endian; } dnode_end_t; +struct grub_zfs_device_desc +{ + enum { DEVICE_LEAF } type; + grub_disk_t disk; + grub_uint64_t id; + grub_disk_addr_t vdev_phys_sector; + uberblock_t current_uberblock; +}; + struct grub_zfs_data { /* cache for a file block of the currently zfs_open()-ed file */ @@ -152,14 +161,16 @@ struct grub_zfs_data grub_uint64_t dnode_end; grub_zfs_endian_t dnode_endian; - uberblock_t current_uberblock; - grub_disk_t disk; - dnode_end_t mos; dnode_end_t mdn; dnode_end_t dnode; - grub_disk_addr_t vdev_phys_sector; + struct grub_zfs_device_desc *devices_attached; + unsigned n_devices_attached; + unsigned n_devices_allocated; + + int mounted; + grub_uint64_t guid; }; static grub_err_t @@ -408,7 +419,7 @@ get_psize (blkptr_t * bp, grub_zfs_endian_t endian) } static grub_uint64_t -dva_get_offset (dva_t * dva, grub_zfs_endian_t endian) +dva_get_offset (const dva_t *dva, grub_zfs_endian_t endian) { grub_dprintf ("zfs", "dva=%llx, %llx\n", (unsigned long long) dva->dva_word[0], @@ -417,6 +428,356 @@ dva_get_offset (dva_t * dva, grub_zfs_endian_t endian) endian) << SPA_MINBLOCKSHIFT; } +static grub_err_t +zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) +{ + grub_err_t err; + + *nvlist = grub_malloc (VDEV_PHYS_SIZE); + /* Read in the vdev name-value pair list (112K). */ + err = grub_disk_read (diskdesc->disk, diskdesc->vdev_phys_sector, 0, + VDEV_PHYS_SIZE, *nvlist); + if (err) + { + grub_free (*nvlist); + *nvlist = 0; + return err; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +fill_vdev_info (char *nvlist, struct grub_zfs_device_desc *diskdesc) +{ + char *type = 0; + + type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); + + if (!type) + return grub_errno; + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) + { + diskdesc->type = DEVICE_LEAF; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &diskdesc->id)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", + type); +} + +/* + * Check the disk label information and retrieve needed vdev name-value pairs. + * + */ +static grub_err_t +check_pool_label (struct grub_zfs_data *data, + struct grub_zfs_device_desc *diskdesc, + grub_uint64_t *id) +{ + grub_uint64_t pool_state, txg = 0; + char *nvlist; +#if 0 + char *nv; +#endif + grub_uint64_t diskguid, poolguid; + grub_uint64_t version; + int found; + grub_err_t err; + + err = zfs_fetch_nvlist (diskdesc, &nvlist); + if (err) + return err; + + grub_dprintf ("zfs", "check 2 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, + &pool_state); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 3 passed\n"); + + if (pool_state == POOL_STATE_DESTROYED) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); + } + grub_dprintf ("zfs", "check 4 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); + if (!found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 6 passed\n"); + + /* not an active device */ + if (txg == 0) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); + } + grub_dprintf ("zfs", "check 7 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, + &version); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); + return grub_errno; + } + grub_dprintf ("zfs", "check 8 passed\n"); + + if (version > SPA_VERSION) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "too new version %llu > %llu", + (unsigned long long) version, + (unsigned long long) SPA_VERSION); + } + grub_dprintf ("zfs", "check 9 passed\n"); + + { + char *nv; + nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); + + if (!nv) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); + } + err = fill_vdev_info (nv, diskdesc); + if (err) + { + grub_free (nvlist); + return err; + } + } + grub_dprintf ("zfs", "check 10 passed\n"); + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); + return grub_errno; + } + + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, + &poolguid); + if (! found) + { + grub_free (nvlist); + if (! grub_errno) + grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_GUID " not found"); + return grub_errno; + } + + grub_dprintf ("zfs", "check 11 passed\n"); + + if (data->mounted && data->guid != poolguid) + return grub_error (GRUB_ERR_BAD_FS, "another zpool"); + else + data->guid = poolguid; + grub_free (nvlist); + + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; + data->n_devices_allocated = 2 * data->n_devices_attached + 1; + data->devices_attached + = grub_realloc (tmp = data->devices_attached, + data->n_devices_allocated + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + data->devices_attached = tmp; + return grub_errno; + } + } + + data->devices_attached[data->n_devices_attached - 1] = *diskdesc; + if (id) + *id = diskdesc->id; + + return GRUB_ERR_NONE; +} + +static grub_err_t +scan_disk (grub_disk_t disk, struct grub_zfs_data *data, + grub_uint64_t *id) +{ + int label = 0; + uberblock_phys_t *ub_array, *ubbest = NULL; + vdev_boot_header_t *bh; + grub_err_t err; + int vdevnum; + struct grub_zfs_device_desc desc; + + ub_array = grub_malloc (VDEV_UBERBLOCK_RING); + if (!ub_array) + return grub_errno; + + bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); + if (!bh) + { + grub_free (ub_array); + return grub_errno; + } + + vdevnum = VDEV_LABELS; + + desc.disk = disk; + + /* Don't check back labels on CDROM. */ + if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN) + vdevnum = VDEV_LABELS / 2; + + for (label = 0; ubbest == NULL && label < vdevnum; label++) + { + grub_dprintf ("zfs", "label %d\n", label); + + desc.vdev_phys_sector + = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) + + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) + + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (disk) + - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); + + /* Read in the uberblock ring (128K). */ + err = grub_disk_read (disk, desc.vdev_phys_sector + + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), + 0, VDEV_UBERBLOCK_RING, (char *) ub_array); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + grub_dprintf ("zfs", "label ok %d\n", label); + + ubbest = find_bestub (ub_array, desc.vdev_phys_sector); + if (!ubbest) + { + grub_dprintf ("zfs", "No uberblock found\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + + grub_memmove (&(desc.current_uberblock), + &ubbest->ubp_uberblock, sizeof (uberblock_t)); + + err = check_pool_label (data, &desc, id); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } +#if 0 + if (find_best_root && + vdev_uberblock_compare (&ubbest->ubp_uberblock, + &(current_uberblock)) <= 0) + continue; +#endif + grub_free (ub_array); + grub_free (bh); + return GRUB_ERR_NONE; + } + + grub_free (ub_array); + grub_free (bh); + + return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); +} + +static grub_err_t +scan_devices (struct grub_zfs_data *data, grub_uint64_t id) +{ + grub_device_t dev_found = NULL; + auto int hook (const char *name); + int hook (const char *name) + { + grub_device_t dev; + grub_err_t err; + grub_uint64_t f_id = -1; + dev = grub_device_open (name); + if (!dev) + return 0; + if (!dev->disk) + { + grub_device_close (dev); + return 0; + } + err = scan_disk (dev->disk, data, &f_id); + if (err == GRUB_ERR_BAD_FS) + { + grub_device_close (dev); + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (err) + { + grub_device_close (dev); + grub_print_error (); + return 0; + } + if (f_id != id) + { + grub_device_close (dev); + return 0; + } + + dev_found = dev; + return 1; + } + grub_device_iterate (hook); + if (!dev_found) + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find device 0x%" PRIxGRUB_UINT64_T, id); + return GRUB_ERR_NONE; +} + +static grub_err_t +read_dva (const dva_t *dva, + grub_zfs_endian_t endian, struct grub_zfs_data *data, + void *buf, grub_size_t len) +{ + grub_uint64_t offset, sector; + unsigned i; + grub_err_t err; + int try = 0; + + for (try = 0; try < 1; try++) + { + for (i = 0; i < data->n_devices_attached; i++) + if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) + { + /* read in a data block */ + offset = dva_get_offset (dva, endian); + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); + return grub_disk_read (data->devices_attached[i].disk, sector, + 0, len, buf); + } + err = scan_devices (data, DVA_GET_VDEV (dva)); + if (err) + return err; + } + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find device 0x%" PRIxGRUB_UINT64_T, + DVA_GET_VDEV (dva)); +} /* * Read a block of data based on the gang block address dva, @@ -428,7 +789,6 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, struct grub_zfs_data *data) { zio_gbh_phys_t *zio_gb; - grub_uint64_t offset, sector; unsigned i; grub_err_t err; zio_cksum_t zc; @@ -440,13 +800,8 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, return grub_errno; grub_dprintf ("zfs", endian == LITTLE_ENDIAN ? "little-endian gang\n" :"big-endian gang\n"); - offset = dva_get_offset (dva, endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - grub_dprintf ("zfs", "offset=%llx\n", (unsigned long long) offset); - /* read in the gang block header */ - err = grub_disk_read (data->disk, sector, 0, SPA_GANGBLOCKSIZE, - (char *) zio_gb); + err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE); if (err) { grub_free (zio_gb); @@ -499,20 +854,13 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, /* pick a good dva from the block pointer */ for (i = 0; i < SPA_DVAS_PER_BP; i++) { - grub_uint64_t offset, sector; - if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0) continue; if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1) err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data); else - { - /* read in a data block */ - offset = dva_get_offset (&bp->blk_dva[i], endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - err = grub_disk_read (data->disk, sector, 0, psize, buf); - } + err = read_dva (&bp->blk_dva[i], endian, data, buf, psize); if (!err) return GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE; @@ -1888,128 +2236,6 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, return ret; } -static grub_err_t -zfs_fetch_nvlist (struct grub_zfs_data * data, char **nvlist) -{ - grub_err_t err; - - *nvlist = grub_malloc (VDEV_PHYS_SIZE); - /* Read in the vdev name-value pair list (112K). */ - err = grub_disk_read (data->disk, data->vdev_phys_sector, 0, - VDEV_PHYS_SIZE, *nvlist); - if (err) - { - grub_free (*nvlist); - *nvlist = 0; - return err; - } - return GRUB_ERR_NONE; -} - -/* - * Check the disk label information and retrieve needed vdev name-value pairs. - * - */ -static grub_err_t -check_pool_label (struct grub_zfs_data *data) -{ - grub_uint64_t pool_state, txg = 0; - char *nvlist; -#if 0 - char *nv; -#endif - grub_uint64_t diskguid; - grub_uint64_t version; - int found; - grub_err_t err; - - err = zfs_fetch_nvlist (data, &nvlist); - if (err) - return err; - - grub_dprintf ("zfs", "check 2 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, - &pool_state); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 3 passed\n"); - - if (pool_state == POOL_STATE_DESTROYED) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); - } - grub_dprintf ("zfs", "check 4 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); - if (!found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 6 passed\n"); - - /* not an active device */ - if (txg == 0) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); - } - grub_dprintf ("zfs", "check 7 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, - &version); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 8 passed\n"); - - if (version > SPA_VERSION) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "too new version %llu > %llu", - (unsigned long long) version, - (unsigned long long) SPA_VERSION); - } - grub_dprintf ("zfs", "check 9 passed\n"); -#if 0 - if (nvlist_lookup_value (nvlist, ZPOOL_CONFIG_VDEV_TREE, &nv, - DATA_TYPE_NVLIST, NULL)) - { - grub_free (vdev); - return (GRUB_ERR_BAD_FS); - } - grub_dprintf ("zfs", "check 10 passed\n"); -#endif - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 11 passed\n"); - - grub_free (nvlist); - - return GRUB_ERR_NONE; -} - static void zfs_unmount (struct grub_zfs_data *data) { @@ -2028,13 +2254,11 @@ static struct grub_zfs_data * zfs_mount (grub_device_t dev) { struct grub_zfs_data *data = 0; - int label = 0; - uberblock_phys_t *ub_array, *ubbest = NULL; - vdev_boot_header_t *bh; + grub_err_t err; objset_phys_t *osp = 0; grub_size_t ospsize; - grub_err_t err; - int vdevnum; + grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + uberblock_t *ub; if (! dev->disk) { @@ -2042,118 +2266,56 @@ zfs_mount (grub_device_t dev) return 0; } - data = grub_malloc (sizeof (*data)); + data = grub_zalloc (sizeof (*data)); if (!data) return 0; - grub_memset (data, 0, sizeof (*data)); #if 0 /* if it's our first time here, zero the best uberblock out */ if (data->best_drive == 0 && data->best_part == 0 && find_best_root) grub_memset (¤t_uberblock, 0, sizeof (uberblock_t)); #endif - data->disk = dev->disk; - - ub_array = grub_malloc (VDEV_UBERBLOCK_RING); - if (!ub_array) + data->n_devices_allocated = 16; + data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) + * data->n_devices_allocated); + data->n_devices_attached = 0; + err = scan_disk (dev->disk, data, NULL); + if (err) { zfs_unmount (data); - return 0; + return NULL; } - bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); - if (!bh) + ub = &(data->devices_attached[0].current_uberblock); + ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, + LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? LITTLE_ENDIAN : BIG_ENDIAN); + + err = zio_read (&ub->ub_rootbp, ub_endian, + (void **) &osp, &ospsize, data); + if (err) { zfs_unmount (data); - grub_free (ub_array); - return 0; + return NULL; } - vdevnum = VDEV_LABELS; - - /* Don't check back labels on CDROM. */ - if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) - vdevnum = VDEV_LABELS / 2; - - for (label = 0; ubbest == NULL && label < vdevnum; label++) + if (ospsize < OBJSET_PHYS_SIZE_V14) { - grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; - grub_dprintf ("zfs", "label %d\n", label); - - data->vdev_phys_sector - = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) - + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) - + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (dev->disk) - - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); - - /* Read in the uberblock ring (128K). */ - err = grub_disk_read (data->disk, data->vdev_phys_sector - + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), - 0, VDEV_UBERBLOCK_RING, (char *) ub_array); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - grub_dprintf ("zfs", "label ok %d\n", label); - - ubbest = find_bestub (ub_array, data->vdev_phys_sector); - if (!ubbest) - { - grub_dprintf ("zfs", "No uberblock found\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - ub_endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_magic, - LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? LITTLE_ENDIAN : BIG_ENDIAN); - err = zio_read (&ubbest->ubp_uberblock.ub_rootbp, - ub_endian, - (void **) &osp, &ospsize, data); - if (err) - { - grub_dprintf ("zfs", "couldn't zio_read\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - - if (ospsize < OBJSET_PHYS_SIZE_V14) - { - grub_dprintf ("zfs", "osp too small\n"); - grub_free (osp); - continue; - } - grub_dprintf ("zfs", "ubbest %p\n", ubbest); - - err = check_pool_label (data); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } -#if 0 - if (find_best_root && - vdev_uberblock_compare (&ubbest->ubp_uberblock, - &(current_uberblock)) <= 0) - continue; -#endif - /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); - data->mos.endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_rootbp.blk_prop, ub_endian) >> 63) & 1; - grub_memmove (&(data->current_uberblock), - &ubbest->ubp_uberblock, sizeof (uberblock_t)); - grub_free (ub_array); - grub_free (bh); + grub_error (GRUB_ERR_BAD_FS, "OSP too small"); grub_free (osp); - return data; + zfs_unmount (data); + return NULL; } - grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); - zfs_unmount (data); - grub_free (ub_array); - grub_free (bh); + + /* Got the MOS. Save it at the memory addr MOS. */ + grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); + data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop, + ub_endian) >> 63) & 1; grub_free (osp); - return 0; + data->mounted = 1; + + return data; } grub_err_t @@ -2165,7 +2327,7 @@ grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) zfs = zfs_mount (dev); if (!zfs) return grub_errno; - err = zfs_fetch_nvlist (zfs, nvlist); + err = zfs_fetch_nvlist (&zfs->devices_attached[0], nvlist); zfs_unmount (zfs); return err; } @@ -2181,7 +2343,7 @@ zfs_label (grub_device_t device, char **label) if (! data) return grub_errno; - err = zfs_fetch_nvlist (data, &nvlist); + err = zfs_fetch_nvlist (data->devices_attached, &nvlist); if (err) { zfs_unmount (data); @@ -2197,11 +2359,7 @@ zfs_label (grub_device_t device, char **label) static grub_err_t zfs_uuid (grub_device_t device, char **uuid) { - char *nvlist; - int found; struct grub_zfs_data *data; - grub_uint64_t guid; - grub_err_t err; *uuid = 0; @@ -2209,18 +2367,7 @@ zfs_uuid (grub_device_t device, char **uuid) if (! data) return grub_errno; - err = zfs_fetch_nvlist (data, &nvlist); - if (err) - { - zfs_unmount (data); - return err; - } - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); - if (! found) - return grub_errno; - grub_free (nvlist); - *uuid = grub_xasprintf ("%016llx", (long long unsigned) guid); + *uuid = grub_xasprintf ("%016llx", (long long unsigned) data->guid); zfs_unmount (data); if (! *uuid) return grub_errno; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 2fcde4ab0..122465d7a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -60,6 +60,7 @@ execute_command (char *name, int n, char **args) #define CMD_HEX 4 #define CMD_CRC 6 #define CMD_BLOCKLIST 7 +#define CMD_ZFSINFO 8 #define BUF_SIZE 32256 @@ -309,6 +310,9 @@ fstest (int n, char **args) case CMD_LS: execute_command ("ls", n, args); break; + case CMD_ZFSINFO: + execute_command ("zfsinfo", n, args); + break; case CMD_CP: cmd_cp (args[0], args[1]); break; @@ -454,6 +458,10 @@ argp_parser (int key, char *arg, struct argp_state *state) { cmd = CMD_LS; } + else if (!grub_strcmp (arg, "zfsinfo")) + { + cmd = CMD_ZFSINFO; + } else if (!grub_strcmp (arg, "cp")) { cmd = CMD_CP; From 8ff84951c5c8d09011caec8bf77c67e55414ec30 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 02:31:22 +0100 Subject: [PATCH 0453/1414] ZFS mirror support --- grub-core/fs/zfs/zfs.c | 299 +++++++++++++++++++++++++++++------------ include/grub/zfs/zfs.h | 12 +- 2 files changed, 221 insertions(+), 90 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3163e2e78..b5f25473f 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -140,11 +140,19 @@ typedef struct dnode_end struct grub_zfs_device_desc { - enum { DEVICE_LEAF } type; - grub_disk_t disk; + enum { DEVICE_LEAF, DEVICE_MIRROR } type; grub_uint64_t id; + grub_uint64_t guid; + + /* Valid only for non-leafs. */ + unsigned n_children; + struct grub_zfs_device_desc *children; + + /* Valid only for leaf devices. */ + grub_device_t dev; grub_disk_addr_t vdev_phys_sector; uberblock_t current_uberblock; + int original; }; struct grub_zfs_data @@ -169,6 +177,8 @@ struct grub_zfs_data unsigned n_devices_attached; unsigned n_devices_allocated; + uberblock_t current_uberblock; + int mounted; grub_uint64_t guid; }; @@ -434,8 +444,11 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) grub_err_t err; *nvlist = grub_malloc (VDEV_PHYS_SIZE); + if (!diskdesc->dev) + return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); + /* Read in the vdev name-value pair list (112K). */ - err = grub_disk_read (diskdesc->disk, diskdesc->vdev_phys_sector, 0, + err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0, VDEV_PHYS_SIZE, *nvlist); if (err) { @@ -447,41 +460,129 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) } static grub_err_t -fill_vdev_info (char *nvlist, struct grub_zfs_device_desc *diskdesc) +fill_vdev_info_real (const char *nvlist, + struct grub_zfs_device_desc *fill, + struct grub_zfs_device_desc *insert) { - char *type = 0; + char *type; type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); if (!type) return grub_errno; + + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &(fill->id))) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) { - diskdesc->type = DEVICE_LEAF; - if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &diskdesc->id)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + fill->type = DEVICE_LEAF; + + if (!fill->dev && fill->guid == insert->guid) + { + fill->dev = insert->dev; + fill->vdev_phys_sector = insert->vdev_phys_sector; + fill->current_uberblock = insert->current_uberblock; + fill->original = insert->original; + } return GRUB_ERR_NONE; } + + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + { + int nelm, i; + + fill->type = DEVICE_MIRROR; + + nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); + + if (nelm <= 0) + return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); + + fill->n_children = nelm; + + fill->children = grub_zalloc (fill->n_children + * sizeof (fill->children[0])); + + for (i = 0; i < nelm; i++) + { + char *child; + grub_err_t err; + + child = grub_zfs_nvlist_lookup_nvlist_array + (nvlist, ZPOOL_CONFIG_CHILDREN, i); + + err = fill_vdev_info_real (child, &fill->children[i], insert); + + grub_free (child); + + if (err) + return err; + } + return GRUB_ERR_NONE; + } + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", type); } +static grub_err_t +fill_vdev_info (struct grub_zfs_data *data, + char *nvlist, struct grub_zfs_device_desc *diskdesc) +{ + grub_uint64_t id; + unsigned i; + + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &id)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + + for (i = 0; i < data->n_devices_attached; i++) + if (data->devices_attached[i].id == id) + return fill_vdev_info_real (nvlist, &data->devices_attached[i], + diskdesc); + + data->n_devices_attached++; + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; + data->n_devices_allocated = 2 * data->n_devices_attached + 1; + data->devices_attached + = grub_realloc (tmp = data->devices_attached, + data->n_devices_allocated + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + data->devices_attached = tmp; + return grub_errno; + } + } + + grub_memset (&data->devices_attached[data->n_devices_attached - 1], + 0, sizeof (data->devices_attached[data->n_devices_attached - 1])); + + return fill_vdev_info_real (nvlist, + &data->devices_attached[data->n_devices_attached - 1], + diskdesc); +} + /* * Check the disk label information and retrieve needed vdev name-value pairs. * */ static grub_err_t check_pool_label (struct grub_zfs_data *data, - struct grub_zfs_device_desc *diskdesc, - grub_uint64_t *id) + struct grub_zfs_device_desc *diskdesc) { grub_uint64_t pool_state, txg = 0; char *nvlist; #if 0 char *nv; #endif - grub_uint64_t diskguid, poolguid; + grub_uint64_t poolguid; grub_uint64_t version; int found; grub_err_t err; @@ -549,25 +650,8 @@ check_pool_label (struct grub_zfs_data *data, } grub_dprintf ("zfs", "check 9 passed\n"); - { - char *nv; - nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); - - if (!nv) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); - } - err = fill_vdev_info (nv, diskdesc); - if (err) - { - grub_free (nvlist); - return err; - } - } - grub_dprintf ("zfs", "check 10 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, &diskguid); + found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, + &(diskdesc->guid)); if (! found) { grub_free (nvlist); @@ -592,34 +676,33 @@ check_pool_label (struct grub_zfs_data *data, return grub_error (GRUB_ERR_BAD_FS, "another zpool"); else data->guid = poolguid; + + { + char *nv; + nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); + + if (!nv) + { + grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); + } + err = fill_vdev_info (data, nv, diskdesc); + if (err) + { + grub_free (nvlist); + return err; + } + } + grub_dprintf ("zfs", "check 10 passed\n"); + grub_free (nvlist); - data->n_devices_attached++; - if (data->n_devices_attached > data->n_devices_allocated) - { - void *tmp; - data->n_devices_allocated = 2 * data->n_devices_attached + 1; - data->devices_attached - = grub_realloc (tmp = data->devices_attached, - data->n_devices_allocated - * sizeof (data->devices_attached[0])); - if (!data->devices_attached) - { - data->devices_attached = tmp; - return grub_errno; - } - } - - data->devices_attached[data->n_devices_attached - 1] = *diskdesc; - if (id) - *id = diskdesc->id; - return GRUB_ERR_NONE; } static grub_err_t -scan_disk (grub_disk_t disk, struct grub_zfs_data *data, - grub_uint64_t *id) +scan_disk (grub_device_t dev, struct grub_zfs_data *data, + int original) { int label = 0; uberblock_phys_t *ub_array, *ubbest = NULL; @@ -641,24 +724,23 @@ scan_disk (grub_disk_t disk, struct grub_zfs_data *data, vdevnum = VDEV_LABELS; - desc.disk = disk; + desc.dev = dev; + desc.original = original; /* Don't check back labels on CDROM. */ - if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN) + if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) vdevnum = VDEV_LABELS / 2; for (label = 0; ubbest == NULL && label < vdevnum; label++) { - grub_dprintf ("zfs", "label %d\n", label); - desc.vdev_phys_sector = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) - + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (disk) + + (label < VDEV_LABELS / 2 ? 0 : grub_disk_get_size (dev->disk) - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); /* Read in the uberblock ring (128K). */ - err = grub_disk_read (disk, desc.vdev_phys_sector + err = grub_disk_read (dev->disk, desc.vdev_phys_sector + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), 0, VDEV_UBERBLOCK_RING, (char *) ub_array); if (err) @@ -678,8 +760,11 @@ scan_disk (grub_disk_t disk, struct grub_zfs_data *data, grub_memmove (&(desc.current_uberblock), &ubbest->ubp_uberblock, sizeof (uberblock_t)); + if (original) + grub_memmove (&(data->current_uberblock), + &ubbest->ubp_uberblock, sizeof (uberblock_t)); - err = check_pool_label (data, &desc, id); + err = check_pool_label (data, &desc); if (err) { grub_errno = GRUB_ERR_NONE; @@ -711,7 +796,6 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) { grub_device_t dev; grub_err_t err; - grub_uint64_t f_id = -1; dev = grub_device_open (name); if (!dev) return 0; @@ -720,7 +804,7 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) grub_device_close (dev); return 0; } - err = scan_disk (dev->disk, data, &f_id); + err = scan_disk (dev, data, 0); if (err == GRUB_ERR_BAD_FS) { grub_device_close (dev); @@ -733,11 +817,6 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) grub_print_error (); return 0; } - if (f_id != id) - { - grub_device_close (dev); - return 0; - } dev_found = dev; return 1; @@ -749,6 +828,36 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) return GRUB_ERR_NONE; } +static grub_err_t +read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, + grub_size_t len, void *buf) +{ + switch (desc->type) + { + case DEVICE_LEAF: + if (!desc->dev) + return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); + /* read in a data block */ + return grub_disk_read (desc->dev->disk, sector, 0, len, buf); + case DEVICE_MIRROR: + { + grub_err_t err; + unsigned i; + for (i = 0; i < desc->n_children; i++) + { + err = read_device (sector, &desc->children[i], + len, buf); + if (!err) + break; + grub_errno = GRUB_ERR_NONE; + } + return (grub_errno = err); + } + default: + return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); + } +} + static grub_err_t read_dva (const dva_t *dva, grub_zfs_endian_t endian, struct grub_zfs_data *data, @@ -758,18 +867,15 @@ read_dva (const dva_t *dva, unsigned i; grub_err_t err; int try = 0; + offset = dva_get_offset (dva, endian); + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); for (try = 0; try < 1; try++) { for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) - { - /* read in a data block */ - offset = dva_get_offset (dva, endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - return grub_disk_read (data->devices_attached[i].disk, sector, - 0, len, buf); - } + return read_device (sector, &data->devices_attached[i], + len, buf); err = scan_devices (data, DVA_GET_VDEV (dva)); if (err) return err; @@ -2026,11 +2132,12 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, */ static int -nvlist_find_value (char *nvlist, char *name, int valtype, char **val, +nvlist_find_value (const char *nvlist, const char *name, + int valtype, char **val, grub_size_t *size_out, grub_size_t *nelm_out) { int name_len, type, encode_size; - char *nvpair, *nvp_name; + const char *nvpair, *nvp_name; /* Verify if the 1st and 2nd byte in the nvlist are valid. */ /* NOTE: independently of what endianness header announces all @@ -2072,7 +2179,7 @@ nvlist_find_value (char *nvlist, char *name, int valtype, char **val, if ((grub_strncmp (nvp_name, name, name_len) == 0) && type == valtype) { - *val = nvpair; + *val = (char *) nvpair; *size_out = encode_size; if (nelm_out) *nelm_out = nelm; @@ -2085,7 +2192,8 @@ nvlist_find_value (char *nvlist, char *name, int valtype, char **val, } int -grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t * out) +grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, + grub_uint64_t * out) { char *nvpair; grub_size_t size; @@ -2105,7 +2213,7 @@ grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, grub_uint64_t * out) } char * -grub_zfs_nvlist_lookup_string (char *nvlist, char *name) +grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name) { char *nvpair; char *ret; @@ -2133,7 +2241,7 @@ grub_zfs_nvlist_lookup_string (char *nvlist, char *name) } char * -grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name) +grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name) { char *nvpair; char *ret; @@ -2154,7 +2262,8 @@ grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name) } int -grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) +grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, + const char *name) { char *nvpair; grub_size_t nelm, size; @@ -2168,9 +2277,9 @@ grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name) } static int -get_nvlist_size (char *beg, char *limit) +get_nvlist_size (const char *beg, const char *limit) { - char *ptr; + const char *ptr; grub_uint32_t encode_size; ptr = beg + 8; @@ -2183,7 +2292,7 @@ get_nvlist_size (char *beg, char *limit) } char * -grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, +grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name, grub_size_t index) { char *nvpair, *nvpairptr; @@ -2236,9 +2345,29 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, return ret; } +static void +unmount_device (struct grub_zfs_device_desc *desc) +{ + unsigned i; + switch (desc->type) + { + case DEVICE_LEAF: + if (!desc->original && desc->dev) + grub_device_close (desc->dev); + return; + case DEVICE_MIRROR: + for (i = 0; i < desc->n_children; i++) + unmount_device (&desc->children[i]); + return; + } +} + static void zfs_unmount (struct grub_zfs_data *data) { + unsigned i; + for (i = 0; i < data->n_devices_attached; i++) + unmount_device (&data->devices_attached[i]); grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); @@ -2279,14 +2408,14 @@ zfs_mount (grub_device_t dev) data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) * data->n_devices_allocated); data->n_devices_attached = 0; - err = scan_disk (dev->disk, data, NULL); + err = scan_disk (dev, data, 1); if (err) { zfs_unmount (data); return NULL; } - ub = &(data->devices_attached[0].current_uberblock); + ub = &(data->current_uberblock); ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC ? LITTLE_ENDIAN : BIG_ENDIAN); diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 057692573..e1759dbbd 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -112,12 +112,14 @@ grub_err_t grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist); grub_err_t grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, grub_uint64_t *mdnobj); -char *grub_zfs_nvlist_lookup_string (char *nvlist, char *name); -char *grub_zfs_nvlist_lookup_nvlist (char *nvlist, char *name); -int grub_zfs_nvlist_lookup_uint64 (char *nvlist, char *name, +char *grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name); +char *grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name); +int grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, grub_uint64_t *out); -char *grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name, +char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, + const char *name, grub_size_t index); -int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name); +int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, + const char *name); #endif /* ! GRUB_ZFS_HEADER */ From 925d998e6f9eb04c92465246b6fe458128bafb65 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 07:03:58 +0100 Subject: [PATCH 0454/1414] Fix a warining --- grub-core/fs/zfs/zfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index b5f25473f..b23490c92 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -843,6 +843,9 @@ read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, { grub_err_t err; unsigned i; + if (desc->n_children <= 0) + return grub_error (GRUB_ERR_BAD_FS, + "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { err = read_device (sector, &desc->children[i], From 79282228ec14e6509d1c6df5eb0ec9a7ee67a3f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 20:26:49 +0100 Subject: [PATCH 0455/1414] use anopther RAID1(0) copy if main one fails --- grub-core/fs/btrfs.c | 86 +++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7e31fa3f1..b7edb7e39 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -491,7 +491,8 @@ lower_bound (struct grub_btrfs_data *data, } static grub_device_t -find_device (struct grub_btrfs_data *data, grub_uint64_t id) +find_device (struct grub_btrfs_data *data, grub_uint64_t id, + int do_rescan) { grub_device_t dev_found = NULL; auto int hook (const char *name); @@ -537,7 +538,8 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id) for (i = 0; i < data->n_devices_attached; i++) if (id == data->devices_attached[i].id) return data->devices_attached[i].dev; - grub_device_iterate (hook); + if (do_rescan) + grub_device_iterate (hook); if (!dev_found) { grub_error (GRUB_ERR_BAD_FS, "couldn't find a member device"); @@ -574,7 +576,6 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_uint8_t *ptr; struct grub_btrfs_key *key; struct grub_btrfs_chunk_item *chunk; - struct grub_btrfs_chunk_stripe *stripe; grub_ssize_t csize; grub_err_t err; struct grub_btrfs_key key_out; @@ -598,7 +599,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, + grub_le_to_cpu64 (chunk->size)) goto chunk_found; ptr += sizeof (*key) + sizeof (*chunk) - + sizeof (*stripe) * grub_le_to_cpu16 (chunk->nstripes); + + sizeof (struct grub_btrfs_chunk_stripe) + * grub_le_to_cpu16 (chunk->nstripes); } struct grub_btrfs_key key_in; grub_size_t chsize; @@ -634,9 +636,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_uint32_t stripen; grub_uint32_t stripe_offset; grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); - grub_disk_addr_t paddr; + unsigned redundancy = 1; + unsigned i, j; - stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); switch (grub_le_to_cpu64 (chunk->type) & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE) { @@ -661,6 +663,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, stripen = 0; stripe_offset = off; csize = stripe_length - off; + redundancy = 2; break; } case GRUB_BTRFS_CHUNK_TYPE_RAID0: @@ -692,6 +695,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, &stripen); stripen *= grub_le_to_cpu16 (chunk->nstripes) / grub_le_to_cpu16 (chunk->nsubstripes); + redundancy = grub_le_to_cpu16 (chunk->nstripes) + / grub_le_to_cpu16 (chunk->nsubstripes); stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) * high; csize = grub_le_to_cpu64 (chunk->stripe_length) - low; @@ -702,35 +707,60 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, "unsupported RAID flags %" PRIxGRUB_UINT64_T, grub_le_to_cpu64 (chunk->type)); } - stripe += stripen; if (csize <= 0) return grub_error (GRUB_ERR_BAD_FS, "couldn't find the chunk descriptor"); if ((grub_size_t) csize > size) csize = size; - dev = find_device (data, stripe->device_id); - if (!dev) - return grub_errno; - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" - PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT32_T - " maps to 0x%" PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (key->offset), - grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - grub_le_to_cpu16 (chunk->nsubstripes), - grub_le_to_cpu64 (chunk->stripe_length), - stripen, - stripe->offset); - paddr = stripe->offset + stripe_offset; - grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, - addr); - err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, - paddr & (GRUB_DISK_SECTOR_SIZE - 1), csize, buf); + for (j = 0; j < 2; j++) + { + for (i = 0; i < redundancy; i++) + { + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + /* Right now the redundancy handlind is easy. + With RAID5-like it will be more difficult. */ + stripe += stripen + i; + + paddr = stripe->offset + stripe_offset; + + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT32_T + " maps to 0x%" PRIxGRUB_UINT64_T "\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu64 (chunk->stripe_length), + stripen, stripe->offset); + grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T + " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, + addr); + + dev = find_device (data, stripe->device_id, j); + if (!dev) + { + err = grub_errno; + grub_errno = GRUB_ERR_NONE; + continue; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buf); + if (!err) + break; + grub_errno = GRUB_ERR_NONE; + } + if (i != redundancy) + break; + } if (err) - return err; + return grub_errno = err; } size -= csize; buf = (grub_uint8_t *) buf + csize; From c3b87afcd47d0ad5e4fa8f14c551ce3593c649f4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 20:28:02 +0100 Subject: [PATCH 0456/1414] Recognize vdev file --- grub-core/fs/zfs/zfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index b23490c92..1dab363b2 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -477,7 +477,8 @@ fill_vdev_info_real (const char *nvlist, if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); - if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) + if (grub_strcmp (type, VDEV_TYPE_DISK) == 0 + || grub_strcmp (type, VDEV_TYPE_FILE) == 0) { fill->type = DEVICE_LEAF; From 39db1a3f75047d1a665c7d1c194a134b31b1ee0a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 6 Dec 2010 23:46:01 +0100 Subject: [PATCH 0457/1414] First attempt on RAIDZ. Right now works only with right phase of the moon. --- grub-core/fs/zfs/zfs.c | 122 +++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1dab363b2..23e9c7b36 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -140,7 +140,7 @@ typedef struct dnode_end struct grub_zfs_device_desc { - enum { DEVICE_LEAF, DEVICE_MIRROR } type; + enum { DEVICE_LEAF, DEVICE_MIRROR, DEVICE_RAIDZ } type; grub_uint64_t id; grub_uint64_t guid; @@ -148,6 +148,9 @@ struct grub_zfs_device_desc unsigned n_children; struct grub_zfs_device_desc *children; + /* Valid only for RAIDZ. */ + unsigned nparity; + /* Valid only for leaf devices. */ grub_device_t dev; grub_disk_addr_t vdev_phys_sector; @@ -290,13 +293,13 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, || (actual_cksum.zc_word[2] != zc.zc_word[2]) || (actual_cksum.zc_word[3] != zc.zc_word[3])) { - grub_dprintf ("zfs", "checksum %d verification failed\n", checksum); - grub_dprintf ("zfs", "actual checksum %16llx %16llx %16llx %16llx\n", + grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name); + grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n", (unsigned long long) actual_cksum.zc_word[0], (unsigned long long) actual_cksum.zc_word[1], (unsigned long long) actual_cksum.zc_word[2], (unsigned long long) actual_cksum.zc_word[3]); - grub_dprintf ("zfs", "expected checksum %16llx %16llx %16llx %16llx\n", + grub_dprintf ("zfs", "expected checksum %016llx %016llx %016llx %016llx\n", (unsigned long long) zc.zc_word[0], (unsigned long long) zc.zc_word[1], (unsigned long long) zc.zc_word[2], @@ -493,21 +496,34 @@ fill_vdev_info_real (const char *nvlist, return GRUB_ERR_NONE; } - if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0 + || grub_strcmp (type, VDEV_TYPE_RAIDZ) == 0) { int nelm, i; - fill->type = DEVICE_MIRROR; + if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) + fill->type = DEVICE_MIRROR; + else + { + grub_uint64_t par; + fill->type = DEVICE_RAIDZ; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); + fill->nparity = par; + } nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); if (nelm <= 0) return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); - fill->n_children = nelm; - - fill->children = grub_zalloc (fill->n_children - * sizeof (fill->children[0])); + if (!fill->children) + { + fill->n_children = nelm; + + fill->children = grub_zalloc (fill->n_children + * sizeof (fill->children[0])); + } for (i = 0; i < nelm; i++) { @@ -789,9 +805,8 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, } static grub_err_t -scan_devices (struct grub_zfs_data *data, grub_uint64_t id) +scan_devices (struct grub_zfs_data *data) { - grub_device_t dev_found = NULL; auto int hook (const char *name); int hook (const char *name) { @@ -819,27 +834,29 @@ scan_devices (struct grub_zfs_data *data, grub_uint64_t id) return 0; } - dev_found = dev; - return 1; + return 0; } grub_device_iterate (hook); - if (!dev_found) - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find device 0x%" PRIxGRUB_UINT64_T, id); return GRUB_ERR_NONE; } static grub_err_t -read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, +read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t len, void *buf) { switch (desc->type) { case DEVICE_LEAF: - if (!desc->dev) - return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); - /* read in a data block */ - return grub_disk_read (desc->dev->disk, sector, 0, len, buf); + { + grub_uint64_t sector; + sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); + if (!desc->dev) + { + return grub_error (GRUB_ERR_BAD_FS, "member drive unknown"); + } + /* read in a data block */ + return grub_disk_read (desc->dev->disk, sector, 0, len, buf); + } case DEVICE_MIRROR: { grub_err_t err; @@ -849,7 +866,7 @@ read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { - err = read_device (sector, &desc->children[i], + err = read_device (offset, &desc->children[i], len, buf); if (!err) break; @@ -857,9 +874,41 @@ read_device (grub_uint64_t sector, struct grub_zfs_device_desc *desc, } return (grub_errno = err); } - default: - return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); + case DEVICE_RAIDZ: + { + grub_uint64_t sector; + grub_uint64_t high; + grub_uint32_t devn; + if (desc->n_children <= 0) + return grub_error (GRUB_ERR_BAD_FS, + "non-positive number of mirror children"); + offset += 512; + + sector = offset >> 9; + high = grub_divmod64 (sector, desc->n_children, &devn); + + while (len > 0) + { + grub_size_t csize; + grub_err_t err; + + csize = 0x200 * desc->n_children - (offset & 0x1ff); + if (csize > len) + csize = len; + + err = read_device (high << 9, &desc->children[devn], + csize, buf); + if (err) + return err; + len -= csize; + buf = (grub_uint8_t *) buf + csize; + devn = (devn + 1) % desc->n_children; + high++; + } + } + return GRUB_ERR_NONE; } + return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); } static grub_err_t @@ -867,26 +916,30 @@ read_dva (const dva_t *dva, grub_zfs_endian_t endian, struct grub_zfs_data *data, void *buf, grub_size_t len) { - grub_uint64_t offset, sector; + grub_uint64_t offset; unsigned i; grub_err_t err; int try = 0; offset = dva_get_offset (dva, endian); - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - for (try = 0; try < 1; try++) + for (try = 0; try < 2; try++) { for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) - return read_device (sector, &data->devices_attached[i], - len, buf); - err = scan_devices (data, DVA_GET_VDEV (dva)); + { + err = read_device (offset, &data->devices_attached[i], + len, buf); + if (!err) + return GRUB_ERR_NONE; + break; + } + if (try == 1) + break; + err = scan_devices (data); if (err) return err; } - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find device 0x%" PRIxGRUB_UINT64_T, - DVA_GET_VDEV (dva)); + return err; } /* @@ -2359,6 +2412,7 @@ unmount_device (struct grub_zfs_device_desc *desc) if (!desc->original && desc->dev) grub_device_close (desc->dev); return; + case DEVICE_RAIDZ: case DEVICE_MIRROR: for (i = 0; i < desc->n_children; i++) unmount_device (&desc->children[i]); From bfff320cdfd27c197dec74cdff9c258098acadb3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 7 Dec 2010 11:45:37 +0100 Subject: [PATCH 0458/1414] Apparently functioning raidz. Still mostly a guesswork so may break --- grub-core/fs/zfs/zfs.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 23e9c7b36..e41067c38 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -842,7 +842,7 @@ scan_devices (struct grub_zfs_data *data) static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - grub_size_t len, void *buf) + grub_uint32_t asize, grub_size_t len, void *buf) { switch (desc->type) { @@ -866,7 +866,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { - err = read_device (offset, &desc->children[i], + err = read_device (offset, &desc->children[i], asize, len, buf); if (!err) break; @@ -877,35 +877,35 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, case DEVICE_RAIDZ: { grub_uint64_t sector; - grub_uint64_t high; - grub_uint32_t devn; - if (desc->n_children <= 0) - return grub_error (GRUB_ERR_BAD_FS, - "non-positive number of mirror children"); - offset += 512; + grub_uint32_t bsize; + unsigned c = 0; + bsize = (asize + desc->nparity) / desc->n_children; sector = offset >> 9; - high = grub_divmod64 (sector, desc->n_children, &devn); - while (len > 0) { grub_size_t csize; + grub_uint64_t high; + grub_uint32_t devn; grub_err_t err; - - csize = 0x200 * desc->n_children - (offset & 0x1ff); + high = grub_divmod64 (sector + (asize > 2) + c, desc->n_children, + &devn); + csize = bsize << 9; if (csize > len) csize = len; - + grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T + "+%d+%u -> (0x%" PRIxGRUB_UINT64_T ", 0x%x)\n", + sector,(asize > 2), c, high, devn); err = read_device (high << 9, &desc->children[devn], - csize, buf); + bsize, csize, buf); if (err) return err; + c++; + buf = (char *) buf + csize; len -= csize; - buf = (grub_uint8_t *) buf + csize; - devn = (devn + 1) % desc->n_children; - high++; } - } + return GRUB_ERR_NONE; + } return GRUB_ERR_NONE; } return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); @@ -928,7 +928,7 @@ read_dva (const dva_t *dva, if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) { err = read_device (offset, &data->devices_attached[i], - len, buf); + dva->dva_word[0] & 0xffffff, len, buf); if (!err) return GRUB_ERR_NONE; break; From 393324be7c27ee65c3f07de5b5e56f001b8a9ed3 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 8 Dec 2010 16:43:11 +0530 Subject: [PATCH 0459/1414] execute menu editor commands with argument scope --- grub-core/normal/menu_entry.c | 59 +++++++++++++++++------------------ 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 0bb51ca28..4db4a45c1 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1163,37 +1163,35 @@ clear_completions_all (struct screen *screen) static int run (struct screen *screen) { - int currline = 0; - char *nextline; + char *script; int errs_before; grub_menu_t menu; + char *dummy[1] = { NULL }; - auto grub_err_t editor_getline (char **line, int cont); - grub_err_t editor_getline (char **line, int cont __attribute__ ((unused))) - { - struct line *linep = screen->lines + currline; - char *p; + auto char * editor_getsource (void); + char * editor_getsource (void) + { + int i; + int size = 0; + char *source; - if (currline > screen->num_lines) - { - *line = 0; - return 0; - } + for (i = 0; i < screen->num_lines; i++) + size += screen->lines[i].len + 1; - /* Trim down space characters. */ - for (p = linep->buf + linep->len - 1; - p >= linep->buf && grub_isspace (*p); - p--) - ; - *++p = '\0'; + source = grub_malloc (size + 1); + if (! source) + return NULL; - linep->len = p - linep->buf; - for (p = linep->buf; grub_isspace (*p); p++) - ; - *line = grub_strdup (p); - currline++; - return 0; - } + size = 0; + for (i = 0; i < screen->num_lines; i++) + { + grub_strcpy (source + size, screen->lines[i].buf); + size += screen->lines[i].len; + source[size++] = '\n'; + } + source[size] = '\0'; + return source; + } grub_cls (); grub_printf (" "); @@ -1212,12 +1210,11 @@ run (struct screen *screen) } /* Execute the script, line for line. */ - while (currline < screen->num_lines) - { - editor_getline (&nextline, 0); - if (grub_normal_parse_line (nextline, editor_getline)) - break; - } + script = editor_getsource (); + if (! script) + return 0; + grub_script_execute_sourcecode (script, 0, dummy); + grub_free (script); if (errs_before != grub_err_printed_errors) grub_wait_after_message (); From 332fa368872a57f945a7387cc1b931e83f197cb0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 8 Dec 2010 21:22:46 +0100 Subject: [PATCH 0460/1414] 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 0461/1414] 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 0462/1414] 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 0463/1414] 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 a94a667185f093fd953b8775292652bc58b0d5fe Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 9 Dec 2010 14:09:37 +0100 Subject: [PATCH 0464/1414] 2010-12-09 Robert Millan * NEWS: Document addition of ZFS support. --- ChangeLog | 4 ++++ NEWS | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c6e842de..f215398cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-12-09 Robert Millan + + * NEWS: Document addition of ZFS support. + 2010-12-04 Colin Watson * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Use `>> 1' diff --git a/NEWS b/NEWS index 7fce921d6..36e3f25bf 100644 --- a/NEWS +++ b/NEWS @@ -51,9 +51,7 @@ New in 1.99: * Add `sendkey' command (i386-pc only). -* ZFS support in `grub-install' and `grub-mkconfig'. Note: complete - functionality requires external ZFS implementation (available from - grub-extras). +* ZFS support. * Support 1.x versions of mdadm metadata. From 948ebd7e91f29efea22bc4987582efb827940294 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 9 Dec 2010 17:06:49 +0100 Subject: [PATCH 0465/1414] 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 0466/1414] 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 0467/1414] 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 0468/1414] 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 0469/1414] 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 0470/1414] 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 0471/1414] 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 0472/1414] 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 0473/1414] 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 0474/1414] 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 0475/1414] 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 0476/1414] 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 1fb430f865f2c4b367ddce5c45cc1b2f3eaecd34 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 10 Dec 2010 11:45:08 +0000 Subject: [PATCH 0477/1414] * grub-core/gettext/gettext.c (grub_gettext_init_ext): Factor out .mo/.mo.gz opening sequence to ... (grub_mofile_open_lang): ... here. (grub_gettext_init_ext): If opening ll_CC fails, try ll. * util/grub.d/00_header.in (grub_lang): Include country part of locale. Reported by: Mario Limonciello. --- ChangeLog | 10 ++++++++ grub-core/gettext/gettext.c | 48 +++++++++++++++++++++++++++---------- util/grub.d/00_header.in | 2 +- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index f215398cc..e8ac26e83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-12-10 Colin Watson + + * grub-core/gettext/gettext.c (grub_gettext_init_ext): Factor out + .mo/.mo.gz opening sequence to ... + (grub_mofile_open_lang): ... here. + (grub_gettext_init_ext): If opening ll_CC fails, try ll. + * util/grub.d/00_header.in (grub_lang): Include country part of + locale. + Reported by: Mario Limonciello. + 2010-12-09 Robert Millan * NEWS: Document addition of ZFS support. diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 9ab4c3b8d..5c7db4408 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -261,24 +261,16 @@ grub_mofile_open (const char *filename) return fd_mo; } +/* Returning grub_file_t would be more natural, but grub_mofile_open assigns + to fd_mo anyway ... */ static void -grub_gettext_init_ext (const char *lang) +grub_mofile_open_lang (const char *locale_dir, const char *locale) { char *mo_file; - char *locale_dir; - - locale_dir = grub_env_get ("locale_dir"); - if (locale_dir == NULL) - { - grub_dprintf ("gettext", "locale_dir variable is not set up.\n"); - return; - } - - fd_mo = NULL; /* mo_file e.g.: /boot/grub/locale/ca.mo */ - mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang); + mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, locale); if (!mo_file) return; @@ -295,6 +287,38 @@ grub_gettext_init_ext (const char *lang) return; fd_mo = grub_mofile_open (mo_file); } +} + +static void +grub_gettext_init_ext (const char *locale) +{ + char *locale_dir; + + locale_dir = grub_env_get ("locale_dir"); + if (locale_dir == NULL) + { + grub_dprintf ("gettext", "locale_dir variable is not set up.\n"); + return; + } + + fd_mo = NULL; + + grub_mofile_open_lang (locale_dir, locale); + + /* ll_CC didn't work, so try ll. */ + if (fd_mo == NULL) + { + char *lang = grub_strdup (locale); + char *underscore = grub_strchr (lang, '_'); + + if (underscore) + { + *underscore = '\0'; + grub_mofile_open_lang (locale_dir, lang); + } + + grub_free (lang); + } if (fd_mo) { diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 9ed3fc3a1..a596e9c4a 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -23,7 +23,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ locale_dir=`echo ${GRUB_PREFIX}/locale | sed ${transform}` -grub_lang=`echo $LANG | cut -d _ -f 1` +grub_lang=`echo $LANG | cut -d . -f 1` . ${libdir}/grub/grub-mkconfig_lib From 5367ecd3050ebbc8e732b687303f5afc86ac3c62 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 10 Dec 2010 12:56:45 +0000 Subject: [PATCH 0478/1414] * .bzrignore: Ignore grub-core/rs_decoder.S. --- .bzrignore | 1 + ChangeLog | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.bzrignore b/.bzrignore index 7c5597bce..0cbb3f17f 100644 --- a/.bzrignore +++ b/.bzrignore @@ -131,5 +131,6 @@ grub-core/gnulib/unistd.h grub-core/gnulib/warn-on-use.h grub-core/gnulib/wchar.h grub-core/gnulib/wctype.h +grub-core/rs_decoder.S widthspec.bin widthspec.h diff --git a/ChangeLog b/ChangeLog index e8ac26e83..abd1d0400 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-12-10 Colin Watson + + * .bzrignore: Ignore grub-core/rs_decoder.S. + 2010-12-10 Colin Watson * grub-core/gettext/gettext.c (grub_gettext_init_ext): Factor out From d6f07b29fca3f555b22000fde18577a45bd42b39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 14:38:16 +0100 Subject: [PATCH 0479/1414] mtime btrfs support --- grub-core/fs/btrfs.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index b7edb7e39..b7c59065c 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -172,10 +172,18 @@ struct grub_btrfs_root_item grub_uint64_t inode; }; +struct grub_btrfs_time +{ + grub_int64_t sec; + grub_uint32_t nanosec; +} __attribute__ ((aligned(4))); + struct grub_btrfs_inode { - grub_uint8_t dummy[0x10]; + grub_uint8_t dummy1[0x10]; grub_uint64_t size; + grub_uint8_t dummy2[0x70]; + struct grub_btrfs_time mtime; } __attribute__ ((packed)); struct grub_btrfs_extent_data @@ -1263,7 +1271,6 @@ grub_btrfs_dir (grub_device_t device, const char *path, } do { - struct grub_dirhook_info info; struct grub_btrfs_dir_item *cdirel; if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM || key_out.object_id != key_in.object_id) @@ -1295,9 +1302,20 @@ grub_btrfs_dir (grub_device_t device, const char *path, + grub_le_to_cpu16 (cdirel->m))) { char c; + struct grub_btrfs_inode inode; + struct grub_dirhook_info info; + err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, + tree); + grub_memset (&info, 0, sizeof (info)); + if (err) + grub_errno = GRUB_ERR_NONE; + else + { + info.mtime = inode.mtime.sec; + info.mtimeset = 1; + } c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; - grub_memset (&info, 0, sizeof (info)); info.dir = (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY); if (hook (cdirel->name, &info)) goto out; From 3b95531920bdd3bd96706ef6fb01ee6a0cfab8f1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 10 Dec 2010 15:04:12 +0100 Subject: [PATCH 0480/1414] 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 0481/1414] 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 0482/1414] 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 0483/1414] 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 0484/1414] 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 0485/1414] 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 0486/1414] 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 0487/1414] 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 0488/1414] 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 0489/1414] 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 0490/1414] 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 eb03b5527161d9537e914870858d232e1fa277a9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 14:56:02 +0100 Subject: [PATCH 0491/1414] fix ZFS label handling in non-single disk configs --- grub-core/fs/zfs/zfs.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index e41067c38..cafe915c5 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -179,6 +179,7 @@ struct grub_zfs_data struct grub_zfs_device_desc *devices_attached; unsigned n_devices_attached; unsigned n_devices_allocated; + struct grub_zfs_device_desc *device_original; uberblock_t current_uberblock; @@ -463,7 +464,8 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) } static grub_err_t -fill_vdev_info_real (const char *nvlist, +fill_vdev_info_real (struct grub_zfs_data *data, + const char *nvlist, struct grub_zfs_device_desc *fill, struct grub_zfs_device_desc *insert) { @@ -492,6 +494,8 @@ fill_vdev_info_real (const char *nvlist, fill->current_uberblock = insert->current_uberblock; fill->original = insert->original; } + if (!data->device_original) + data->device_original = fill; return GRUB_ERR_NONE; } @@ -533,7 +537,7 @@ fill_vdev_info_real (const char *nvlist, child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, ZPOOL_CONFIG_CHILDREN, i); - err = fill_vdev_info_real (child, &fill->children[i], insert); + err = fill_vdev_info_real (data, child, &fill->children[i], insert); grub_free (child); @@ -559,7 +563,7 @@ fill_vdev_info (struct grub_zfs_data *data, for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == id) - return fill_vdev_info_real (nvlist, &data->devices_attached[i], + return fill_vdev_info_real (data, nvlist, &data->devices_attached[i], diskdesc); data->n_devices_attached++; @@ -581,7 +585,7 @@ fill_vdev_info (struct grub_zfs_data *data, grub_memset (&data->devices_attached[data->n_devices_attached - 1], 0, sizeof (data->devices_attached[data->n_devices_attached - 1])); - return fill_vdev_info_real (nvlist, + return fill_vdev_info_real (data, nvlist, &data->devices_attached[data->n_devices_attached - 1], diskdesc); } @@ -2514,7 +2518,7 @@ grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) zfs = zfs_mount (dev); if (!zfs) return grub_errno; - err = zfs_fetch_nvlist (&zfs->devices_attached[0], nvlist); + err = zfs_fetch_nvlist (zfs->device_original, nvlist); zfs_unmount (zfs); return err; } @@ -2530,7 +2534,7 @@ zfs_label (grub_device_t device, char **label) if (! data) return grub_errno; - err = zfs_fetch_nvlist (data->devices_attached, &nvlist); + err = zfs_fetch_nvlist (data->device_original, &nvlist); if (err) { zfs_unmount (data); From ea0df4e9530965c4ec04982656f27e074aeefac8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 15:01:33 +0100 Subject: [PATCH 0492/1414] ZFS mtime support --- grub-core/fs/zfs/zfs.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index cafe915c5..327e99a90 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -2565,6 +2565,29 @@ zfs_uuid (grub_device_t device, char **uuid) return GRUB_ERR_NONE; } +static grub_err_t +zfs_mtime (grub_device_t device, grub_int32_t *mt) +{ + struct grub_zfs_data *data; + grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + uberblock_t *ub; + + *mt = 0; + + data = zfs_mount (device); + if (! data) + return grub_errno; + + ub = &(data->current_uberblock); + ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, + LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? LITTLE_ENDIAN : BIG_ENDIAN); + + *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian); + zfs_unmount (data); + return GRUB_ERR_NONE; +} + /* * zfs_open() locates a file in the rootpool by following the * MOS and places the dnode of the file in the memory address DNODE. @@ -2934,7 +2957,7 @@ static struct grub_fs grub_zfs_fs = { .close = grub_zfs_close, .label = zfs_label, .uuid = zfs_uuid, - .mtime = 0, + .mtime = zfs_mtime, .next = 0 }; From f5ff296240e8575a35b14fc3ec8ca8263b6161c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 11 Dec 2010 17:46:16 +0100 Subject: [PATCH 0493/1414] 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 0494/1414] 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 0495/1414] 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 0496/1414] 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 0497/1414] 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 0498/1414] 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 0499/1414] 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 0500/1414] 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 0501/1414] 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 0502/1414] 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 0503/1414] 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 0504/1414] 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 0505/1414] 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 0506/1414] (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 e03f549b3e11018b0ec0f44465f6bf5ca98ca993 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 14 Dec 2010 16:22:19 +0000 Subject: [PATCH 0507/1414] Preferred resolution detection for VBE. * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info): New function. (grub_vbe_bios_get_ddc_capabilities): Likewise. (grub_vbe_bios_read_edid): Likewise. (grub_vbe_edid_checksum): Likewise. (grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the Flat Panel extension, in line with the X.org VESA driver. (grub_video_vbe_setup): When the mode is "auto", try to get the preferred mode from VBE, and use the largest mode that is no larger than the preferred mode (some BIOSes expose a preferred mode that is not in their mode list!). If this fails, fall back to 640x480 as a safe conservative choice. * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New structure. (struct grub_vbe_edid_info): Likewise. (grub_vbe_bios_get_flat_panel_info): Add prototype. (grub_vbe_bios_get_ddc_capabilities): Likewise. (grub_vbe_bios_read_edid): Likewise. * util/grub.d/00_header.in (GRUB_GFXMODE): Default to "auto". This is more appropriate on a wider range of platforms than 640x480. --- ChangeLog.vbe-autodetect | 25 ++++++ grub-core/video/i386/pc/vbe.c | 150 +++++++++++++++++++++++++++++++++- include/grub/i386/pc/vbe.h | 84 +++++++++++++++++++ util/grub.d/00_header.in | 2 +- 4 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 ChangeLog.vbe-autodetect diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect new file mode 100644 index 000000000..7d16ebee2 --- /dev/null +++ b/ChangeLog.vbe-autodetect @@ -0,0 +1,25 @@ +2010-12-14 Colin Watson + + Preferred resolution detection for VBE. + + * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info): + New function. + (grub_vbe_bios_get_ddc_capabilities): Likewise. + (grub_vbe_bios_read_edid): Likewise. + (grub_vbe_edid_checksum): Likewise. + (grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the + Flat Panel extension, in line with the X.org VESA driver. + (grub_video_vbe_setup): When the mode is "auto", try to get the + preferred mode from VBE, and use the largest mode that is no larger + than the preferred mode (some BIOSes expose a preferred mode that is + not in their mode list!). If this fails, fall back to 640x480 as a + safe conservative choice. + * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New + structure. + (struct grub_vbe_edid_info): Likewise. + (grub_vbe_bios_get_flat_panel_info): Add prototype. + (grub_vbe_bios_get_ddc_capabilities): Likewise. + (grub_vbe_bios_read_edid): Likewise. + + * util/grub.d/00_header.in (GRUB_GFXMODE): Default to "auto". This + is more appropriate on a wider range of platforms than 640x480. diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 2ddb4ca80..1794addae 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -273,6 +273,56 @@ grub_vbe_bios_get_pm_interface (grub_uint16_t *segment, grub_uint16_t *offset, return regs.eax & 0xffff; } +/* Call VESA BIOS 0x4f11 to get flat panel information, return status. */ +grub_vbe_status_t +grub_vbe_bios_get_flat_panel_info (struct grub_vbe_flat_panel_info *flat_panel_info) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x4f11; + regs.ebx = 0x0001; + regs.es = (((grub_addr_t) flat_panel_info) & 0xffff0000) >> 4; + regs.edi = ((grub_addr_t) flat_panel_info) & 0xffff; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + return regs.eax & 0xffff; +} + +/* Call VESA BIOS 0x4f15 to get DDC availability, return status. */ +grub_vbe_status_t +grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x4f15; + regs.ebx = 0x0000; + regs.ecx = 0x0000; + regs.es = 0x0000; + regs.edi = 0x0000; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + + *level = regs.ebx & 0xff; + return regs.eax & 0xffff; +} + +/* Call VESA BIOS 0x4f15 to read EDID information, return status. */ +grub_vbe_status_t +grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_info) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x4f15; + regs.ebx = 0x0001; + regs.ecx = 0x0000; + regs.edx = 0x0000; + regs.es = (((grub_addr_t) edid_info) & 0xffff0000) >> 4; + regs.edi = ((grub_addr_t) edid_info) & 0xffff; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + return regs.eax & 0xffff; +} + grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block) @@ -327,6 +377,70 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block) return GRUB_ERR_NONE; } +static grub_err_t +grub_vbe_edid_checksum (struct grub_vbe_edid_info *edid_info) +{ + const char *edid_bytes = (const char *) edid_info; + int i; + char checksum = 0; + + /* Check EDID checksum. */ + for (i = 0; i < 128; ++i) + checksum += edid_bytes[i]; + + if (checksum != 0) + return grub_error (GRUB_ERR_BAD_DEVICE, + "invalid EDID checksum %d", checksum); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + +static grub_err_t +grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) +{ + grub_vbe_status_t status; + grub_uint8_t ddc_level; + struct grub_vbe_edid_info edid_info; + struct grub_vbe_flat_panel_info flat_panel_info; + + if (controller_info.version >= 0x200 + && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff) + == GRUB_VBE_STATUS_OK) + { + status = grub_vbe_bios_read_edid (&edid_info); + /* Bit 1 in the Feature Support field indicates that the first + Detailed Timing Description is the preferred timing mode. */ + if (status == GRUB_VBE_STATUS_OK + && grub_vbe_edid_checksum (&edid_info) == GRUB_ERR_NONE + && edid_info.version == 1 /* we don't understand later versions */ + && (edid_info.feature_support + & GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE) + && edid_info.detailed_timings[0].pixel_clock) + { + *width = edid_info.detailed_timings[0].horizontal_active_lo + | (((unsigned int) + (edid_info.detailed_timings[0].horizontal_hi & 0xf0)) + << 4); + *height = edid_info.detailed_timings[0].vertical_active_lo + | (((unsigned int) + (edid_info.detailed_timings[0].vertical_hi & 0xf0)) + << 4); + return GRUB_ERR_NONE; + } + } + + status = grub_vbe_bios_get_flat_panel_info (&flat_panel_info); + if (status == GRUB_VBE_STATUS_OK) + { + *width = flat_panel_info.horizontal_size; + *height = flat_panel_info.vertical_size; + return GRUB_ERR_NONE; + } + + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot get preferred mode"); +} + grub_err_t grub_vbe_set_video_mode (grub_uint32_t vbe_mode, struct grub_vbe_mode_info_block *vbe_mode_info) @@ -695,11 +809,28 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, struct grub_vbe_mode_info_block best_vbe_mode_info; grub_uint32_t best_vbe_mode = 0; int depth; + int preferred_mode = 0; /* 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 == 0 && height == 0) + { + grub_vbe_get_preferred_mode (&width, &height); + if (grub_errno == GRUB_ERR_NONE) + preferred_mode = 1; + else + { + /* Fall back to 640x480. This is conservative, but the largest + mode supported by the graphics card may not be safe for the + display device. */ + grub_errno = GRUB_ERR_NONE; + width = 640; + height = 480; + } + } + /* Walk thru mode list and try to find matching mode. */ for (p = vbe_mode_list; *p != 0xFFFF; p++) { @@ -742,10 +873,21 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, /* Unsupported bitdepth . */ continue; - if (((vbe_mode_info.x_resolution != width) - || (vbe_mode_info.y_resolution != height)) && width != 0 && height != 0) - /* Non matching resolution. */ - continue; + if (preferred_mode) + { + if (vbe_mode_info.x_resolution > width + || vbe_mode_info.y_resolution > height) + /* Resolution exceeds that of preferred mode. */ + continue; + } + else + { + if (((vbe_mode_info.x_resolution != width) + || (vbe_mode_info.y_resolution != height)) + && width != 0 && height != 0) + /* Non matching resolution. */ + continue; + } /* Check if user requested RGB or index color mode. */ if ((mode_mask & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0) diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index fba3ee642..5be34fdec 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -169,6 +169,81 @@ struct grub_vbe_palette_data grub_uint8_t alignment; } __attribute__ ((packed)); +struct grub_vbe_flat_panel_info +{ + grub_uint16_t horizontal_size; + grub_uint16_t vertical_size; + grub_uint16_t panel_type; + grub_uint8_t red_bpp; + grub_uint8_t green_bpp; + grub_uint8_t blue_bpp; + grub_uint8_t reserved_bpp; + grub_uint32_t reserved_offscreen_mem_size; + grub_vbe_farptr_t reserved_offscreen_mem_ptr; + + grub_uint8_t reserved[14]; +} __attribute__ ((packed)); + +struct grub_vbe_edid_info +{ + grub_uint8_t header[8]; + grub_uint16_t manufacturer_id; + grub_uint16_t product_id; + grub_uint32_t serial_number; + grub_uint8_t week_of_manufacture; + grub_uint8_t year_of_manufacture; + grub_uint8_t version; + grub_uint8_t revision; + + grub_uint8_t video_input_definition; + grub_uint8_t max_horizontal_image_size; + grub_uint8_t max_vertical_image_size; + grub_uint8_t display_gamma; + grub_uint8_t feature_support; +#define GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1) + + grub_uint8_t red_green_lo; + grub_uint8_t blue_white_lo; + grub_uint8_t red_x_hi; + grub_uint8_t red_y_hi; + grub_uint8_t green_x_hi; + grub_uint8_t green_y_hi; + grub_uint8_t blue_x_hi; + grub_uint8_t blue_y_hi; + grub_uint8_t white_x_hi; + grub_uint8_t white_y_hi; + + grub_uint8_t established_timings_1; + grub_uint8_t established_timings_2; + grub_uint8_t manufacturer_reserved_timings; + + grub_uint16_t standard_timings[8]; + + struct { + grub_uint16_t pixel_clock; + /* Only valid if the pixel clock is non-null. */ + grub_uint8_t horizontal_active_lo; + grub_uint8_t horizontal_blanking_lo; + grub_uint8_t horizontal_hi; + grub_uint8_t vertical_active_lo; + grub_uint8_t vertical_blanking_lo; + grub_uint8_t vertical_hi; + grub_uint8_t horizontal_sync_offset_lo; + grub_uint8_t horizontal_sync_pulse_width_lo; + grub_uint8_t vertical_sync_lo; + grub_uint8_t sync_hi; + grub_uint8_t horizontal_image_size_lo; + grub_uint8_t vertical_image_size_lo; + grub_uint8_t image_size_hi; + grub_uint8_t horizontal_border; + grub_uint8_t vertical_border; + grub_uint8_t flags; + } detailed_timings[4]; + + grub_uint8_t extension_flag; + grub_uint8_t checksum; +} __attribute__ ((packed)); + /* Prototypes for helper functions. */ /* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ grub_vbe_status_t @@ -197,6 +272,15 @@ grub_vbe_bios_get_scanline_length (grub_uint32_t *length); grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x, grub_uint32_t *y); +/* Call VESA BIOS 0x4f11 to get flat panel information, return status. */ +grub_vbe_status_t +grub_vbe_bios_get_flat_panel_info (struct grub_vbe_flat_panel_info *flat_panel_info); +/* Call VESA BIOS 0x4f15 to get DDC availability, return status. */ +grub_vbe_status_t +grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level); +/* Call VESA BIOS 0x4f15 to read EDID information, return status. */ +grub_vbe_status_t +grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_data); grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width); diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index a596e9c4a..55c686296 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -36,7 +36,7 @@ done if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi -if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi +if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=auto ; fi if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi From 25d884a52a1819792bc97cac9890d44a72446b7c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 14 Dec 2010 17:06:32 +0000 Subject: [PATCH 0508/1414] move generic parts of EDID handling (structure, checksumming) to generic location --- ChangeLog.vbe-autodetect | 7 ++-- grub-core/video/i386/pc/vbe.c | 27 +++------------ grub-core/video/video.c | 19 +++++++++++ include/grub/i386/pc/vbe.h | 64 ++--------------------------------- include/grub/video.h | 62 +++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 87 deletions(-) diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect index 7d16ebee2..0d96fc0a2 100644 --- a/ChangeLog.vbe-autodetect +++ b/ChangeLog.vbe-autodetect @@ -2,11 +2,11 @@ Preferred resolution detection for VBE. + * grub-core/video/video.c (grub_video_edid_checksum): New function. * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info): - New function. + Likewise. (grub_vbe_bios_get_ddc_capabilities): Likewise. (grub_vbe_bios_read_edid): Likewise. - (grub_vbe_edid_checksum): Likewise. (grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the Flat Panel extension, in line with the X.org VESA driver. (grub_video_vbe_setup): When the mode is "auto", try to get the @@ -14,9 +14,10 @@ than the preferred mode (some BIOSes expose a preferred mode that is not in their mode list!). If this fails, fall back to 640x480 as a safe conservative choice. + * include/grub/video.h (struct grub_vbe_edid_info): New structure. + (grub_video_edid_checksum): Add prototype. * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New structure. - (struct grub_vbe_edid_info): Likewise. (grub_vbe_bios_get_flat_panel_info): Add prototype. (grub_vbe_bios_get_ddc_capabilities): Likewise. (grub_vbe_bios_read_edid): Likewise. diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 1794addae..e2dcc151e 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -308,7 +308,7 @@ grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level) /* Call VESA BIOS 0x4f15 to read EDID information, return status. */ grub_vbe_status_t -grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_info) +grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_info) { struct grub_bios_int_registers regs; @@ -377,31 +377,12 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block) return GRUB_ERR_NONE; } -static grub_err_t -grub_vbe_edid_checksum (struct grub_vbe_edid_info *edid_info) -{ - const char *edid_bytes = (const char *) edid_info; - int i; - char checksum = 0; - - /* Check EDID checksum. */ - for (i = 0; i < 128; ++i) - checksum += edid_bytes[i]; - - if (checksum != 0) - return grub_error (GRUB_ERR_BAD_DEVICE, - "invalid EDID checksum %d", checksum); - - grub_errno = GRUB_ERR_NONE; - return grub_errno; -} - static grub_err_t grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) { grub_vbe_status_t status; grub_uint8_t ddc_level; - struct grub_vbe_edid_info edid_info; + struct grub_video_edid_info edid_info; struct grub_vbe_flat_panel_info flat_panel_info; if (controller_info.version >= 0x200 @@ -412,10 +393,10 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) /* Bit 1 in the Feature Support field indicates that the first Detailed Timing Description is the preferred timing mode. */ if (status == GRUB_VBE_STATUS_OK - && grub_vbe_edid_checksum (&edid_info) == GRUB_ERR_NONE + && grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE && edid_info.version == 1 /* we don't understand later versions */ && (edid_info.feature_support - & GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE) + & GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE) && edid_info.detailed_timings[0].pixel_clock) { *width = edid_info.detailed_timings[0].horizontal_active_lo diff --git a/grub-core/video/video.c b/grub-core/video/video.c index 7a1a446e4..f3ecab94d 100644 --- a/grub-core/video/video.c +++ b/grub-core/video/video.c @@ -374,6 +374,25 @@ grub_video_get_active_render_target (struct grub_video_render_target **target) return grub_video_adapter_active->get_active_render_target (target); } +grub_err_t +grub_video_edid_checksum (struct grub_video_edid_info *edid_info) +{ + const char *edid_bytes = (const char *) edid_info; + int i; + char checksum = 0; + + /* Check EDID checksum. */ + for (i = 0; i < 128; ++i) + checksum += edid_bytes[i]; + + if (checksum != 0) + return grub_error (GRUB_ERR_BAD_DEVICE, + "invalid EDID checksum %d", checksum); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + /* Parse x[x]*/ static grub_err_t parse_modespec (const char *current_mode, int *width, int *height, int *depth) diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index 5be34fdec..0422558db 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -19,6 +19,8 @@ #ifndef GRUB_VBE_MACHINE_HEADER #define GRUB_VBE_MACHINE_HEADER 1 +#include + /* Default video mode to be used. */ #define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101 @@ -184,66 +186,6 @@ struct grub_vbe_flat_panel_info grub_uint8_t reserved[14]; } __attribute__ ((packed)); -struct grub_vbe_edid_info -{ - grub_uint8_t header[8]; - grub_uint16_t manufacturer_id; - grub_uint16_t product_id; - grub_uint32_t serial_number; - grub_uint8_t week_of_manufacture; - grub_uint8_t year_of_manufacture; - grub_uint8_t version; - grub_uint8_t revision; - - grub_uint8_t video_input_definition; - grub_uint8_t max_horizontal_image_size; - grub_uint8_t max_vertical_image_size; - grub_uint8_t display_gamma; - grub_uint8_t feature_support; -#define GRUB_VBE_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1) - - grub_uint8_t red_green_lo; - grub_uint8_t blue_white_lo; - grub_uint8_t red_x_hi; - grub_uint8_t red_y_hi; - grub_uint8_t green_x_hi; - grub_uint8_t green_y_hi; - grub_uint8_t blue_x_hi; - grub_uint8_t blue_y_hi; - grub_uint8_t white_x_hi; - grub_uint8_t white_y_hi; - - grub_uint8_t established_timings_1; - grub_uint8_t established_timings_2; - grub_uint8_t manufacturer_reserved_timings; - - grub_uint16_t standard_timings[8]; - - struct { - grub_uint16_t pixel_clock; - /* Only valid if the pixel clock is non-null. */ - grub_uint8_t horizontal_active_lo; - grub_uint8_t horizontal_blanking_lo; - grub_uint8_t horizontal_hi; - grub_uint8_t vertical_active_lo; - grub_uint8_t vertical_blanking_lo; - grub_uint8_t vertical_hi; - grub_uint8_t horizontal_sync_offset_lo; - grub_uint8_t horizontal_sync_pulse_width_lo; - grub_uint8_t vertical_sync_lo; - grub_uint8_t sync_hi; - grub_uint8_t horizontal_image_size_lo; - grub_uint8_t vertical_image_size_lo; - grub_uint8_t image_size_hi; - grub_uint8_t horizontal_border; - grub_uint8_t vertical_border; - grub_uint8_t flags; - } detailed_timings[4]; - - grub_uint8_t extension_flag; - grub_uint8_t checksum; -} __attribute__ ((packed)); - /* Prototypes for helper functions. */ /* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ grub_vbe_status_t @@ -280,7 +222,7 @@ grub_vbe_status_t grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level); /* Call VESA BIOS 0x4f15 to read EDID information, return status. */ grub_vbe_status_t -grub_vbe_bios_read_edid (struct grub_vbe_edid_info *edid_data); +grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_data); grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width); diff --git a/include/grub/video.h b/include/grub/video.h index 97bd85bd1..2cf1424c4 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -210,6 +210,66 @@ struct grub_video_palette_data grub_uint8_t a; /* Reserved bits value (0-255). */ }; +struct grub_video_edid_info +{ + grub_uint8_t header[8]; + grub_uint16_t manufacturer_id; + grub_uint16_t product_id; + grub_uint32_t serial_number; + grub_uint8_t week_of_manufacture; + grub_uint8_t year_of_manufacture; + grub_uint8_t version; + grub_uint8_t revision; + + grub_uint8_t video_input_definition; + grub_uint8_t max_horizontal_image_size; + grub_uint8_t max_vertical_image_size; + grub_uint8_t display_gamma; + grub_uint8_t feature_support; +#define GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1) + + grub_uint8_t red_green_lo; + grub_uint8_t blue_white_lo; + grub_uint8_t red_x_hi; + grub_uint8_t red_y_hi; + grub_uint8_t green_x_hi; + grub_uint8_t green_y_hi; + grub_uint8_t blue_x_hi; + grub_uint8_t blue_y_hi; + grub_uint8_t white_x_hi; + grub_uint8_t white_y_hi; + + grub_uint8_t established_timings_1; + grub_uint8_t established_timings_2; + grub_uint8_t manufacturer_reserved_timings; + + grub_uint16_t standard_timings[8]; + + struct { + grub_uint16_t pixel_clock; + /* Only valid if the pixel clock is non-null. */ + grub_uint8_t horizontal_active_lo; + grub_uint8_t horizontal_blanking_lo; + grub_uint8_t horizontal_hi; + grub_uint8_t vertical_active_lo; + grub_uint8_t vertical_blanking_lo; + grub_uint8_t vertical_hi; + grub_uint8_t horizontal_sync_offset_lo; + grub_uint8_t horizontal_sync_pulse_width_lo; + grub_uint8_t vertical_sync_lo; + grub_uint8_t sync_hi; + grub_uint8_t horizontal_image_size_lo; + grub_uint8_t vertical_image_size_lo; + grub_uint8_t image_size_hi; + grub_uint8_t horizontal_border; + grub_uint8_t vertical_border; + grub_uint8_t flags; + } detailed_timings[4]; + + grub_uint8_t extension_flag; + grub_uint8_t checksum; +} __attribute__ ((packed)); + typedef enum grub_video_driver_id { GRUB_VIDEO_DRIVER_NONE, @@ -423,6 +483,8 @@ grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_ grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); +grub_err_t grub_video_edid_checksum (struct grub_video_edid_info *edid_info); + grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring, unsigned int modemask, unsigned int modevalue); From 129185cfaae5969be4e49f5d898ed553b18d8502 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 14 Dec 2010 18:03:34 +0000 Subject: [PATCH 0509/1414] move more EDID-handling functions to generic code, and make videoinfo display EDID information --- ChangeLog.vbe-autodetect | 15 +++++++++--- grub-core/commands/videoinfo.c | 31 ++++++++++++++++++++++++ grub-core/video/i386/pc/vbe.c | 36 +++++++++++++--------------- grub-core/video/video.c | 43 ++++++++++++++++++++++++++++++++++ include/grub/video.h | 6 +++++ 5 files changed, 108 insertions(+), 23 deletions(-) diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect index 0d96fc0a2..355ce00f6 100644 --- a/ChangeLog.vbe-autodetect +++ b/ChangeLog.vbe-autodetect @@ -3,24 +3,33 @@ Preferred resolution detection for VBE. * grub-core/video/video.c (grub_video_edid_checksum): New function. + (grub_video_get_edid): Likewise. + (grub_video_edid_preferred_mode): Likewise. Try EDID followed by + the Flat Panel extension, in line with the X.org VESA driver. * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info): - Likewise. + New function. (grub_vbe_bios_get_ddc_capabilities): Likewise. (grub_vbe_bios_read_edid): Likewise. - (grub_vbe_get_preferred_mode): Likewise. Try EDID followed by the - Flat Panel extension, in line with the X.org VESA driver. + (grub_vbe_get_preferred_mode): Likewise. (grub_video_vbe_setup): When the mode is "auto", try to get the preferred mode from VBE, and use the largest mode that is no larger than the preferred mode (some BIOSes expose a preferred mode that is not in their mode list!). If this fails, fall back to 640x480 as a safe conservative choice. + (grub_video_vbe_get_edid): New function. + (grub_video_vbe_adapter): Add get_edid. * include/grub/video.h (struct grub_vbe_edid_info): New structure. (grub_video_edid_checksum): Add prototype. + (grub_video_get_edid): Likewise. + (grub_video_edid_preferred_mode): Likewise. * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New structure. (grub_vbe_bios_get_flat_panel_info): Add prototype. (grub_vbe_bios_get_ddc_capabilities): Likewise. (grub_vbe_bios_read_edid): Likewise. + * grub-core/commands/videoinfo.c (print_edid): New function. + (grub_cmd_videoinfo): Print EDID if available. + * util/grub.d/00_header.in (GRUB_GFXMODE): Default to "auto". This is more appropriate on a wider range of platforms than 640x480. diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 10f77915b..56df943ec 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -77,6 +77,30 @@ hook (const struct grub_video_mode_info *info) return 0; } +static void +print_edid (struct grub_video_edid_info *edid_info) +{ + unsigned int edid_width, edid_height; + + if (grub_video_edid_checksum (edid_info)) + { + grub_printf (" EDID checksum invalid\n"); + grub_errno = GRUB_ERR_NONE; + return; + } + + grub_printf (" EDID version: %u.%u\n", + edid_info->version, edid_info->revision); + if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height) + == GRUB_ERR_NONE) + grub_printf (" Preferred mode: %ux%u\n", edid_width, edid_height); + else + { + grub_printf (" No preferred mode available\n"); + grub_errno = GRUB_ERR_NONE; + } +} + static grub_err_t grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) @@ -120,6 +144,8 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), FOR_VIDEO_ADAPTERS (adapter) { + struct grub_video_edid_info edid_info; + grub_printf ("Adapter '%s':\n", adapter->name); if (!adapter->iterate) @@ -143,6 +169,11 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), adapter->iterate (hook); + if (adapter->get_edid (&edid_info) == GRUB_ERR_NONE) + print_edid (&edid_info); + else + grub_errno = GRUB_ERR_NONE; + if (adapter->id != id) { if (adapter->fini ()) diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index e2dcc151e..c6bb733a9 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -389,26 +389,12 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff) == GRUB_VBE_STATUS_OK) { - status = grub_vbe_bios_read_edid (&edid_info); - /* Bit 1 in the Feature Support field indicates that the first - Detailed Timing Description is the preferred timing mode. */ - if (status == GRUB_VBE_STATUS_OK - && grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE - && edid_info.version == 1 /* we don't understand later versions */ - && (edid_info.feature_support - & GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE) - && edid_info.detailed_timings[0].pixel_clock) - { - *width = edid_info.detailed_timings[0].horizontal_active_lo - | (((unsigned int) - (edid_info.detailed_timings[0].horizontal_hi & 0xf0)) - << 4); - *height = edid_info.detailed_timings[0].vertical_active_lo - | (((unsigned int) - (edid_info.detailed_timings[0].vertical_hi & 0xf0)) - << 4); - return GRUB_ERR_NONE; - } + if (grub_video_get_edid (&edid_info) == GRUB_ERR_NONE + && grub_video_edid_preferred_mode (&edid_info, width, height) + == GRUB_ERR_NONE) + return GRUB_ERR_NONE; + + grub_errno = GRUB_ERR_NONE; } status = grub_vbe_bios_get_flat_panel_info (&flat_panel_info); @@ -978,6 +964,15 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, return grub_video_fb_get_info_and_fini (mode_info, framebuf); } +static grub_err_t +grub_video_vbe_get_edid (struct grub_video_edid_info *edid_info) +{ + if (grub_vbe_bios_read_edid (edid_info) != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_BAD_DEVICE, "EDID information not available"); + + return GRUB_ERR_NONE; +} + static void grub_video_vbe_print_adapter_specific_info (void) { @@ -1022,6 +1017,7 @@ static struct grub_video_adapter grub_video_vbe_adapter = .set_active_render_target = grub_video_fb_set_active_render_target, .get_active_render_target = grub_video_fb_get_active_render_target, .iterate = grub_video_vbe_iterate, + .get_edid = grub_video_vbe_get_edid, .print_adapter_specific_info = grub_video_vbe_print_adapter_specific_info, .next = 0 diff --git a/grub-core/video/video.c b/grub-core/video/video.c index f3ecab94d..84e98bb67 100644 --- a/grub-core/video/video.c +++ b/grub-core/video/video.c @@ -393,6 +393,49 @@ grub_video_edid_checksum (struct grub_video_edid_info *edid_info) return grub_errno; } +grub_err_t +grub_video_get_edid (struct grub_video_edid_info *edid_info) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); + + if (! grub_video_adapter_active->get_edid) + return grub_error (GRUB_ERR_BAD_DEVICE, + "EDID information unavailable for this video mode"); + + if (grub_video_adapter_active->get_edid (edid_info) != GRUB_ERR_NONE) + return grub_errno; + if (grub_video_edid_checksum (edid_info) != GRUB_ERR_NONE) + return grub_errno; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info, + unsigned int *width, unsigned int *height) +{ + /* Bit 1 in the Feature Support field indicates that the first + Detailed Timing Description is the preferred timing mode. */ + if (edid_info->version == 1 /* we don't understand later versions */ + && (edid_info->feature_support + & GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE) + && edid_info->detailed_timings[0].pixel_clock) + { + *width = edid_info->detailed_timings[0].horizontal_active_lo + | (((unsigned int) + (edid_info->detailed_timings[0].horizontal_hi & 0xf0)) + << 4); + *height = edid_info->detailed_timings[0].vertical_active_lo + | (((unsigned int) + (edid_info->detailed_timings[0].vertical_hi & 0xf0)) + << 4); + return GRUB_ERR_NONE; + } + + return grub_error (GRUB_ERR_BAD_DEVICE, "no preferred mode available"); +} + /* Parse x[x]*/ static grub_err_t parse_modespec (const char *current_mode, int *width, int *height, int *depth) diff --git a/include/grub/video.h b/include/grub/video.h index 2cf1424c4..2251ed5f4 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -371,6 +371,8 @@ struct grub_video_adapter int (*iterate) (int (*hook) (const struct grub_video_mode_info *info)); + grub_err_t (*get_edid) (struct grub_video_edid_info *edid_info); + void (*print_adapter_specific_info) (void); }; typedef struct grub_video_adapter *grub_video_adapter_t; @@ -484,6 +486,10 @@ grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_ grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); grub_err_t grub_video_edid_checksum (struct grub_video_edid_info *edid_info); +grub_err_t grub_video_get_edid (struct grub_video_edid_info *edid_info); +grub_err_t grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info, + unsigned int *width, + unsigned int *height); grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring, unsigned int modemask, From ef429417b2297c508685d9b1cc43e0bee74f0f44 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 14 Dec 2010 18:08:27 +0000 Subject: [PATCH 0510/1414] mention struct grub_video_adapter change --- ChangeLog.vbe-autodetect | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect index 355ce00f6..d8034b885 100644 --- a/ChangeLog.vbe-autodetect +++ b/ChangeLog.vbe-autodetect @@ -19,6 +19,7 @@ (grub_video_vbe_get_edid): New function. (grub_video_vbe_adapter): Add get_edid. * include/grub/video.h (struct grub_vbe_edid_info): New structure. + (struct grub_video_adapter): Add get_edid. (grub_video_edid_checksum): Add prototype. (grub_video_get_edid): Likewise. (grub_video_edid_preferred_mode): Likewise. From 015e21571c2ecaacb7eb59c2cfde566d1290c445 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 14 Dec 2010 19:03:28 +0000 Subject: [PATCH 0511/1414] check that adapter->get_edid is non-NULL --- grub-core/commands/videoinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 56df943ec..9bd0a0e78 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -169,7 +169,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), adapter->iterate (hook); - if (adapter->get_edid (&edid_info) == GRUB_ERR_NONE) + if (adapter->get_edid && adapter->get_edid (&edid_info) == GRUB_ERR_NONE) print_edid (&edid_info); else grub_errno = GRUB_ERR_NONE; From 477343c86e0b1e4279be40a1af488e7755f20339 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 15 Dec 2010 01:31:07 +0000 Subject: [PATCH 0512/1414] 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 0513/1414] 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 0514/1414] 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 0515/1414] 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 0516/1414] 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 b04298cfa29418564bd86fd1053fb681000966bc Mon Sep 17 00:00:00 2001 From: kashyap garimella Date: Sat, 18 Dec 2010 15:22:11 +0100 Subject: [PATCH 0517/1414] * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_load): Use correct cat to grub_uint8_t * rather than grub_uint32_t *. --- ChangeLog | 5 +++++ grub-core/loader/i386/multiboot_mbi.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index abd1d0400..254c8303a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-12-18 kashyap garimella + + * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_load): Use + correct cat to grub_uint8_t * rather than grub_uint32_t *. + 2010-12-10 Colin Watson * .bzrignore: Ignore grub-core/rs_decoder.S. diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 79f72ee0f..e3f328494 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -141,7 +141,7 @@ grub_multiboot_load (grub_file_t file) } if (header->bss_end_addr) - grub_memset ((grub_uint32_t *) source + load_size, 0, + grub_memset ((grub_uint8_t *) source + load_size, 0, header->bss_end_addr - header->load_addr - load_size); grub_multiboot_payload_eip = header->entry_addr; From e1dffcf2705db474dd3a59d8a514598af878da19 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 18 Dec 2010 14:31:05 +0100 Subject: [PATCH 0518/1414] * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): Set ptrdest to correct get_physical_target_address rather than incorrect get_virtual_current_address. --- ChangeLog | 6 ++++++ grub-core/loader/i386/multiboot_mbi.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 254c8303a..d7091f27c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-18 Vladimir Serbinenko + + * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): + Set ptrdest to correct get_physical_target_address rather than + incorrect get_virtual_current_address. + 2010-12-18 kashyap garimella * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_load): Use diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index e3f328494..7015666fc 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -441,7 +441,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) if (err) return err; ptrorig = get_virtual_current_address (ch); - ptrdest = (grub_addr_t) get_virtual_current_address (ch); + ptrdest = get_physical_target_address (ch); *target = ptrdest; From 32570200a8bb64856c3125fecfc79b9467dddb50 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 18 Dec 2010 17:37:48 +0000 Subject: [PATCH 0519/1414] * grub-core/normal/term.c (print_more): Make \r or \n scroll one line, and other keys scroll an entire page (previous handling was for \r and \n to scroll a page and other keys to scroll two lines). --- ChangeLog | 6 ++++++ grub-core/normal/term.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7091f27c..3f15bcc7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-18 Colin Watson + + * grub-core/normal/term.c (print_more): Make \r or \n scroll one + line, and other keys scroll an entire page (previous handling was + for \r and \n to scroll a page and other keys to scroll two lines). + 2010-12-18 Vladimir Serbinenko * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index 00721c447..a1aa3d783 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -91,16 +91,16 @@ print_more (void) grub_term_restore_pos (pos); grub_free (pos); - /* Scroll one lines or an entire page, depending on the key. */ + /* Scroll one line or an entire page, depending on the key. */ if (key == '\r' || key =='\n') - grub_normal_reset_more (); - else { static struct term_state *state; for (state = term_states; state; state = state->next) - state->num_lines -= 2; + state->num_lines--; } + else + grub_normal_reset_more (); } void From e872a2dd82c6bfc27a870aff9088dfccaaa4fc02 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 18 Dec 2010 22:47:50 +0100 Subject: [PATCH 0520/1414] * 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 5cf86f4b0fadf4fbe8780cf5d4592b81e86158b4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 18 Dec 2010 22:47:50 +0100 Subject: [PATCH 0521/1414] * 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 bc5e26582..1012833a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,10 @@ editor under argument scope. Reported by: Jordan Uggla +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 0522/1414] 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 7059d1ec14f7c5c44623688a7960050be9c585e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 00:43:41 +0100 Subject: [PATCH 0523/1414] 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 1012833a0..333b24ab2 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-19 BVK Chaitanya * grub-core/normal/menu_entry.c (run): Execute commands from menu 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 0524/1414] * 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 a2a08a35bf2a6603b9c0ee5dc3e224f41373258c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 00:49:52 +0100 Subject: [PATCH 0525/1414] * 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 333b24ab2..99cf2cd7f 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 0526/1414] * 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 6c85b743f5c3a07c400ffd798e87cbcf2d3ab64d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 00:52:18 +0100 Subject: [PATCH 0527/1414] * 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 99cf2cd7f..12836d9af 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 70e8145a7b52759fcf94fe16fa3ea287d83eb904 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 16:10:26 +0100 Subject: [PATCH 0528/1414] Plan9 support --- grub-core/Makefile.core.def | 7 + grub-core/loader/i386/pc/plan9.c | 219 +++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 grub-core/loader/i386/pc/plan9.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 37c0ce970..ae604b3c6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1146,6 +1146,13 @@ module = { enable = x86; }; +module = { + name = plan9; + i386_pc = loader/i386/pc/plan9.c; + enable = i386_pc; +}; + + module = { name = linux16; i386_pc = loader/i386/pc/linux.c; diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c new file mode 100644 index 000000000..aa96ae83c --- /dev/null +++ b/grub-core/loader/i386/pc/plan9.c @@ -0,0 +1,219 @@ +/* + * 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 +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; +static struct grub_relocator *rel; +static grub_uint32_t eip = 0xffffffff; + +#define GRUB_PLAN9_TARGET 0x100000 +#define GRUB_PLAN9_CONFIG_ADDR 0x001200 +#define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 +#define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" + +struct grub_plan9_header +{ + grub_uint32_t magic; +#define GRUB_PLAN9_MAGIC 0x1eb + grub_uint32_t text_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t zero1; + grub_uint32_t entry_addr; + grub_uint32_t zero2; + grub_uint32_t zero3; +}; + +static grub_err_t +grub_plan9_boot (void) +{ + struct grub_relocator32_state state = { + .eax = 0, + .eip = eip, + .ebx = 0, + .ecx = 0, + .edx = 0, + .edi = 0, + .esp = 0, + .ebp = 0, + .esi = 0 + /* grub_uint32_t ebp; + grub_uint32_t esi; +*/ + }; + grub_video_set_mode ("text", 0, 0); + + return grub_relocator32_boot (rel, state); +} + +static grub_err_t +grub_plan9_unload (void) +{ + grub_relocator_unload (rel); + rel = NULL; + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_err_t err; + void *mem; + grub_uint8_t *ptr; + grub_size_t memsize, padsize; + struct grub_plan9_header hdr; + char *config, *configptr; + grub_size_t configsize; + int i; + + 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; + + if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) + goto fail; + + if (grub_be_to_cpu32 (hdr.magic) != GRUB_PLAN9_MAGIC + || hdr.zero1 || hdr.zero2 || hdr.zero3) + { + grub_error (GRUB_ERR_BAD_OS, "unsupported Plan9"); + goto fail; + } + + memsize = sizeof (hdr); + memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16); + memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16); + memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16); + eip = grub_be_to_cpu32 (hdr.entry_addr) & 0xfffffff; + + /* path */ + configsize = GRUB_PLAN9_CONFIG_PATH_SIZE; + /* magic */ + configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; + for (i = 1; i < argc; i++) + configsize += grub_strlen (argv[i]) + 1; + /* Terminating \0. */ + configsize++; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_CONFIG_ADDR, + configsize); + if (err) + goto fail; + config = get_virtual_current_address (ch); + } + + grub_memset (config, 0, GRUB_PLAN9_CONFIG_PATH_SIZE); + configptr = config + GRUB_PLAN9_CONFIG_PATH_SIZE; + grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, + sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); + configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; + for (i = 1; i < argc; i++) + { + configptr = grub_stpcpy (configptr, argv[i]); + *configptr++ = '\n'; + } + *configptr = 0; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_TARGET, + memsize); + if (err) + goto fail; + mem = get_virtual_current_address (ch); + } + + ptr = mem; + grub_memcpy (ptr, &hdr, sizeof (hdr)); + ptr += sizeof (hdr); + + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.text_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16) + - grub_be_to_cpu32 (hdr.text_size); + + grub_memset (ptr, 0, padsize); + ptr += padsize; + + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.data_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16) + - grub_be_to_cpu32 (hdr.data_size); + + grub_memset (ptr, 0, padsize); + ptr += padsize; + grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16)); + + grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); + return GRUB_ERR_NONE; + + fail: + + if (file) + grub_file_close (file); + + grub_plan9_unload (); + + return grub_errno; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(plan9) +{ + cmd = grub_register_command ("plan9", grub_cmd_plan9, + 0, N_("Load Plan9 kernel.")); + my_mod = mod; +} + +GRUB_MOD_FINI(plan9) +{ + grub_unregister_command (cmd); +} From 239ab5f0480cb232ccb987856f21d4875629702e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 17:02:25 +0100 Subject: [PATCH 0529/1414] Fix Plan9 alignment --- grub-core/loader/i386/pc/plan9.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index aa96ae83c..aaceb2825 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -36,6 +36,7 @@ static struct grub_relocator *rel; static grub_uint32_t eip = 0xffffffff; #define GRUB_PLAN9_TARGET 0x100000 +#define GRUB_PLAN9_ALIGN 4096 #define GRUB_PLAN9_CONFIG_ADDR 0x001200 #define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 #define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" @@ -121,10 +122,10 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), goto fail; } - memsize = sizeof (hdr); - memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16); - memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16); - memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16); + memsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), + GRUB_PLAN9_ALIGN); + memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN); + memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN); eip = grub_be_to_cpu32 (hdr.entry_addr) & 0xfffffff; /* path */ @@ -174,8 +175,9 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) goto fail; ptr += grub_be_to_cpu32 (hdr.text_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size), 16) - - grub_be_to_cpu32 (hdr.text_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), + GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) + - sizeof (hdr); grub_memset (ptr, 0, padsize); ptr += padsize; @@ -184,12 +186,12 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) goto fail; ptr += grub_be_to_cpu32 (hdr.data_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), 16) + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.data_size); grub_memset (ptr, 0, padsize); ptr += padsize; - grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), 16)); + grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN)); grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); return GRUB_ERR_NONE; From 3c50773923e086199748c7d431c2d0c1fd419bbd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 19 Dec 2010 20:51:32 +0100 Subject: [PATCH 0530/1414] Ignore fields zero1 and zero3 --- grub-core/loader/i386/pc/plan9.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index aaceb2825..7b777d0b3 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -48,10 +48,10 @@ struct grub_plan9_header grub_uint32_t text_size; grub_uint32_t data_size; grub_uint32_t bss_size; - grub_uint32_t zero1; + grub_uint32_t sectiona; grub_uint32_t entry_addr; - grub_uint32_t zero2; - grub_uint32_t zero3; + grub_uint32_t zero; + grub_uint32_t sectionb; }; static grub_err_t @@ -116,7 +116,7 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), goto fail; if (grub_be_to_cpu32 (hdr.magic) != GRUB_PLAN9_MAGIC - || hdr.zero1 || hdr.zero2 || hdr.zero3) + || hdr.zero) { grub_error (GRUB_ERR_BAD_OS, "unsupported Plan9"); goto fail; From ac9ef7eef97d4c217a849e185ca5e06c560b9c83 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Dec 2010 01:18:21 +0100 Subject: [PATCH 0531/1414] plan9 subpartition support --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 ++ grub-core/partmap/plan.c | 118 ++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 grub-core/partmap/plan.c diff --git a/Makefile.util.def b/Makefile.util.def index 74984e2e9..2b9d28cf0 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -91,6 +91,7 @@ library = { common = grub-core/partmap/gpt.c; common = grub-core/partmap/msdos.c; common = grub-core/partmap/sun.c; + common = grub-core/partmap/plan.c; common = grub-core/partmap/sunpc.c; common = grub-core/partmap/bsdlabel.c; common = grub-core/script/function.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ae604b3c6..9151e434b 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1308,6 +1308,11 @@ module = { common = partmap/sun.c; }; +module = { + name = part_plan; + common = partmap/plan.c; +}; + module = { name = part_bsd; common = partmap/bsdlabel.c; diff --git a/grub-core/partmap/plan.c b/grub-core/partmap/plan.c new file mode 100644 index 000000000..c62d04b73 --- /dev/null +++ b/grub-core/partmap/plan.c @@ -0,0 +1,118 @@ +/* + * 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 + +static struct grub_partition_map grub_plan_partition_map; + +static grub_err_t +plan_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition p; + int ptr = 0; + grub_err_t err; + + p.partmap = &grub_plan_partition_map; + p.msdostype = 0; + + for (p.number = 0; ; p.number++) + { + char sig[sizeof ("part ") - 1]; + char c; + + p.offset = (ptr >> GRUB_DISK_SECTOR_BITS) + 1; + p.index = ptr & (GRUB_DISK_SECTOR_SIZE - 1); + + err = grub_disk_read (disk, 1, ptr, sizeof (sig), sig); + if (err) + return err; + if (grub_memcmp (sig, "part ", sizeof ("part ") - 1) != 0) + break; + ptr += sizeof (sig); + do + { + err = grub_disk_read (disk, 1, ptr, 1, &c); + if (err) + return err; + ptr++; + } + while (grub_isdigit (c) || grub_isalpha (c)); + if (c != ' ') + break; + p.start = 0; + while (1) + { + err = grub_disk_read (disk, 1, ptr, 1, &c); + if (err) + return err; + ptr++; + if (!grub_isdigit (c)) + break; + p.start = p.start * 10 + (c - '0'); + } + if (c != ' ') + break; + p.len = 0; + while (1) + { + err = grub_disk_read (disk, 1, ptr, 1, &c); + if (err) + return err; + ptr++; + if (!grub_isdigit (c)) + break; + p.len = p.len * 10 + (c - '0'); + } + if (c != '\n') + break; + p.len -= p.start; + if (hook (disk, &p)) + return grub_errno; + } + if (p.number == 0) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a plan partition table"); + + return GRUB_ERR_NONE; +} + +/* Partition map type. */ +static struct grub_partition_map grub_plan_partition_map = + { + .name = "plan", + .iterate = plan_partition_map_iterate, + }; + +GRUB_MOD_INIT(part_plan) +{ + grub_partition_map_register (&grub_plan_partition_map); +} + +GRUB_MOD_FINI(part_plan) +{ + grub_partition_map_unregister (&grub_plan_partition_map); +} + From 5318fe9804f1e95e2d04186f4bf28562c8cfaf5e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 20 Dec 2010 16:13:01 +0100 Subject: [PATCH 0532/1414] * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_add_module): Avoid next pointing to nowhere. --- ChangeLog | 5 +++++ grub-core/loader/i386/multiboot_mbi.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 12836d9af..6e564324b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-12-20 Vladimir Serbinenko + + * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_add_module): + Avoid next pointing to nowhere. + 2010-12-19 Vladimir Serbinenko * grub-core/fs/affs.c (grub_affs_mount): Read data->bblock.rootblock diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 7015666fc..eade78e93 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -641,6 +641,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, return grub_errno; newmod->start = start; newmod->size = size; + newmod->next = 0; for (i = 0; i < argc; i++) len += grub_strlen (argv[i]) + 1; From da94d203d9f421259aca4548d9862d138c5d7188 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Dec 2010 00:04:31 +0100 Subject: [PATCH 0533/1414] Generate partmaps for plan9 --- grub-core/loader/i386/pc/plan9.c | 279 +++++++++++++++++++++++++++---- include/grub/disk.h | 2 - include/grub/misc.h | 1 + include/grub/mm.h | 17 ++ include/grub/msdos_partition.h | 2 + 5 files changed, 271 insertions(+), 30 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 7b777d0b3..2418bf1a1 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -67,9 +69,6 @@ grub_plan9_boot (void) .esp = 0, .ebp = 0, .esi = 0 - /* grub_uint32_t ebp; - grub_uint32_t esi; -*/ }; grub_video_set_mode ("text", 0, 0); @@ -90,14 +89,218 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; - grub_err_t err; void *mem; - grub_uint8_t *ptr; grub_size_t memsize, padsize; struct grub_plan9_header hdr; char *config, *configptr; grub_size_t configsize; int i; + char *pmap = NULL; + grub_size_t pmapalloc = 256; + grub_size_t pmapptr = 0; + int noslash = 1; + char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"}; + int prefixescnt[5]; + + auto int fill_partition (grub_disk_t disk, + const grub_partition_t partition); + int fill_partition (grub_disk_t disk, + const grub_partition_t partition) + { + if (!noslash) + { + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; + pmap[pmapptr++] = '/'; + } + noslash = 0; + + if (grub_strcmp (partition->partmap->name, "plan") == 0) + { + unsigned ptr = partition->index + sizeof ("part ") - 1; + grub_err_t err; + disk->partition = partition->parent; + do + { + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; + err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr); + if (err) + { + disk->partition = 0; + return err; + } + ptr++; + pmapptr++; + } + while (grub_isalpha (pmap[pmapptr - 1]) + || grub_isdigit (pmap[pmapptr - 1])); + pmapptr--; + } + else + { + char name[50]; + int c = 0; + if (grub_strcmp (partition->partmap->name, "msdos") == 0) + { + switch (partition->msdostype) + { + case GRUB_PC_PARTITION_TYPE_PLAN9: + c = 1; + break; + case GRUB_PC_PARTITION_TYPE_NTFS: + c = 2; + break; + case GRUB_PC_PARTITION_TYPE_MINIX: + case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: + case GRUB_PC_PARTITION_TYPE_EXT2FS: + c = 3; + break; + case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: + c = 4; + break; + } + } + + if (prefixescnt[c] == 0) + grub_strcpy (name, prefixes[c]); + else + grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], + prefixescnt[c]); + prefixescnt[c]++; + if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1, + &pmapalloc, (void **) &pmap)) + return 1; + grub_strcpy (pmap + pmapptr, name); + pmapptr += grub_strlen (name); + } + if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, + (void **) &pmap)) + return 1; + pmap[pmapptr++] = ' '; + grub_snprintf (pmap + pmapptr, 25 + 5 + 25, + "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, + grub_partition_get_start (partition), + grub_partition_get_start (partition) + + grub_partition_get_len (partition)); + pmapptr += grub_strlen (pmap + pmapptr); + return 0; + } + + auto int fill_disk (const char *name); + int fill_disk (const char *name) + { + grub_device_t dev; + int file_disk; + char *plan9name = NULL; + + dev = grub_device_open (name); + if (!dev) + { + grub_print_error (); + return 0; + } + if (!dev->disk) + { + grub_device_close (dev); + return 0; + } + file_disk = file->device->disk && dev->disk->id == file->device->disk->id + && dev->disk->dev->id == file->device->disk->dev->id; + switch (dev->disk->dev->id) + { + case GRUB_DISK_DEVICE_BIOSDISK_ID: + if (dev->disk->id & 0x80) + plan9name = grub_xasprintf ("sdB%u", + (unsigned) (dev->disk->id & 0x7f)); + else + plan9name = grub_xasprintf ("fd%u", + (unsigned) (dev->disk->id & 0x7f)); + break; + /* Shouldn't happen as Plan9 doesn't work on these platforms. */ + case GRUB_DISK_DEVICE_OFDISK_ID: + case GRUB_DISK_DEVICE_EFIDISK_ID: + + /* Plan9 doesn't see those. */ + case GRUB_DISK_DEVICE_LOOPBACK_ID: + case GRUB_DISK_DEVICE_RAID_ID: + case GRUB_DISK_DEVICE_LVM_ID: + case GRUB_DISK_DEVICE_HOST_ID: + case GRUB_DISK_DEVICE_MEMDISK_ID: + case GRUB_DISK_DEVICE_LUKS_ID: + + /* Not sure how to handle those. */ + case GRUB_DISK_DEVICE_PXE_ID: + case GRUB_DISK_DEVICE_NAND_ID: + if (!file_disk) + { + grub_device_close (dev); + return 0; + } + + /* if it's the disk the kernel is loaded from we need to name + it nevertheless. */ + plan9name = grub_strdup ("sdZ0"); + break; + + case GRUB_DISK_DEVICE_ATA_ID: + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else + unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); + } + break; + case GRUB_DISK_DEVICE_SCSI_ID: + if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) + == GRUB_SCSI_SUBSYSTEM_ATAPI) + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else + unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); + break; + } + + /* FIXME: how does Plan9 number controllers? + We probably need save the SCSI devices and sort them */ + plan9name + = grub_xasprintf ("sd0%u", (unsigned) + ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) & 0xf)); + break; + } + if (!plan9name) + { + grub_print_error (); + return 0; + } + if (grub_extend_alloc (pmapptr + grub_strlen (plan9name) + + sizeof ("part="), &pmapalloc, + (void **) &pmap)) + { + grub_free (plan9name); + return 1; + } + grub_strcpy (pmap + pmapptr, plan9name); + pmapptr += grub_strlen (plan9name); + grub_free (plan9name); + grub_strcpy (pmap + pmapptr, "part="); + pmapptr += sizeof ("part=") - 1; + + noslash = 1; + grub_memset (prefixescnt, 0, sizeof (prefixescnt)); + if (grub_partition_iterate (dev->disk, fill_partition)) + return 1; + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; + pmap[pmapptr++] = '\n'; + + return 0; + } if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); @@ -112,6 +315,18 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), if (! file) goto fail; + pmap = grub_malloc (pmapalloc); + if (!pmap) + goto fail; + + if (grub_disk_dev_iterate (fill_disk)) + goto fail; + + if (grub_extend_alloc (pmapptr + 1, &pmapalloc, + (void **) &pmap)) + goto fail; + pmap[pmapptr] = 0; + if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) goto fail; @@ -134,11 +349,13 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; for (i = 1; i < argc; i++) configsize += grub_strlen (argv[i]) + 1; + configsize += pmapptr; /* Terminating \0. */ configsize++; { grub_relocator_chunk_t ch; + grub_err_t err; err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_CONFIG_ADDR, configsize); if (err) @@ -156,10 +373,12 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), configptr = grub_stpcpy (configptr, argv[i]); *configptr++ = '\n'; } - *configptr = 0; + configptr = grub_stpcpy (configptr, pmap); { grub_relocator_chunk_t ch; + grub_err_t err; + err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_TARGET, memsize); if (err) @@ -167,36 +386,40 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), mem = get_virtual_current_address (ch); } - ptr = mem; - grub_memcpy (ptr, &hdr, sizeof (hdr)); - ptr += sizeof (hdr); + { + grub_uint8_t *ptr; + ptr = mem; + grub_memcpy (ptr, &hdr, sizeof (hdr)); + ptr += sizeof (hdr); - if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) - != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) - goto fail; - ptr += grub_be_to_cpu32 (hdr.text_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), - GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) - - sizeof (hdr); + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.text_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), + GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) + - sizeof (hdr); - grub_memset (ptr, 0, padsize); - ptr += padsize; + grub_memset (ptr, 0, padsize); + ptr += padsize; - if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) - != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) - goto fail; - ptr += grub_be_to_cpu32 (hdr.data_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) - - grub_be_to_cpu32 (hdr.data_size); - - grub_memset (ptr, 0, padsize); - ptr += padsize; - grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN)); + if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) + goto fail; + ptr += grub_be_to_cpu32 (hdr.data_size); + padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) + - grub_be_to_cpu32 (hdr.data_size); + grub_memset (ptr, 0, padsize); + ptr += padsize; + grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), + GRUB_PLAN9_ALIGN)); + } grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); return GRUB_ERR_NONE; fail: + grub_free (pmap); if (file) grub_file_close (file); diff --git a/include/grub/disk.h b/include/grub/disk.h index 66db1149a..b72b26f46 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -38,10 +38,8 @@ enum grub_disk_dev_id GRUB_DISK_DEVICE_ATA_ID, GRUB_DISK_DEVICE_MEMDISK_ID, GRUB_DISK_DEVICE_NAND_ID, - GRUB_DISK_DEVICE_UUID_ID, GRUB_DISK_DEVICE_PXE_ID, GRUB_DISK_DEVICE_SCSI_ID, - GRUB_DISK_DEVICE_FILE_ID, GRUB_DISK_DEVICE_LUKS_ID }; diff --git a/include/grub/misc.h b/include/grub/misc.h index 6fcaa148b..b26a70cd0 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -353,4 +353,5 @@ extern int EXPORT_VAR(grub_no_autoload); #define grub_no_autoload 0 #endif + #endif /* ! GRUB_MISC_HEADER */ diff --git a/include/grub/mm.h b/include/grub/mm.h index cc115907a..5810fff41 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -72,4 +72,21 @@ void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line, grub_size_t align, grub_size_t size); #endif /* MM_DEBUG && ! GRUB_UTIL */ +#include + +static inline grub_err_t +grub_extend_alloc (grub_size_t sz, grub_size_t *allocated, void **ptr) +{ + void *n; + if (sz < *allocated) + return GRUB_ERR_NONE; + + *allocated = 2 * sz; + n = grub_realloc (*ptr, *allocated); + if (!n) + return grub_errno; + *ptr = n; + return GRUB_ERR_NONE; +} + #endif /* ! GRUB_MM_H */ diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h index a6e3fda49..9c8ac3e8a 100644 --- a/include/grub/msdos_partition.h +++ b/include/grub/msdos_partition.h @@ -42,9 +42,11 @@ #define GRUB_PC_PARTITION_TYPE_FAT32_LBA 0xc #define GRUB_PC_PARTITION_TYPE_FAT16_LBA 0xe #define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED 0xf +#define GRUB_PC_PARTITION_TYPE_PLAN9 0x39 #define GRUB_PC_PARTITION_TYPE_EZD 0x55 #define GRUB_PC_PARTITION_TYPE_MINIX 0x80 #define GRUB_PC_PARTITION_TYPE_LINUX_MINIX 0x81 +#define GRUB_PC_PARTITION_TYPE_LINUX_SWAP 0x82 #define GRUB_PC_PARTITION_TYPE_EXT2FS 0x83 #define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED 0x85 #define GRUB_PC_PARTITION_TYPE_VSTAFS 0x9e From 645b8cd99f6a83df1c0780b0bfdf8685cd21adb9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Dec 2010 00:22:11 +0100 Subject: [PATCH 0534/1414] Allow override Plan9 device names --- grub-core/loader/i386/pc/plan9.c | 161 ++++++++++++++++++------------- 1 file changed, 93 insertions(+), 68 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 2418bf1a1..228ea6159 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -32,6 +32,7 @@ #include #include #include +#include static grub_dl_t my_mod; static struct grub_relocator *rel; @@ -43,6 +44,14 @@ static grub_uint32_t eip = 0xffffffff; #define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 #define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" +static const struct grub_arg_option options[] = + { + {"map", 'm', GRUB_ARG_OPTION_REPEATABLE, + N_("Override guessed mapping of Plan9 devices."), "GRUBDEVICE=PLAN9DEVICE", + ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + struct grub_plan9_header { grub_uint32_t magic; @@ -85,8 +94,7 @@ grub_plan9_unload (void) } static grub_err_t -grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) +grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) { grub_file_t file = 0; void *mem; @@ -94,7 +102,6 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), struct grub_plan9_header hdr; char *config, *configptr; grub_size_t configsize; - int i; char *pmap = NULL; grub_size_t pmapalloc = 256; grub_size_t pmapptr = 0; @@ -193,6 +200,7 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), grub_device_t dev; int file_disk; char *plan9name = NULL; + unsigned i; dev = grub_device_open (name); if (!dev) @@ -207,55 +215,50 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), } file_disk = file->device->disk && dev->disk->id == file->device->disk->id && dev->disk->dev->id == file->device->disk->dev->id; - switch (dev->disk->dev->id) - { - case GRUB_DISK_DEVICE_BIOSDISK_ID: - if (dev->disk->id & 0x80) - plan9name = grub_xasprintf ("sdB%u", - (unsigned) (dev->disk->id & 0x7f)); - else - plan9name = grub_xasprintf ("fd%u", - (unsigned) (dev->disk->id & 0x7f)); + for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++) + if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0 + && ctxt->state[0].args[i][grub_strlen (name)] == '=') break; - /* Shouldn't happen as Plan9 doesn't work on these platforms. */ - case GRUB_DISK_DEVICE_OFDISK_ID: - case GRUB_DISK_DEVICE_EFIDISK_ID: - - /* Plan9 doesn't see those. */ - case GRUB_DISK_DEVICE_LOOPBACK_ID: - case GRUB_DISK_DEVICE_RAID_ID: - case GRUB_DISK_DEVICE_LVM_ID: - case GRUB_DISK_DEVICE_HOST_ID: - case GRUB_DISK_DEVICE_MEMDISK_ID: - case GRUB_DISK_DEVICE_LUKS_ID: - - /* Not sure how to handle those. */ - case GRUB_DISK_DEVICE_PXE_ID: - case GRUB_DISK_DEVICE_NAND_ID: - if (!file_disk) - { - grub_device_close (dev); - return 0; - } - - /* if it's the disk the kernel is loaded from we need to name - it nevertheless. */ - plan9name = grub_strdup ("sdZ0"); - break; - - case GRUB_DISK_DEVICE_ATA_ID: + if (ctxt->state[0].args && ctxt->state[0].args[i]) + plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1); + else + switch (dev->disk->dev->id) { - int unit; - if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) - unit = 0; + case GRUB_DISK_DEVICE_BIOSDISK_ID: + if (dev->disk->id & 0x80) + plan9name = grub_xasprintf ("sdB%u", + (unsigned) (dev->disk->id & 0x7f)); else - unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); - plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); - } - break; - case GRUB_DISK_DEVICE_SCSI_ID: - if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) - == GRUB_SCSI_SUBSYSTEM_ATAPI) + plan9name = grub_xasprintf ("fd%u", + (unsigned) (dev->disk->id & 0x7f)); + break; + /* Shouldn't happen as Plan9 doesn't work on these platforms. */ + case GRUB_DISK_DEVICE_OFDISK_ID: + case GRUB_DISK_DEVICE_EFIDISK_ID: + + /* Plan9 doesn't see those. */ + case GRUB_DISK_DEVICE_LOOPBACK_ID: + case GRUB_DISK_DEVICE_RAID_ID: + case GRUB_DISK_DEVICE_LVM_ID: + case GRUB_DISK_DEVICE_HOST_ID: + case GRUB_DISK_DEVICE_MEMDISK_ID: + case GRUB_DISK_DEVICE_LUKS_ID: + + /* Not sure how to handle those. */ + case GRUB_DISK_DEVICE_PXE_ID: + case GRUB_DISK_DEVICE_NAND_ID: + if (!file_disk) + { + grub_device_close (dev); + return 0; + } + + /* if it's the disk the kernel is loaded from we need to name + it nevertheless. */ + plan9name = grub_strdup ("sdZ0"); + break; + + case GRUB_DISK_DEVICE_ATA_ID: { int unit; if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) @@ -263,16 +266,30 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), else unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); - break; } + break; + case GRUB_DISK_DEVICE_SCSI_ID: + if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) + == GRUB_SCSI_SUBSYSTEM_ATAPI) + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else + unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, + 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); + break; + } - /* FIXME: how does Plan9 number controllers? - We probably need save the SCSI devices and sort them */ - plan9name - = grub_xasprintf ("sd0%u", (unsigned) - ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) & 0xf)); - break; - } + /* FIXME: how does Plan9 number controllers? + We probably need save the SCSI devices and sort them */ + plan9name + = grub_xasprintf ("sd0%u", (unsigned) + ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) + & 0xf)); + break; + } if (!plan9name) { grub_print_error (); @@ -347,8 +364,11 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), configsize = GRUB_PLAN9_CONFIG_PATH_SIZE; /* magic */ configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; - for (i = 1; i < argc; i++) - configsize += grub_strlen (argv[i]) + 1; + { + int i; + for (i = 1; i < argc; i++) + configsize += grub_strlen (argv[i]) + 1; + } configsize += pmapptr; /* Terminating \0. */ configsize++; @@ -368,11 +388,14 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; - for (i = 1; i < argc; i++) - { - configptr = grub_stpcpy (configptr, argv[i]); - *configptr++ = '\n'; - } + { + int i; + for (i = 1; i < argc; i++) + { + configptr = grub_stpcpy (configptr, argv[i]); + *configptr++ = '\n'; + } + } configptr = grub_stpcpy (configptr, pmap); { @@ -429,16 +452,18 @@ grub_cmd_plan9 (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(plan9) { - cmd = grub_register_command ("plan9", grub_cmd_plan9, - 0, N_("Load Plan9 kernel.")); + cmd = grub_register_extcmd ("plan9", grub_cmd_plan9, + GRUB_COMMAND_OPTIONS_AT_START, + N_("KERNEL ARGS"), N_("Load Plan9 kernel."), + options); my_mod = mod; } GRUB_MOD_FINI(plan9) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } From 5c61fc9f48fee403037fc4399832f8c96d789f6a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 21 Dec 2010 00:37:03 +0100 Subject: [PATCH 0535/1414] supply boot file to plan9 --- grub-core/loader/i386/pc/plan9.c | 54 ++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 228ea6159..02d1d63cd 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -108,12 +108,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) int noslash = 1; char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"}; int prefixescnt[5]; + char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL; auto int fill_partition (grub_disk_t disk, const grub_partition_t partition); int fill_partition (grub_disk_t disk, const grub_partition_t partition) { + int file_disk = 0; + int pstart, pend; if (!noslash) { if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) @@ -122,6 +125,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) } noslash = 0; + file_disk = file->device->disk && disk->id == file->device->disk->id + && disk->dev->id == file->device->disk->dev->id; + + pstart = pmapptr; if (grub_strcmp (partition->partmap->name, "plan") == 0) { unsigned ptr = partition->index + sizeof ("part ") - 1; @@ -180,7 +187,8 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) return 1; grub_strcpy (pmap + pmapptr, name); pmapptr += grub_strlen (name); - } + } + pend = pmapptr; if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, (void **) &pmap)) return 1; @@ -190,6 +198,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) grub_partition_get_start (partition), grub_partition_get_start (partition) + grub_partition_get_len (partition)); + if (file_disk && grub_partition_get_start (partition) + == grub_partition_get_start (file->device->disk->partition) + && grub_partition_get_len (partition) + == grub_partition_get_len (file->device->disk->partition)) + { + grub_free (bootpart); + bootpart = grub_strndup (pmap + pstart, pend - pstart); + } + pmapptr += grub_strlen (pmap + pmapptr); return 0; } @@ -198,9 +215,9 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) int fill_disk (const char *name) { grub_device_t dev; - int file_disk; char *plan9name = NULL; unsigned i; + int file_disk = 0; dev = grub_device_open (name); if (!dev) @@ -304,7 +321,13 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) } grub_strcpy (pmap + pmapptr, plan9name); pmapptr += grub_strlen (plan9name); - grub_free (plan9name); + if (!file_disk) + grub_free (plan9name); + else + { + grub_free (bootdisk); + bootdisk = plan9name; + } grub_strcpy (pmap + pmapptr, "part="); pmapptr += sizeof ("part=") - 1; @@ -344,6 +367,25 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) goto fail; pmap[pmapptr] = 0; + { + char *file_name = grub_strchr (argv[0], ')'); + if (file_name) + file_name++; + else + file_name = argv[0]; + if (*file_name) + file_name++; + + if (bootpart) + bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name); + else + bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name); + grub_free (bootdisk); + grub_free (bootpart); + } + if (!bootpath) + goto fail; + if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) goto fail; @@ -369,6 +411,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) for (i = 1; i < argc; i++) configsize += grub_strlen (argv[i]) + 1; } + configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1; configsize += pmapptr; /* Terminating \0. */ configsize++; @@ -384,10 +427,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) } grub_memset (config, 0, GRUB_PLAN9_CONFIG_PATH_SIZE); + grub_strncpy (config, bootpath, GRUB_PLAN9_CONFIG_PATH_SIZE - 1); + configptr = config + GRUB_PLAN9_CONFIG_PATH_SIZE; grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; + configptr = grub_stpcpy (configptr, "bootfile="); + configptr = grub_stpcpy (configptr, bootpath); + *configptr++ = '\n'; { int i; for (i = 1; i < argc; i++) From 4e01b6c821b46c83b19a22b7ecd0207780c90ab0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Dec 2010 12:49:29 +0000 Subject: [PATCH 0536/1414] * util/grub-mkconfig_lib.in (gettext_quoted): Add clarifying comment. Add an extra layer of quotation, requiring the output of this function to be used in a printf format string. (gettext_printf): New function. * util/grub.d/10_hurd.in: Use gettext_printf where appropriate. Extract translatable strings from here-documents and use a temporary variable instead, so that xgettext can find them. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. * util/grub.d/20_linux_xen.in: Likewise. * po/grub.d.sed: New file. * po/Makefile.in.in ($(DOMAIN).pot-update): Extract gettext_printf arguments. Set c-format flags on all strings extracted from util/grub.d/ (xgettext refuses to include these itself for strings it extracted from a shell file, but these really are c-format). --- ChangeLog | 19 +++++++++++++++++++ po/Makefile.in.in | 8 ++++++-- po/grub.d.sed | 2 ++ util/grub-mkconfig_lib.in | 14 +++++++++++++- util/grub.d/10_hurd.in | 12 ++++++++---- util/grub.d/10_kfreebsd.in | 3 ++- util/grub.d/10_linux.in | 6 ++++-- util/grub.d/20_linux_xen.in | 6 ++++-- 8 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 po/grub.d.sed diff --git a/ChangeLog b/ChangeLog index 6e564324b..ca555a662 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-12-21 Colin Watson + + * util/grub-mkconfig_lib.in (gettext_quoted): Add clarifying + comment. Add an extra layer of quotation, requiring the output of + this function to be used in a printf format string. + (gettext_printf): New function. + * util/grub.d/10_hurd.in: Use gettext_printf where appropriate. + Extract translatable strings from here-documents and use a temporary + variable instead, so that xgettext can find them. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + + * po/grub.d.sed: New file. + * po/Makefile.in.in ($(DOMAIN).pot-update): Extract gettext_printf + arguments. Set c-format flags on all strings extracted from + util/grub.d/ (xgettext refuses to include these itself for strings + it extracted from a shell file, but these really are c-format). + 2010-12-20 Vladimir Serbinenko * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_add_module): diff --git a/po/Makefile.in.in b/po/Makefile.in.in index d0af6c962..b0e7b8fa2 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -173,7 +173,8 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell --files-from=$(srcdir)/POTFILES-shell.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --msgid-bugs-address="$$msgid_bugs_address" \ - --join-existing --language=Shell --keyword=gettext_quoted \ + --join-existing --language=Shell \ + --keyword=gettext_quoted --keyword=gettext_printf \ ;; \ *) \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ @@ -183,10 +184,13 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell --package-name="$${package_gnu}@PACKAGE@" \ --package-version='@VERSION@' \ --msgid-bugs-address="$$msgid_bugs_address" \ - --join-existing --language=Shell --keyword=gettext_quoted \ + --join-existing --language=Shell \ + --keyword=gettext_quoted --keyword=gettext_printf \ ;; \ esac test ! -f $(DOMAIN).po || { \ + sed -f grub.d.sed < $(DOMAIN).po > $(DOMAIN).1po && \ + mv $(DOMAIN).1po $(DOMAIN).po; \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ diff --git a/po/grub.d.sed b/po/grub.d.sed new file mode 100644 index 000000000..9fd729474 --- /dev/null +++ b/po/grub.d.sed @@ -0,0 +1,2 @@ +/^#: util\/grub\.d\//a\ +#, c-format diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 41359975e..ec4084698 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -187,8 +187,20 @@ version_find_latest () echo "$a" } +# One layer of quotation is eaten by "", the second by sed, and the third by +# printf; so this turns ' into \'. Note that you must use the output of +# this function in a printf format string. gettext_quoted () { - $gettext "$@" | sed "s/'/'\\\\''/g" + $gettext "$@" | sed "s/'/'\\\\\\\\''/g" +} + +# Run the first argument through gettext_quoted, and then pass that and all +# remaining arguments to printf. This is a useful abbreviation and tends to +# be easier to type. +gettext_printf () { + local format="$1" + shift + printf "$(gettext_quoted "$format")" "$@" } uses_abstraction () { diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 6490913ae..eeb441aa4 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -81,14 +81,16 @@ do menuentry "${OS} ${KERNEL}" ${CLASS} { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + message="$(gettext_printf "Loading GNU Mach ...")" cat << EOF - echo '$(gettext_quoted "Loading GNU Mach ...")' + echo '$message' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + message="$(gettext_printf "Loading the Hurd ...")" cat << EOF - echo '$(gettext_quoted "Loading the Hurd ...")' + echo '$message' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ --host-priv-port='\${host-port}' \\ @@ -103,13 +105,15 @@ EOF menuentry "${OS} ${KERNEL} (recovery mode)" ${CLASS} { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + message="$(gettext_printf "Loading GNU Mach ...")" cat << EOF - echo '$(gettext_quoted "Loading GNU Mach ...")' + echo '$message' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + message="$(gettext_printf "Loading the Hurd ...")" cat << EOF - echo '$(gettext_quoted "Loading the Hurd ...")' + echo '$message' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ --host-priv-port='\${host-port}' \\ diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 9cb2788df..b026812a7 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -84,8 +84,9 @@ kfreebsd_entry () fi printf '%s\n' "${prepare_boot_cache}" + message="$(gettext_printf "Loading kernel of FreeBSD %s ..." ${version})" cat << EOF - echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})' + echo '$message' kfreebsd ${rel_dirname}/${basename} ${args} EOF diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 7650ac9fa..a09c3e687 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -94,13 +94,15 @@ EOF prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi printf '%s\n' "${prepare_boot_cache}" + message="$(gettext_printf "Loading Linux %s ..." ${version})" cat << EOF - echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})' + echo '$message' linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then + message="$(gettext_printf "Loading initial ramdisk ...")" cat << EOF - echo '$(gettext_quoted "Loading initial ramdisk ...")' + echo '$message' initrd ${rel_dirname}/${initrd} EOF fi diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 649ae85dd..a90211f44 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -73,14 +73,16 @@ linux_entry () prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi printf '%s\n' "${prepare_boot_cache}" + message="$(gettext_printf "Loading Linux %s ..." ${version})" cat << EOF - echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})' + echo '$message' multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then + message="$(gettext_printf "Loading initial ramdisk ...")" cat << EOF - echo '$(gettext_quoted "Loading initial ramdisk ...")' + echo '$message' module ${rel_dirname}/${initrd} EOF fi From b889cfadf9e3cf85f538d5eb206028b583bff7ef Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Dec 2010 13:00:10 +0000 Subject: [PATCH 0537/1414] * grub-core/fs/udf.c (read_string): Pacify GCC warning by initialising utf16. --- ChangeLog | 5 +++++ grub-core/fs/udf.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca555a662..42e059d46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-12-21 Colin Watson + + * grub-core/fs/udf.c (read_string): Pacify GCC warning by + initialising utf16. + 2010-12-21 Colin Watson * util/grub-mkconfig_lib.in (gettext_quoted): Add clarifying diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 51726edf3..1672aab1b 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -791,7 +791,7 @@ fail: static char * read_string (grub_uint8_t *raw, grub_size_t sz) { - grub_uint16_t *utf16; + grub_uint16_t *utf16 = NULL; char *ret; grub_size_t utf16len = 0; From d060ad60eee798a5c7c970ca2e777c7f1d0f8caa Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Dec 2010 13:52:07 +0000 Subject: [PATCH 0538/1414] * grub-core/commands/echo.c (grub_cmd_echo): Make UTF-8-clean by constructing a new unescaped string and passing it to grub_xputs in one go, rather than passing characters to grub_printf one at a time. --- ChangeLog | 6 ++++++ grub-core/commands/echo.c | 26 ++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42e059d46..e65dc231c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-21 Colin Watson + + * grub-core/commands/echo.c (grub_cmd_echo): Make UTF-8-clean by + constructing a new unescaped string and passing it to grub_xputs in + one go, rather than passing characters to grub_printf one at a time. + 2010-12-21 Colin Watson * grub-core/fs/udf.c (read_string): Pacify GCC warning by diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c index 7ab9f92c6..93a452fc8 100644 --- a/grub-core/commands/echo.c +++ b/grub-core/commands/echo.c @@ -44,8 +44,14 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) for (i = 0; i < argc; i++) { char *arg = *args; + /* Unescaping results in a string no longer than the original. */ + char *unescaped = grub_malloc (grub_strlen (arg) + 1); + char *p = unescaped; args++; + if (!unescaped) + return grub_errno; + while (*arg) { /* In case `-e' is used, parse backslashes. */ @@ -58,11 +64,11 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) switch (*arg) { case '\\': - grub_printf ("\\"); + *p++ = '\\'; break; case 'a': - grub_printf ("\a"); + *p++ = '\a'; break; case 'c': @@ -70,23 +76,23 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) break; case 'f': - grub_printf ("\f"); + *p++ = '\f'; break; case 'n': - grub_printf ("\n"); + *p++ = '\n'; break; case 'r': - grub_printf ("\r"); + *p++ = '\r'; break; case 't': - grub_printf ("\t"); + *p++ = '\t'; break; case 'v': - grub_printf ("\v"); + *p++ = '\v'; break; } arg++; @@ -95,10 +101,14 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) /* This was not an escaped character, or escaping is not enabled. */ - grub_printf ("%c", *arg); + *p++ = *arg; arg++; } + *p = '\0'; + grub_xputs (unescaped); + grub_free (unescaped); + /* If another argument follows, insert a space. */ if (i != argc - 1) grub_printf (" " ); From 20641b6baad5d5a18ec5d5cd5305e01ff3c7f025 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Dec 2010 16:51:08 +0000 Subject: [PATCH 0539/1414] * grub-core/lib/reed_solomon.c (gauss_solve): Fix size of standalone scratch area. Make sure to initialise chosen in standalone mode as well as non-standalone. Reported by: Robert Hooker and Andy Whitcroft. Tested by: Andy Whitcroft. --- ChangeLog | 8 ++++++++ grub-core/lib/reed_solomon.c | 12 +++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e65dc231c..4c7225bc5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-12-21 Colin Watson + + * grub-core/lib/reed_solomon.c (gauss_solve): Fix size of standalone + scratch area. Make sure to initialise chosen in standalone mode as + well as non-standalone. + Reported by: Robert Hooker and Andy Whitcroft. + Tested by: Andy Whitcroft. + 2010-12-21 Colin Watson * grub-core/commands/echo.c (grub_cmd_echo): Make UTF-8-clean by diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 4c6e160e4..6f571550a 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -18,6 +18,8 @@ #ifdef TEST #include +#include +#include #define xmalloc malloc #define grub_memset memset #define grub_memcpy memcpy @@ -25,8 +27,6 @@ #ifndef STANDALONE #ifdef TEST -#include -#include typedef unsigned int grub_size_t; typedef unsigned char grub_uint8_t; typedef unsigned short grub_uint16_t; @@ -45,6 +45,7 @@ typedef unsigned char grub_uint8_t; typedef unsigned short grub_uint16_t; #else #include +#include #endif void grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs); @@ -207,11 +208,12 @@ gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol) #ifndef STANDALONE chosen = xmalloc (n * sizeof (int)); - grub_memset (chosen, -1, n * sizeof (int)); #else chosen = (void *) scratch; - scratch += n; + scratch += n * sizeof (int); #endif + for (i = 0; i < n; i++) + chosen[i] = -1; for (i = 0; i < m; i++) sol[i] = 0; gauss_eliminate (eq, n, m, chosen); @@ -228,7 +230,7 @@ gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol) #ifndef STANDALONE free (chosen); #else - scratch -= n; + scratch -= n * sizeof (int); #endif } From 1426ef3560721b04db1d3e162957825a00753cd8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 21 Dec 2010 17:41:47 +0000 Subject: [PATCH 0540/1414] * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): The previous patch increased the size of the RS code by 20 bytes (at least with gcc-4.4), so increase this by 20 bytes to match. (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. --- ChangeLog | 7 +++++++ include/grub/offsets.h | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c7225bc5..27e2aee97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-21 Colin Watson + + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): The + previous patch increased the size of the RS code by 20 bytes (at + least with gcc-4.4), so increase this by 20 bytes to match. + (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. + 2010-12-21 Colin Watson * grub-core/lib/reed_solomon.c (gauss_solve): Fix size of standalone diff --git a/include/grub/offsets.h b/include/grub/offsets.h index b096abf37..817372b69 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -38,9 +38,9 @@ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x1c /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc90 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xca4 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6f8 +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x70c /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE From ab66c69f1a91617b429d73c59987e2c0c7d898c3 Mon Sep 17 00:00:00 2001 From: Jordan Uggla Date: Thu, 23 Dec 2010 11:51:18 +0000 Subject: [PATCH 0541/1414] * tests/util/grub-shell.in: Suppress "ACPI shutdown failed" error to keep unit tests from failing when they shouldn't. --- ChangeLog | 5 +++++ tests/util/grub-shell.in | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 27e2aee97..79eeae387 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-12-23 Jordan Uggla + + * tests/util/grub-shell.in: Suppress "ACPI shutdown failed" error to + keep unit tests from failing when they shouldn't. + 2010-12-21 Colin Watson * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): The diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index fc14ca7b0..e35d6bc65 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -132,6 +132,8 @@ done cat <>${cfgfile} source /boot/grub/testcase.cfg +# Stop serial output to suppress "ACPI shutdown failed" error. +terminal_output console halt EOF From 1c95b6d2bfb721df4859414a4f31ac8ed9c7bc8d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 23 Dec 2010 12:11:44 +0000 Subject: [PATCH 0542/1414] 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 0543/1414] 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 c7336d912c656c4b7c7162e8dee6f5001e732be5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Dec 2010 16:07:53 +0100 Subject: [PATCH 0544/1414] splitting generic ata from pata. --- commands/hdparm.c | 95 +++-- disk/ahci.c | 289 ++++++++++----- disk/ata.c | 829 ++++++++++++++------------------------------ disk/ata_pthru.c | 520 ++++++++++++++++++++++++--- disk/scsi.c | 38 +- disk/usbms.c | 12 +- include/grub/ata.h | 122 ++++--- include/grub/disk.h | 13 +- include/grub/scsi.h | 16 +- kern/disk.c | 4 - 10 files changed, 1095 insertions(+), 843 deletions(-) diff --git a/commands/hdparm.c b/commands/hdparm.c index a3f8bbff0..02ae8f36b 100644 --- a/commands/hdparm.c +++ b/commands/hdparm.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -61,60 +62,60 @@ enum grub_ata_smart_commands static int quiet = 0; static grub_err_t -grub_hdparm_do_ata_cmd (grub_disk_t disk, grub_uint8_t cmd, +grub_hdparm_do_ata_cmd (grub_ata_t ata, grub_uint8_t cmd, grub_uint8_t features, grub_uint8_t sectors, void * buffer, int size) { struct grub_disk_ata_pass_through_parms apt; grub_memset (&apt, 0, sizeof (apt)); - apt.taskfile[GRUB_ATA_REG_CMD] = cmd; - apt.taskfile[GRUB_ATA_REG_FEATURES] = features; - apt.taskfile[GRUB_ATA_REG_SECTORS] = sectors; + apt.taskfile.cmd = cmd; + apt.taskfile.features = features; + apt.taskfile.sectors = sectors; apt.buffer = buffer; apt.size = size; - if (grub_disk_ata_pass_through (disk, &apt)) + if (ata->dev->readwrite (ata, &apt)) return grub_errno; return GRUB_ERR_NONE; } static int -grub_hdparm_do_check_powermode_cmd (grub_disk_t disk) +grub_hdparm_do_check_powermode_cmd (grub_ata_t ata) { struct grub_disk_ata_pass_through_parms apt; grub_memset (&apt, 0, sizeof (apt)); - apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_CHECK_POWER_MODE; + apt.taskfile.cmd = GRUB_ATA_CMD_CHECK_POWER_MODE; - if (grub_disk_ata_pass_through (disk, &apt)) + if (ata->dev->readwrite (ata, &apt)) return -1; - return apt.taskfile[GRUB_ATA_REG_SECTORS]; + return apt.taskfile.sectors; } static int -grub_hdparm_do_smart_cmd (grub_disk_t disk, grub_uint8_t features) +grub_hdparm_do_smart_cmd (grub_ata_t ata, grub_uint8_t features) { struct grub_disk_ata_pass_through_parms apt; grub_memset (&apt, 0, sizeof (apt)); - apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_SMART; - apt.taskfile[GRUB_ATA_REG_FEATURES] = features; - apt.taskfile[GRUB_ATA_REG_LBAMID] = 0x4f; - apt.taskfile[GRUB_ATA_REG_LBAHIGH] = 0xc2; + apt.taskfile.cmd = GRUB_ATA_CMD_SMART; + apt.taskfile.features = features; + apt.taskfile.lba_mid = 0x4f; + apt.taskfile.lba_high = 0xc2; - if (grub_disk_ata_pass_through (disk, &apt)) + if (ata->dev->readwrite (ata, &apt)) return -1; if (features == GRUB_ATA_FEAT_SMART_STATUS) { - if ( apt.taskfile[GRUB_ATA_REG_LBAMID] == 0x4f - && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0xc2) + if ( apt.taskfile.lba_mid == 0x4f + && apt.taskfile.lba_high == 0xc2) return 0; /* Good SMART status. */ - else if ( apt.taskfile[GRUB_ATA_REG_LBAMID] == 0xf4 - && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0x2c) + else if ( apt.taskfile.lba_mid == 0xf4 + && apt.taskfile.lba_high == 0x2c) return 1; /* Bad SMART status. */ else return -1; @@ -124,12 +125,12 @@ grub_hdparm_do_smart_cmd (grub_disk_t disk, grub_uint8_t features) static grub_err_t grub_hdparm_simple_cmd (const char * msg, - grub_disk_t disk, grub_uint8_t cmd) + grub_ata_t ata, grub_uint8_t cmd) { if (! quiet && msg) grub_printf ("%s", msg); - grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, 0, 0, NULL, 0); + grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, 0, 0, NULL, 0); if (! quiet && msg) grub_printf ("%s\n", ! err ? "" : ": not supported"); @@ -138,7 +139,7 @@ grub_hdparm_simple_cmd (const char * msg, static grub_err_t grub_hdparm_set_val_cmd (const char * msg, int val, - grub_disk_t disk, grub_uint8_t cmd, + grub_ata_t ata, grub_uint8_t cmd, grub_uint8_t features, grub_uint8_t sectors) { if (! quiet && msg && *msg) @@ -149,7 +150,7 @@ grub_hdparm_set_val_cmd (const char * msg, int val, grub_printf ("Disable %s", msg); } - grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, features, sectors, + grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, features, sectors, NULL, 0); if (! quiet && msg) @@ -273,6 +274,7 @@ static grub_err_t grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? { struct grub_arg_list *state = cmd->state; + struct grub_ata *ata; /* Check command line. */ if (argc != 1) @@ -283,9 +285,6 @@ grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? return grub_error (GRUB_ERR_BAD_ARGUMENT, "argument is not a device name"); args[0][len - 1] = 0; - if (! grub_disk_ata_pass_through) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "ATA pass through not available"); - int i = 0; int apm = get_int_arg (&state[i++]); int power = state[i++].set; @@ -311,15 +310,37 @@ grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? return grub_error (GRUB_ERR_BAD_ARGUMENT, "partition not allowed"); } + switch (disk->dev->id) + { + case GRUB_DISK_DEVICE_ATA_ID: + ata = disk->data; + break; + case GRUB_DISK_DEVICE_SCSI_ID: + if (((disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xFF) + == GRUB_SCSI_SUBSYSTEM_PATA + || (((disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xFF) + == GRUB_SCSI_SUBSYSTEM_AHCI)) + { + ata = ((struct grub_scsi *) disk->data)->data; + break; + } + default: + return grub_error (GRUB_ERR_IO, "not an ATA device"); + } + + /* Change settings. */ if (aam >= 0) grub_hdparm_set_val_cmd ("Automatic Acoustic Management", (aam ? aam : -1), - disk, GRUB_ATA_CMD_SET_FEATURES, (aam ? 0x42 : 0xc2), aam); + ata, GRUB_ATA_CMD_SET_FEATURES, + (aam ? 0x42 : 0xc2), aam); if (apm >= 0) grub_hdparm_set_val_cmd ("Advanced Power Management", - (apm != 255 ? apm : -1), disk, GRUB_ATA_CMD_SET_FEATURES, - (apm != 255 ? 0x05 : 0x85), (apm != 255 ? apm : 0)); + (apm != 255 ? apm : -1), ata, + GRUB_ATA_CMD_SET_FEATURES, + (apm != 255 ? 0x05 : 0x85), + (apm != 255 ? apm : 0)); if (standby_tout >= 0) { @@ -330,28 +351,28 @@ grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? grub_printf (")"); } /* The IDLE cmd sets disk to idle mode and configures standby timer. */ - grub_hdparm_set_val_cmd ("", -1, disk, GRUB_ATA_CMD_IDLE, 0, standby_tout); + grub_hdparm_set_val_cmd ("", -1, ata, GRUB_ATA_CMD_IDLE, 0, standby_tout); } if (enable_smart >= 0) { if (! quiet) grub_printf ("%sable SMART operations", (enable_smart ? "En" : "Dis")); - int err = grub_hdparm_do_smart_cmd (disk, (enable_smart ? + int err = grub_hdparm_do_smart_cmd (ata, (enable_smart ? GRUB_ATA_FEAT_SMART_ENABLE : GRUB_ATA_FEAT_SMART_DISABLE)); if (! quiet) grub_printf ("%s\n", err ? ": not supported" : ""); } if (sec_freeze) - grub_hdparm_simple_cmd ("Freeze security settings", disk, + grub_hdparm_simple_cmd ("Freeze security settings", ata, GRUB_ATA_CMD_SECURITY_FREEZE_LOCK); /* Print/dump IDENTIFY. */ if (ident || dumpid) { char buf[GRUB_DISK_SECTOR_SIZE]; - if (grub_hdparm_do_ata_cmd (disk, GRUB_ATA_CMD_IDENTIFY_DEVICE, + if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_IDENTIFY_DEVICE, 0, 0, buf, sizeof (buf))) grub_printf ("Cannot read ATA IDENTIFY data\n"); else @@ -367,7 +388,7 @@ grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? if (power) { grub_printf ("Disk power mode is: "); - int mode = grub_hdparm_do_check_powermode_cmd (disk); + int mode = grub_hdparm_do_check_powermode_cmd (ata); if (mode < 0) grub_printf ("unknown\n"); else @@ -383,7 +404,7 @@ grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? { if (! quiet) grub_printf ("SMART status is: "); - int err = grub_hdparm_do_smart_cmd (disk, GRUB_ATA_FEAT_SMART_STATUS); + int err = grub_hdparm_do_smart_cmd (ata, GRUB_ATA_FEAT_SMART_STATUS); if (! quiet) grub_printf ("%s\n", (err < 0 ? "unknown" : err == 0 ? "OK" : "*BAD*")); @@ -392,11 +413,11 @@ grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? /* Change power mode. */ if (standby_now) - grub_hdparm_simple_cmd ("Set disk to standby mode", disk, + grub_hdparm_simple_cmd ("Set disk to standby mode", ata, GRUB_ATA_CMD_STANDBY_IMMEDIATE); if (sleep_now) - grub_hdparm_simple_cmd ("Set disk to sleep mode", disk, + grub_hdparm_simple_cmd ("Set disk to sleep mode", ata, GRUB_ATA_CMD_SLEEP); grub_disk_close (disk); diff --git a/disk/ahci.c b/disk/ahci.c index 1372fd651..946db82e1 100644 --- a/disk/ahci.c +++ b/disk/ahci.c @@ -21,39 +21,79 @@ #include #include #include +#include #include +#include +#include struct grub_ahci_cmd_head { - grub_uint32_t unused[8]; + grub_uint32_t config; + grub_uint32_t transfered; + grub_uint64_t command_table_base; + grub_uint32_t unused[4]; +}; + +struct grub_ahci_prdt_entry +{ + grub_uint64_t data_base; + grub_uint32_t unused; + grub_uint32_t size; +}; + +struct grub_ahci_cmd_table +{ + grub_uint8_t cfis[0x40]; + grub_uint8_t command[16]; + grub_uint32_t reserved[0xc]; + struct grub_ahci_prdt_entry prdt[1]; }; struct grub_ahci_hba_port { grub_uint64_t command_list_base; - grub_uint32_t unused[12]; + grub_uint64_t fis_base; + grub_uint32_t intstatus; + grub_uint32_t inten; + grub_uint32_t command; + grub_uint32_t unused1[6]; grub_uint32_t sata_active; grub_uint32_t command_issue; - grub_uint32_t unused[16]; + grub_uint32_t unused2[17]; }; struct grub_ahci_hba { grub_uint32_t cap; -#define GRUB_AHCI_HBA_CAP_MASK 0x1f grub_uint32_t global_control; -#define GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN 0x80000000 + grub_uint32_t intr_status; grub_uint32_t ports_implemented; - grub_uint32_t unused1[7]; + grub_uint32_t unused1[6]; grub_uint32_t bios_handoff; -#define GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED 1 -#define GRUB_AHCI_BIOS_HANDOFF_OS_OWNED 2 -#define GRUB_AHCI_BIOS_HANDOFF_OS_OWNERSHIP_CHANGED 8 -#define GRUB_AHCI_BIOS_HANDOFF_RWC 8 grub_uint32_t unused2[53]; struct grub_ahci_hba_port ports[32]; }; +enum + { + GRUB_AHCI_HBA_CAP_NPORTS_MASK = 0x1f + }; + +enum + { + GRUB_AHCI_HBA_GLOBAL_CONTROL_INTR_EN = 0x00000002, + GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN = 0x80000000, + }; + +enum + { + GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED = 1, + GRUB_AHCI_BIOS_HANDOFF_OS_OWNED = 2, + GRUB_AHCI_BIOS_HANDOFF_OS_OWNERSHIP_CHANGED = 8, + GRUB_AHCI_BIOS_HANDOFF_RWC = 8 + }; + + struct grub_ahci_device { struct grub_ahci_device *next; @@ -62,19 +102,41 @@ struct grub_ahci_device int num; struct grub_pci_dma_chunk *command_list_chunk; volatile struct grub_ahci_cmd_head *command_list; + struct grub_pci_dma_chunk *command_table_chunk; + volatile struct grub_ahci_cmd_table *command_table; }; +enum + { + GRUB_AHCI_CONFIG_READ = 0, + GRUB_AHCI_CONFIG_CFIS_LENGTH_MASK = 0x1f, + GRUB_AHCI_CONFIG_ATAPI = 0x20, + GRUB_AHCI_CONFIG_WRITE = 0x40, + GRUB_AHCI_CONFIG_PREFETCH = 0x80, + GRUB_AHCI_CONFIG_RESET = 0x100, + GRUB_AHCI_CONFIG_BIST = 0x200, + GRUB_AHCI_CONFIG_CLEAR_R_OK = 0x400, + GRUB_AHCI_CONFIG_PMP_MASK = 0xf000, + GRUB_AHCI_CONFIG_PRDT_LENGTH_MASK = 0xffff0000, + }; +#define GRUB_AHCI_CONFIG_CFIS_LENGTH_SHIFT 0 +#define GRUB_AHCI_CONFIG_PMP_SHIFT 12 +#define GRUB_AHCI_CONFIG_PRDT_LENGTH_SHIFT 16 +#define GRUB_AHCI_INTERRUPT_ON_COMPLETE 0x80000000 + +#define GRUB_AHCI_PRDT_MAX_CHUNK_LENGTH 0x200000 + static struct grub_ahci_device *grub_ahci_devices; static int numdevs; static int NESTED_FUNC_ATTR grub_ahci_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__ ((unused))) + grub_pci_id_t pciid __attribute__ ((unused))) { grub_pci_address_t addr; grub_uint32_t class; grub_uint32_t bar; - int nports; + unsigned i, nports; volatile struct grub_ahci_hba *hba; /* Read class. */ @@ -88,8 +150,8 @@ grub_ahci_pciinit (grub_pci_device_t dev, addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG5); bar = grub_pci_read (addr); - if (bar & (GRUB_PCI_ADDR_SPACE_MASK | GRUB_PCI_ADDR_MEM_TYPE_MASK - | GRUB_PCI_ADDR_MEM_PREFETCH) + if ((bar & (GRUB_PCI_ADDR_SPACE_MASK | GRUB_PCI_ADDR_MEM_TYPE_MASK + | GRUB_PCI_ADDR_MEM_PREFETCH)) != (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32)) return 0; @@ -98,7 +160,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; - nports = hba->cap & GRUB_AHCI_HBA_CAP_MASK; + nports = (hba->cap & GRUB_AHCI_HBA_CAP_NPORTS_MASK) + 1; if (! (hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_OS_OWNED)) { @@ -122,11 +184,13 @@ grub_ahci_pciinit (grub_pci_device_t dev, } else grub_dprintf ("ahci", "AHCI is already in OS mode\n"); + grub_dprintf ("ahci", "%d AHCI ports\n", nports); for (i = 0; i < nports; i++) { struct grub_ahci_device *adev; struct grub_pci_dma_chunk *command_list; + struct grub_pci_dma_chunk *command_table; if (!(hba->ports_implemented & (1 << i))) continue; @@ -136,18 +200,34 @@ grub_ahci_pciinit (grub_pci_device_t dev, if (!command_list) return 1; - adev = grub_malloc (sizeof (*adev)); - if (!adev) + command_table = grub_memalign_dma32 (1024, + sizeof (struct grub_ahci_cmd_table)); + if (!command_table) { grub_dma_free (command_list); return 1; } + adev = grub_malloc (sizeof (*adev)); + if (!adev) + { + grub_dma_free (command_list); + grub_dma_free (command_table); + return 1; + } + + grub_dprintf ("ahci", "found device ahci%d (port %d)\n", numdevs, i); + adev->hba = hba; adev->port = i; adev->num = numdevs++; adev->command_list_chunk = command_list; adev->command_list = grub_dma_get_virt (command_list); + adev->command_table_chunk = command_table; + adev->command_table = grub_dma_get_virt (command_table); + adev->command_list->command_table_base + = grub_dma_get_phys (command_table); + adev->hba->ports[i].command_list_base = grub_dma_get_phys (command_list); grub_list_push (GRUB_AS_LIST_P (&grub_ahci_devices), GRUB_AS_LIST (adev)); @@ -167,12 +247,12 @@ grub_ahci_initialize (void) static int -grub_ahci_iterate (int (*hook) (int bus, int luns)) +grub_ahci_iterate (int (*hook) (int id, int bus)) { struct grub_ahci_device *dev; FOR_LIST_ELEMENTS(dev, grub_ahci_devices) - if (hook (dev->num, 1)) + if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num)) return 1; return 0; @@ -195,95 +275,130 @@ find_free_cmd_slot (struct grub_ahci_device *dev) } #endif -static grub_err_t -grub_ahci_packet (struct grub_ahci_device *dev, char *packet, - grub_size_t size) +enum + { + GRUB_AHCI_FIS_REG_H2D = 0x27 + }; + +static const int register_map[11] = { 3 /* Features */, + 12 /* Sectors */, + 4 /* LBA low */, + 5 /* LBA mid */, + 6 /* LBA high */, + 7 /* Device */, + 2 /* CMD register */, + 13 /* Sectors 48 */, + 8 /* LBA48 low */, + 9 /* LBA48 mid */, + 10 /* LBA48 high */ }; + +static grub_err_t +grub_ahci_readwrite (grub_ata_t disk, + struct grub_disk_ata_pass_through_parms *parms) { + struct grub_ahci_device *dev = (struct grub_ahci_device *) disk->data; + struct grub_pci_dma_chunk *bufc; + grub_uint64_t endtime; + unsigned i; + + grub_dprintf("ahci", "grub_ahci_read (size=%llu, cmdsize = %llu)\n", + (unsigned long long) parms->size, + (unsigned long long) parms->cmdsize); + + if (parms->cmdsize != 0 && parms->cmdsize != 12 && parms->cmdsize != 16) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "incorrect ATAPI command size"); + + if (parms->size > GRUB_AHCI_PRDT_MAX_CHUNK_LENGTH) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too big data buffer"); + + bufc = grub_memalign_dma32 (1024, parms->size + (parms->size & 1)); + + /* FIXME: support port multipliers. */ + dev->command_list[0].config + = (4 << GRUB_AHCI_CONFIG_CFIS_LENGTH_SHIFT) + | GRUB_AHCI_CONFIG_CLEAR_R_OK + | (0 << GRUB_AHCI_CONFIG_PMP_SHIFT) + | (1 << GRUB_AHCI_CONFIG_PRDT_LENGTH_SHIFT) + | (parms->cmdsize ? GRUB_AHCI_CONFIG_ATAPI : 0) + | (parms->write ? GRUB_AHCI_CONFIG_WRITE : GRUB_AHCI_CONFIG_READ); + dev->command_list[0].transfered = 0; + dev->command_list[0].command_table_base + = grub_dma_get_phys (dev->command_table_chunk); + grub_memset ((char *) dev->command_list[0].unused, 0, + sizeof (dev->command_list[0].unused)); + grub_memset ((char *) &dev->command_table[0], 0, + sizeof (dev->command_table[0])); + if (parms->cmdsize) + grub_memcpy ((char *) dev->command_table[0].command, parms->cmd, + parms->cmdsize); + + dev->command_table[0].cfis[0] = GRUB_AHCI_FIS_REG_H2D; + for (i = 0; i < sizeof (parms->taskfile.raw); i++) + dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i]; + + dev->command_table[0].prdt[0].data_base = grub_dma_get_phys (bufc); + dev->command_table[0].prdt[0].unused = 0; + dev->command_table[0].prdt[0].size = (parms->size + (parms->size & 1) - 1) + | GRUB_AHCI_INTERRUPT_ON_COMPLETE; + + if (parms->write) + grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size); + + grub_dprintf ("ahci", "AHCI command schedulded\n"); + dev->hba->ports[dev->port].inten = (1 << 5); + dev->hba->ports[dev->port].intstatus = (1 << 5); + dev->hba->ports[dev->port].command_issue |= 1; + dev->hba->ports[dev->port].command |= 1; + + endtime = grub_get_time_ms () + 1000; + while (!(dev->hba->ports[dev->port].intstatus & (1 << 5))) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "AHCI timeout\n"); + dev->hba->ports[dev->port].command &= ~1; + /* FIXME: free resources. */ + return grub_error (GRUB_ERR_IO, "AHCI transfer timeouted"); + } + + grub_dprintf ("ahci", "AHCI command completed succesfully\n"); + dev->hba->ports[dev->port].command &= ~1; + + if (!parms->write) + grub_memcpy (parms->buffer, (char *) grub_dma_get_virt (bufc), parms->size); + grub_dma_free (bufc); return GRUB_ERR_NONE; } static grub_err_t -grub_ahci_read (struct grub_scsi *scsi, - grub_size_t cmdsize __attribute__((unused)), - char *cmd, grub_size_t size, char *buf) -{ - struct grub_ahci_device *dev = (struct grub_ahci_device *) scsi->data; - - grub_dprintf("ahci", "grub_ahci_read (size=%llu)\n", (unsigned long long) size); - - if (grub_atapi_packet (dev, cmd, size)) - return grub_errno; - - grub_size_t nread = 0; - while (nread < size) - { - /* Wait for !BSY, DRQ, I/O, !C/D. */ - if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - /* Get byte count for this DRQ assertion. */ - unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 - | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW); - grub_dprintf("ata", "DRQ count=%u\n", cnt); - - /* Count of last transfer may be uneven. */ - if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread))) - return grub_error (GRUB_ERR_READ_ERROR, "invalid ATAPI transfer count"); - - /* Read the data. */ - grub_ata_pio_read (dev, buf + nread, cnt); - - if (cnt & 1) - buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA)); - - nread += cnt; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_ahci_write (struct grub_scsi *scsi __attribute__((unused)), - grub_size_t cmdsize __attribute__((unused)), - char *cmd __attribute__((unused)), - grub_size_t size __attribute__((unused)), - char *buf __attribute__((unused))) -{ - // XXX: scsi.mod does not use write yet. - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "AHCI write not implemented"); -} - -static grub_err_t -grub_ahci_open (int devnum, struct grub_scsi *scsi) +grub_ahci_open (int id, int devnum, struct grub_ata *ata) { struct grub_ahci_device *dev; + if (id != GRUB_SCSI_SUBSYSTEM_AHCI) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an AHCI device"); + FOR_LIST_ELEMENTS(dev, grub_ahci_devices) { if (dev->num == devnum) break; } - grub_dprintf ("ata", "opening AHCI dev `ahci%d'\n", devnum); - if (! dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such AHCI device"); - scsi->data = dev; + grub_dprintf ("ahci", "opening AHCI dev `ahci%d'\n", dev->num); + + ata->data = dev; return GRUB_ERR_NONE; } - -static struct grub_scsi_dev grub_ahci_dev = +static struct grub_ata_dev grub_ahci_dev = { - .name = "ahci", - .id = GRUB_SCSI_SUBSYSTEM_AHCI, .iterate = grub_ahci_iterate, .open = grub_ahci_open, - .read = grub_ahci_read, - .write = grub_ahci_write + .readwrite = grub_ahci_readwrite, }; @@ -291,8 +406,8 @@ static struct grub_scsi_dev grub_ahci_dev = GRUB_MOD_INIT(ahci) { /* To prevent two drivers operating on the same disks. */ - grub_disk_firmware_is_tainted = 1; - if (grub_disk_firmware_fini) + // grub_disk_firmware_is_tainted = 1; + if (0 && grub_disk_firmware_fini) { grub_disk_firmware_fini (); grub_disk_firmware_fini = NULL; @@ -302,10 +417,10 @@ GRUB_MOD_INIT(ahci) grub_ahci_initialize (); /* AHCI devices are handled by scsi.mod. */ - grub_scsi_dev_register (&grub_ahci_dev); + grub_ata_dev_register (&grub_ahci_dev); } GRUB_MOD_FINI(ahci) { - grub_scsi_dev_unregister (&grub_ahci_dev); + grub_ata_dev_unregister (&grub_ahci_dev); } diff --git a/disk/ata.c b/disk/ata.c index cfd58a6d5..3d9de23dd 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -21,76 +21,9 @@ #include #include #include -#include -#include #include -#include -/* At the moment, only two IDE ports are supported. */ -static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1, - GRUB_ATA_CH1_PORT1 }; -static const grub_port_t grub_ata_ioaddress2[] = { GRUB_ATA_CH0_PORT2, - GRUB_ATA_CH1_PORT2 }; - -static struct grub_ata_device *grub_ata_devices; - -/* Wait for !BSY. */ -grub_err_t -grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds) -{ - /* ATA requires 400ns (after a write to CMD register) or - 1 PIO cycle (after a DRQ block transfer) before - first check of BSY. */ - grub_millisleep (1); - - int i = 1; - grub_uint8_t sts; - while ((sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS)) - & GRUB_ATA_STATUS_BUSY) - { - if (i >= milliseconds) - { - grub_dprintf ("ata", "timeout: %dms, status=0x%x\n", - milliseconds, sts); - return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout"); - } - - grub_millisleep (1); - i++; - } - - return GRUB_ERR_NONE; -} - -static inline void -grub_ata_wait (void) -{ - grub_millisleep (50); -} - -/* Wait for !BSY, DRQ. */ -grub_err_t -grub_ata_wait_drq (struct grub_ata_device *dev, int rw, - int milliseconds) -{ - if (grub_ata_wait_not_busy (dev, milliseconds)) - return grub_errno; - - /* !DRQ implies error condition. */ - grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); - if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - != GRUB_ATA_STATUS_DRQ) - { - grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n", - sts, grub_ata_regget (dev, GRUB_ATA_REG_ERROR)); - if (! rw) - return grub_error (GRUB_ERR_READ_ERROR, "ATA read error"); - else - return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error"); - } - - return GRUB_ERR_NONE; -} +static grub_ata_dev_t grub_ata_dev_list; /* Byteorder has to be changed before strings can be read. */ static void @@ -105,30 +38,8 @@ grub_ata_strncpy (char *dst, char *src, grub_size_t len) dst[len] = '\0'; } -void -grub_ata_pio_read (struct grub_ata_device *dev, char *buf, grub_size_t size) -{ - grub_uint16_t *buf16 = (grub_uint16_t *) buf; - unsigned int i; - - /* Read in the data, word by word. */ - for (i = 0; i < size / 2; i++) - buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA)); -} - static void -grub_ata_pio_write (struct grub_ata_device *dev, char *buf, grub_size_t size) -{ - grub_uint16_t *buf16 = (grub_uint16_t *) buf; - unsigned int i; - - /* Write the data, word by word. */ - for (i = 0; i < size / 2; i++) - grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA); -} - -static void -grub_ata_dumpinfo (struct grub_ata_device *dev, char *info) +grub_ata_dumpinfo (struct grub_ata *dev, char *info) { char text[41]; @@ -148,31 +59,27 @@ grub_ata_dumpinfo (struct grub_ata_device *dev, char *info) } static grub_err_t -grub_atapi_identify (struct grub_ata_device *dev) +grub_atapi_identify (struct grub_ata *dev) { + struct grub_disk_ata_pass_through_parms parms; char *info; + grub_err_t err; info = grub_malloc (GRUB_DISK_SECTOR_SIZE); if (! info) return grub_errno; - grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); - grub_ata_wait (); - if (grub_ata_check_ready (dev)) - { - grub_free (info); - return grub_errno; - } + grub_memset (&parms, 0, sizeof (parms)); + parms.taskfile.disk = 0; + parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE; - grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE); - grub_ata_wait (); + err = dev->dev->readwrite (dev, &parms); + if (err) + return err; - if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD)) - { - grub_free (info); - return grub_errno; - } - grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); + if (parms.size != GRUB_DISK_SECTOR_SIZE) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "device cannot be identified"); dev->atapi = 1; @@ -184,96 +91,35 @@ grub_atapi_identify (struct grub_ata_device *dev) } static grub_err_t -grub_atapi_wait_drq (struct grub_ata_device *dev, - grub_uint8_t ireason, - int milliseconds) -{ - /* Wait for !BSY, DRQ, ireason */ - if (grub_ata_wait_not_busy (dev, milliseconds)) - return grub_errno; - - grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); - grub_uint8_t irs = grub_ata_regget (dev, GRUB_ATAPI_REG_IREASON); - - /* OK if DRQ is asserted and interrupt reason is as expected. */ - if ((sts & GRUB_ATA_STATUS_DRQ) - && (irs & GRUB_ATAPI_IREASON_MASK) == ireason) - return GRUB_ERR_NONE; - - /* !DRQ implies error condition. */ - grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n", - sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR)); - - if (! (sts & GRUB_ATA_STATUS_DRQ) - && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_ERROR) - { - if (ireason == GRUB_ATAPI_IREASON_CMD_OUT) - return grub_error (GRUB_ERR_READ_ERROR, "ATA PACKET command error"); - else - return grub_error (GRUB_ERR_READ_ERROR, "ATAPI read error"); - } - - return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error"); -} - -static grub_err_t -grub_atapi_packet (struct grub_ata_device *dev, char *packet, - grub_size_t size) -{ - grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); - if (grub_ata_check_ready (dev)) - return grub_errno; - - /* Send ATA PACKET command. */ - grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0); - grub_ata_regset (dev, GRUB_ATAPI_REG_IREASON, 0); - grub_ata_regset (dev, GRUB_ATAPI_REG_CNTHIGH, size >> 8); - grub_ata_regset (dev, GRUB_ATAPI_REG_CNTLOW, size & 0xFF); - - grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET); - - /* Wait for !BSY, DRQ, !I/O, C/D. */ - if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_CMD_OUT, GRUB_ATA_TOUT_STD)) - return grub_errno; - - /* Write the packet. */ - grub_ata_pio_write (dev, packet, 12); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_ata_identify (struct grub_ata_device *dev) +grub_ata_identify (struct grub_ata *dev) { + struct grub_disk_ata_pass_through_parms parms; char *info; grub_uint16_t *info16; + grub_err_t err; info = grub_malloc (GRUB_DISK_SECTOR_SIZE); if (! info) return grub_errno; info16 = (grub_uint16_t *) info; + grub_memset (&parms, 0, sizeof (parms)); + parms.buffer = info; + parms.taskfile.disk = 0; - grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); - grub_ata_wait (); - if (grub_ata_check_ready (dev)) + parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_DEVICE; + + err = dev->dev->readwrite (dev, &parms); + if (err) + return err; + + if (parms.size != GRUB_DISK_SECTOR_SIZE) { + grub_uint8_t sts = parms.taskfile.status; grub_free (info); - return grub_errno; - } - - 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)) - { - grub_free (info); - grub_errno = GRUB_ERR_NONE; - grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); - if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR - && (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04 /* ABRT */)) + && (parms.taskfile.error & 0x04 /* ABRT */)) /* Device without ATA IDENTIFY, try ATAPI. */ return grub_atapi_identify (dev); @@ -287,19 +133,6 @@ grub_ata_identify (struct grub_ata_device *dev) "device cannot be identified"); } - grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); - - /* Re-check status to avoid bogus identify data due to stuck DRQ. */ - grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); - if (sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - { - grub_dprintf ("ata", "bad status=0x%x\n", sts); - grub_free (info); - /* No device, return error but don't print message. */ - grub_errno = GRUB_ERR_NONE; - return GRUB_ERR_UNKNOWN_DEVICE; - } - /* Now it is certain that this is not an ATAPI device. */ dev->atapi = 0; @@ -335,196 +168,12 @@ grub_ata_identify (struct grub_ata_device *dev) } static grub_err_t -check_device (struct grub_ata_device *dev) -{ - grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); - grub_ata_wait (); - - /* Try to detect if the port is in use by writing to it, - waiting for a while and reading it again. If the value - was preserved, there is a device connected. */ - grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); - grub_ata_wait (); - grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); - grub_dprintf ("ata", "sectors=0x%x\n", sec); - if (sec != 0x5A) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected"); - - /* The above test may detect a second (slave) device - connected to a SATA controller which supports only one - (master) device. It is not safe to use the status register - READY bit to check for controller channel existence. Some - ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */ - - /* Use the IDENTIFY DEVICE command to query the device. */ - return grub_ata_identify (dev); -} - -static grub_err_t -grub_ata_device_initialize (int port, int device, int addr, int addr2) -{ - struct grub_ata_device *dev; - struct grub_ata_device **devp; - grub_err_t err; - - grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n", - port, device, addr, addr2); - - dev = grub_malloc (sizeof(*dev)); - if (! dev) - return grub_errno; - - /* Setup the device information. */ - dev->port = port; - dev->device = device; - dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; - dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; - dev->next = NULL; - - /* Register the device. */ - for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next); - *devp = dev; - - err = check_device (dev); - if (err) - grub_print_error (); - - return 0; -} - -static int NESTED_FUNC_ATTR -grub_ata_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid) -{ - static int compat_use[2] = { 0 }; - grub_pci_address_t addr; - grub_uint32_t class; - grub_uint32_t bar1; - grub_uint32_t bar2; - int rega; - int regb; - int i; - static int controller = 0; - int cs5536 = 0; - int nports = 2; - - /* Read class. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - /* AMD CS5536 Southbridge. */ - if (pciid == GRUB_CS5536_PCIID) - { - cs5536 = 1; - nports = 1; - } - - /* Check if this class ID matches that of a PCI IDE Controller. */ - if (!cs5536 && (class >> 16 != 0x0101)) - return 0; - - for (i = 0; i < nports; i++) - { - /* Set to 0 when the channel operated in compatibility mode. */ - int compat; - - /* We don't support non-compatibility mode for CS5536. */ - if (cs5536) - compat = 0; - else - compat = (class >> (8 + 2 * i)) & 1; - - rega = 0; - regb = 0; - - /* If the channel is in compatibility mode, just assign the - default registers. */ - if (compat == 0 && !compat_use[i]) - { - rega = grub_ata_ioaddress[i]; - regb = grub_ata_ioaddress2[i]; - compat_use[i] = 1; - } - else if (compat) - { - /* Read the BARs, which either contain a mmapped IO address - or the IO port address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES - + sizeof (grub_uint64_t) * i); - bar1 = grub_pci_read (addr); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES - + sizeof (grub_uint64_t) * i - + sizeof (grub_uint32_t)); - bar2 = grub_pci_read (addr); - - /* Check if the BARs describe an IO region. */ - if ((bar1 & 1) && (bar2 & 1)) - { - rega = bar1 & ~3; - regb = bar2 & ~3; - } - } - - grub_dprintf ("ata", - "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n", - grub_pci_get_bus (dev), grub_pci_get_device (dev), - grub_pci_get_function (dev), compat, rega, regb); - - if (rega && regb) - { - grub_errno = GRUB_ERR_NONE; - grub_ata_device_initialize (controller * 2 + i, 0, rega, regb); - - /* Most errors raised by grub_ata_device_initialize() are harmless. - They just indicate this particular drive is not responding, most - likely because it doesn't exist. We might want to ignore specific - error types here, instead of printing them. */ - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - - grub_ata_device_initialize (controller * 2 + i, 1, rega, regb); - - /* Likewise. */ - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - } - } - - controller++; - - return 0; -} - -static grub_err_t -grub_ata_initialize (void) -{ - grub_pci_iterate (grub_ata_pciinit); - return 0; -} - -static void -grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector, - grub_size_t size) -{ - grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size); - grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF); - grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF); - grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF); -} - -static grub_err_t -grub_ata_setaddress (struct grub_ata_device *dev, - grub_ata_addressing_t addressing, +grub_ata_setaddress (struct grub_ata *dev, + struct grub_disk_ata_pass_through_parms *parms, grub_disk_addr_t sector, grub_size_t size) { - switch (addressing) + switch (dev->addr) { case GRUB_ATA_CHS: { @@ -544,14 +193,11 @@ grub_ata_setaddress (struct grub_ata_device *dev, return grub_error (GRUB_ERR_OUT_OF_RANGE, "sector %d cannot be addressed " "using CHS addressing", sector); - - grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head); - if (grub_ata_check_ready (dev)) - return grub_errno; - - grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect); - grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF); - grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8); + + parms->taskfile.disk = head; + parms->taskfile.sectnum = sect; + parms->taskfile.cyllsb = cylinder & 0xFF; + parms->taskfile.cylmsb = cylinder >> 8; break; } @@ -559,26 +205,31 @@ grub_ata_setaddress (struct grub_ata_device *dev, case GRUB_ATA_LBA: if (size == 256) size = 0; - grub_ata_regset (dev, GRUB_ATA_REG_DISK, - 0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F)); - if (grub_ata_check_ready (dev)) - return grub_errno; + parms->taskfile.disk = ((sector >> 24) & 0x0F); - grub_ata_setlba (dev, sector, size); + parms->taskfile.sectors = size; + parms->taskfile.lba_low = sector & 0xFF; + parms->taskfile.lba_mid = (sector >> 8) & 0xFF; + parms->taskfile.lba_high = (sector >> 16) & 0xFF; break; case GRUB_ATA_LBA48: if (size == 65536) size = 0; - grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4)); - if (grub_ata_check_ready (dev)) - return grub_errno; + parms->taskfile.disk = 0; /* Set "Previous". */ - grub_ata_setlba (dev, sector >> 24, size >> 8); + parms->taskfile.sectors = size & 0xFF; + parms->taskfile.lba_low = sector & 0xFF; + parms->taskfile.lba_mid = (sector >> 8) & 0xFF; + parms->taskfile.lba_high = (sector >> 16) & 0xFF; + /* Set "Current". */ - grub_ata_setlba (dev, sector, size); + parms->taskfile.sectors48 = (size >> 8) & 0xFF; + parms->taskfile.lba48_low = (sector >> 24) & 0xFF; + parms->taskfile.lba48_mid = (sector >> 32) & 0xFF; + parms->taskfile.lba48_high = (sector >> 40) & 0xFF; break; } @@ -590,14 +241,15 @@ static grub_err_t grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf, int rw) { - struct grub_ata_device *dev = (struct grub_ata_device *) disk->data; + struct grub_ata *ata = disk->data; - grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n", (unsigned long long) size, rw); - - grub_ata_addressing_t addressing = dev->addr; + grub_ata_addressing_t addressing = ata->addr; grub_size_t batch; int cmd, cmd_write; + grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n", + (unsigned long long) size, rw); + if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0) { batch = 65536; @@ -608,7 +260,10 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, { if (addressing == GRUB_ATA_LBA48) addressing = GRUB_ATA_LBA; - batch = 256; + if (addressing != GRUB_ATA_CHS) + batch = 256; + else + batch = 1; cmd = GRUB_ATA_CMD_READ_SECTORS; cmd_write = GRUB_ATA_CMD_WRITE_SECTORS; } @@ -616,44 +271,25 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t nsectors = 0; while (nsectors < size) { + struct grub_disk_ata_pass_through_parms parms; + grub_err_t err; + if (size - nsectors < batch) batch = size - nsectors; grub_dprintf("ata", "rw=%d, sector=%llu, batch=%llu\n", rw, (unsigned long long) sector, (unsigned long long) batch); - - /* Send read/write command. */ - if (grub_ata_setaddress (dev, addressing, sector, batch)) - return grub_errno; - - grub_ata_regset (dev, GRUB_ATA_REG_CMD, (! rw ? cmd : cmd_write)); - - unsigned sect; - for (sect = 0; sect < batch; sect++) - { - /* Wait for !BSY, DRQ. */ - if (grub_ata_wait_drq (dev, rw, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - /* Transfer data. */ - if (! rw) - grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE); - else - grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE); - - buf += GRUB_DISK_SECTOR_SIZE; - } - - if (rw) - { - /* Check for write error. */ - if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) - & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error"); - } - + grub_memset (&parms, 0, sizeof (parms)); + grub_ata_setaddress (ata, &parms, sector, batch); + parms.taskfile.cmd = (! rw ? cmd : cmd_write); + parms.buffer = buf; + parms.size = batch * GRUB_DISK_SECTOR_SIZE; + + err = ata->dev->readwrite (ata, &parms); + if (err) + return err; + if (parms.size != batch * GRUB_DISK_SECTOR_SIZE) + return grub_error (GRUB_ERR_READ_ERROR, "incomplete read"); + buf += GRUB_DISK_SECTOR_SIZE * batch; sector += batch; nsectors += batch; } @@ -663,76 +299,118 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, -static int -grub_ata_iterate (int (*hook) (const char *name)) +static inline void +grub_ata_real_close (struct grub_ata *ata) { - struct grub_ata_device *dev; + if (ata->dev->close) + ata->dev->close (ata); +} - for (dev = grub_ata_devices; dev; dev = dev->next) +static struct grub_ata * +grub_ata_real_open (int id, int bus) +{ + struct grub_ata *ata; + grub_ata_dev_t p; + + ata = grub_malloc (sizeof (*ata)); + if (!ata) + return NULL; + for (p = grub_ata_dev_list; p; p = p->next) { - char devname[10]; grub_err_t err; - - err = check_device (dev); - if (err) + if (p->open (id, bus, ata)) { grub_errno = GRUB_ERR_NONE; continue; } - - if (dev->atapi) - continue; - - grub_snprintf (devname, sizeof (devname), - "ata%d", dev->port * 2 + dev->device); - - if (hook (devname)) - return 1; + ata->dev = p; + /* Use the IDENTIFY DEVICE command to query the device. */ + err = grub_ata_identify (ata); + if (err) + { + grub_free (ata); + return NULL; + } + return ata; } + grub_free (ata); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATA device"); + return NULL; +} +static int +grub_ata_iterate (int (*hook_in) (const char *name)) +{ + auto int hook (int id, int bus); + int hook (int id, int bus) + { + struct grub_ata *ata; + int ret; + char devname[40]; + + ata = grub_ata_real_open (id, bus); + + if (!ata) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (ata->atapi) + { + grub_ata_real_close (ata); + return 0; + } + grub_snprintf (devname, sizeof (devname), + "%s%d", grub_scsi_names[id], bus); + ret = hook_in (devname); + grub_ata_real_close (ata); + return ret; + } + + grub_ata_dev_t p; + + for (p = grub_ata_dev_list; p; p = p->next) + if (p->iterate && p->iterate (hook)) + return 1; return 0; } static grub_err_t grub_ata_open (const char *name, grub_disk_t disk) { - struct grub_ata_device *dev; - grub_err_t err; + unsigned id, bus; + struct grub_ata *ata; - for (dev = grub_ata_devices; dev; dev = dev->next) - { - char devname[10]; - grub_snprintf (devname, sizeof (devname), - "ata%d", dev->port * 2 + dev->device); - if (grub_strcmp (name, devname) == 0) - break; - } + for (id = 0; id < GRUB_SCSI_NUM_SUBSYSTEMS; id++) + if (grub_strncmp (grub_scsi_names[id], name, + grub_strlen (grub_scsi_names[id])) == 0 + && grub_isdigit (name[grub_strlen (grub_scsi_names[id])])) + break; + if (id == GRUB_SCSI_NUM_SUBSYSTEMS) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); + bus = grub_strtoul (name + grub_strlen (grub_scsi_names[id]), 0, 0); + ata = grub_ata_real_open (id, bus); + if (!ata) + return grub_errno; - if (! dev) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - - if (dev->atapi) + if (ata->atapi) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); - err = check_device (dev); + disk->total_sectors = ata->size; - if (err) - return err; - - disk->total_sectors = dev->size; - - disk->id = (unsigned long) dev; + disk->id = grub_make_scsi_id (id, bus, 0); disk->has_partitions = 1; - disk->data = dev; + disk->data = ata; return 0; } static void -grub_ata_close (grub_disk_t disk __attribute__((unused))) +grub_ata_close (grub_disk_t disk) { - + struct grub_ata *ata = disk->data; + grub_ata_real_close (ata); } static grub_err_t @@ -767,70 +445,35 @@ static struct grub_disk_dev grub_atadisk_dev = /* ATAPI code. */ -static int -grub_atapi_iterate (int (*hook) (int bus, int luns)) -{ - struct grub_ata_device *dev; - - for (dev = grub_ata_devices; dev; dev = dev->next) - { - grub_err_t err; - - err = check_device (dev); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - if (! dev->atapi) - continue; - - if (hook (dev->port * 2 + dev->device, 1)) - return 1; - } - - return 0; - -} - static grub_err_t -grub_atapi_read (struct grub_scsi *scsi, - grub_size_t cmdsize __attribute__((unused)), - char *cmd, grub_size_t size, char *buf) +grub_atapi_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + grub_size_t size, char *buf) { - struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data; + struct grub_ata *dev = scsi->data; + struct grub_disk_ata_pass_through_parms parms; + grub_err_t err; grub_dprintf("ata", "grub_atapi_read (size=%llu)\n", (unsigned long long) size); + grub_memset (&parms, 0, sizeof (parms)); - if (grub_atapi_packet (dev, cmd, size)) - return grub_errno; + parms.taskfile.disk = 0; + parms.taskfile.features = 0; + parms.taskfile.atapi_ireason = 0; + parms.taskfile.atapi_cnthigh = size >> 8; + parms.taskfile.atapi_cntlow = size & 0xff; + parms.taskfile.cmd = GRUB_ATA_CMD_PACKET; + parms.cmd = cmd; + parms.cmdsize = cmdsize; - grub_size_t nread = 0; - while (nread < size) - { - /* Wait for !BSY, DRQ, I/O, !C/D. */ - if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - /* Get byte count for this DRQ assertion. */ - unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 - | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW); - grub_dprintf("ata", "DRQ count=%u\n", cnt); - - /* Count of last transfer may be uneven. */ - if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread))) - return grub_error (GRUB_ERR_READ_ERROR, "invalid ATAPI transfer count"); - - /* Read the data. */ - grub_ata_pio_read (dev, buf + nread, cnt); - - if (cnt & 1) - buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA)); - - nread += cnt; - } + parms.size = size; + parms.buffer = buf; + + err = dev->dev->readwrite (dev, &parms); + if (err) + return err; + if (parms.size != size) + return grub_error (GRUB_ERR_READ_ERROR, "incomplete ATAPI read"); return GRUB_ERR_NONE; } @@ -846,64 +489,98 @@ grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)), } static grub_err_t -grub_atapi_open (int devnum, struct grub_scsi *scsi) +grub_atapi_open (int id, int bus, struct grub_scsi *scsi) { - struct grub_ata_device *dev; - struct grub_ata_device *devfnd = 0; - grub_err_t err; + struct grub_ata *ata; - for (dev = grub_ata_devices; dev; dev = dev->next) - { - if (dev->port * 2 + dev->device == devnum) - { - devfnd = dev; - break; - } - } - - grub_dprintf ("ata", "opening ATAPI dev `ata%d'\n", devnum); - - if (! devfnd) + ata = grub_ata_real_open (id, bus); + if (!ata) + return grub_errno; + + if (! ata->atapi) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); - err = check_device (devfnd); - if (err) - return err; - - if (! devfnd->atapi) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); - - scsi->data = devfnd; + scsi->data = ata; return GRUB_ERR_NONE; } +static int +grub_atapi_iterate (int (*hook_in) (int id, int bus, int luns)) +{ + auto int hook (int id, int bus); + int hook (int id, int bus) + { + struct grub_ata *ata; + int ret; + + ata = grub_ata_real_open (id, bus); + + if (!ata) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + if (!ata->atapi) + { + grub_ata_real_close (ata); + return 0; + } + ret = hook_in (id, bus, 1); + grub_ata_real_close (ata); + return ret; + } + + grub_ata_dev_t p; + + for (p = grub_ata_dev_list; p; p = p->next) + if (p->iterate && p->iterate (hook)) + return 1; + return 0; +} + +static void +grub_atapi_close (grub_scsi_t disk) +{ + struct grub_ata *ata = disk->data; + grub_ata_real_close (ata); +} + + +void +grub_ata_dev_register (grub_ata_dev_t dev) +{ + dev->next = grub_ata_dev_list; + grub_ata_dev_list = dev; +} + +void +grub_ata_dev_unregister (grub_ata_dev_t dev) +{ + grub_ata_dev_t *p, q; + + for (p = &grub_ata_dev_list, q = *p; q; p = &(q->next), q = q->next) + if (q == dev) + { + *p = q->next; + break; + } +} static struct grub_scsi_dev grub_atapi_dev = { - .name = "ata", - .id = GRUB_SCSI_SUBSYSTEM_ATAPI, .iterate = grub_atapi_iterate, .open = grub_atapi_open, + .close = grub_atapi_close, .read = grub_atapi_read, - .write = grub_atapi_write + .write = grub_atapi_write, + .next = 0 }; GRUB_MOD_INIT(ata) { - /* To prevent two drivers operating on the same disks. */ - grub_disk_firmware_is_tainted = 1; - if (grub_disk_firmware_fini) - { - grub_disk_firmware_fini (); - grub_disk_firmware_fini = NULL; - } - - /* ATA initialization. */ - grub_ata_initialize (); - grub_disk_dev_register (&grub_atadisk_dev); /* ATAPI devices are handled by scsi.mod. */ diff --git a/disk/ata_pthru.c b/disk/ata_pthru.c index f52725a49..b6edf78d6 100644 --- a/disk/ata_pthru.c +++ b/disk/ata_pthru.c @@ -18,90 +18,496 @@ */ #include +#include #include #include #include +#include +#include +#include +/* At the moment, only two IDE ports are supported. */ +static const grub_port_t grub_pata_ioaddress[] = { GRUB_ATA_CH0_PORT1, + GRUB_ATA_CH1_PORT1 }; +static const grub_port_t grub_pata_ioaddress2[] = { GRUB_ATA_CH0_PORT2, + GRUB_ATA_CH1_PORT2 }; -/* ATA pass through support, used by hdparm.mod. */ -static grub_err_t -grub_ata_pass_through (grub_disk_t disk, - struct grub_disk_ata_pass_through_parms *parms) +struct grub_pata_device { - if (disk->dev->id != GRUB_DISK_DEVICE_ATA_ID) - return grub_error (GRUB_ERR_BAD_DEVICE, - "device not accessed via ata.mod"); + /* IDE port to use. */ + int port; - struct grub_ata_device *dev = (struct grub_ata_device *) disk->data; + /* IO addresses on which the registers for this device can be + found. */ + grub_port_t ioaddress; + grub_port_t ioaddress2; - if (! (parms->size == 0 || parms->size == GRUB_DISK_SECTOR_SIZE)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "ATA multi-sector read and DATA OUT not implemented"); + /* Two devices can be connected to a single cable. Use this field + to select device 0 (commonly known as "master") or device 1 + (commonly known as "slave"). */ + int device; - grub_dprintf ("ata", "ata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n", - parms->taskfile[GRUB_ATA_REG_CMD], - parms->taskfile[GRUB_ATA_REG_FEATURES], - parms->taskfile[GRUB_ATA_REG_SECTORS]); - grub_dprintf ("ata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n", - parms->taskfile[GRUB_ATA_REG_LBAHIGH], - parms->taskfile[GRUB_ATA_REG_LBAMID], - parms->taskfile[GRUB_ATA_REG_LBALOW], parms->size); + struct grub_pata_device *next; +}; - /* Set registers. */ - grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4 - | (parms->taskfile[GRUB_ATA_REG_DISK] & 0xf)); - if (grub_ata_check_ready (dev)) - return grub_errno; +static struct grub_pata_device *grub_pata_devices; - int i; - for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++) - grub_ata_regset (dev, i, parms->taskfile[i]); +static inline void +grub_pata_regset (struct grub_pata_device *dev, int reg, int val) +{ + grub_outb (val, dev->ioaddress + reg); +} - /* Start command. */ - grub_ata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile[GRUB_ATA_REG_CMD]); +static inline grub_uint8_t +grub_pata_regget (struct grub_pata_device *dev, int reg) +{ + return grub_inb (dev->ioaddress + reg); +} - /* Wait for !BSY. */ - if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; +static inline void +grub_pata_regset2 (struct grub_pata_device *dev, int reg, int val) +{ + grub_outb (val, dev->ioaddress2 + reg); +} - /* Check status. */ - grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); - grub_dprintf ("ata", "status=0x%x\n", sts); +static inline grub_uint8_t +grub_pata_regget2 (struct grub_pata_device *dev, int reg) +{ + return grub_inb (dev->ioaddress2 + reg); +} - /* Transfer data. */ - if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_DRQ) +/* Wait for !BSY. */ +static grub_err_t +grub_pata_wait_not_busy (struct grub_pata_device *dev, int milliseconds) +{ + /* ATA requires 400ns (after a write to CMD register) or + 1 PIO cycle (after a DRQ block transfer) before + first check of BSY. */ + grub_millisleep (1); + + int i = 1; + grub_uint8_t sts; + while ((sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS)) + & GRUB_ATA_STATUS_BUSY) { - if (parms->size != GRUB_DISK_SECTOR_SIZE) - return grub_error (GRUB_ERR_READ_ERROR, "DRQ unexpected"); - grub_ata_pio_read (dev, parms->buffer, GRUB_DISK_SECTOR_SIZE); + if (i >= milliseconds) + { + grub_dprintf ("pata", "timeout: %dms, status=0x%x\n", + milliseconds, sts); + return grub_error (GRUB_ERR_TIMEOUT, "PATA timeout"); + } + + grub_millisleep (1); + i++; } - /* Return registers. */ - for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++) - parms->taskfile[i] = grub_ata_regget (dev, i); - - grub_dprintf ("ata", "status=0x%x, error=0x%x, sectors=0x%x\n", - parms->taskfile[GRUB_ATA_REG_STATUS], - parms->taskfile[GRUB_ATA_REG_ERROR], - parms->taskfile[GRUB_ATA_REG_SECTORS]); - - if (parms->taskfile[GRUB_ATA_REG_STATUS] - & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - return grub_error (GRUB_ERR_READ_ERROR, "ATA passthrough failed"); - return GRUB_ERR_NONE; } +static inline grub_err_t +grub_pata_check_ready (struct grub_pata_device *dev) +{ + if (grub_pata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) + return grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_STD); + + return GRUB_ERR_NONE; +} + +static inline void +grub_pata_wait (void) +{ + grub_millisleep (50); +} + +static void +grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size) +{ + grub_uint16_t *buf16 = (grub_uint16_t *) buf; + unsigned int i; + + /* Read in the data, word by word. */ + for (i = 0; i < size / 2; i++) + buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA)); + if (size & 1) + buf[size - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + + GRUB_ATA_REG_DATA)); +} + +static void +grub_pata_pio_write (struct grub_pata_device *dev, char *buf, grub_size_t size) +{ + grub_uint16_t *buf16 = (grub_uint16_t *) buf; + unsigned int i; + + /* Write the data, word by word. */ + for (i = 0; i < size / 2; i++) + grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA); +} + +/* ATA pass through support, used by hdparm.mod. */ +static grub_err_t +grub_pata_readwrite (struct grub_ata *disk, + struct grub_disk_ata_pass_through_parms *parms) +{ + struct grub_pata_device *dev = (struct grub_pata_device *) disk->data; + grub_size_t nread = 0; + + if (! (parms->cmdsize == 0 || parms->cmdsize == 12)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ATAPI non-12 byte commands not supported"); + + grub_dprintf ("pata", "pata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n", + parms->taskfile.cmd, + parms->taskfile.features, + parms->taskfile.sectors); + grub_dprintf ("pata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n", + parms->taskfile.lba_high, + parms->taskfile.lba_mid, + parms->taskfile.lba_low, parms->size); + + /* Set registers. */ + grub_pata_regset (dev, GRUB_ATA_REG_DISK, (parms->cmdsize ? 0 : 0xE0) + | dev->device << 4 + | (parms->taskfile.disk & 0xf)); + if (grub_pata_check_ready (dev)) + return grub_errno; + + int i; + for (i = GRUB_ATA_REG_SECTORS; i <= GRUB_ATA_REG_LBAHIGH; i++) + grub_pata_regset (dev, i, + parms->taskfile.raw[7 + (i - GRUB_ATA_REG_SECTORS)]); + for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++) + grub_pata_regset (dev, i, parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES]); + + /* Start command. */ + grub_pata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile.cmd); + + /* Wait for !BSY. */ + if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + /* Check status. */ + grub_int8_t sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS); + grub_dprintf ("pata", "status=0x%x\n", sts); + + if (parms->cmdsize) + { + grub_uint8_t irs = grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON); + /* OK if DRQ is asserted and interrupt reason is as expected. */ + if (!((sts & GRUB_ATA_STATUS_DRQ) + && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_CMD_OUT)) + return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error"); + /* Write the packet. */ + grub_pata_pio_write (dev, parms->cmd, parms->cmdsize); + } + + /* Transfer data. */ + while (nread < parms->size + && ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + == GRUB_ATA_STATUS_DRQ) + && (!parms->cmdsize + || ((grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON) + & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_DATA_IN))) + { + unsigned cnt; + if (parms->cmdsize) + { + cnt = grub_pata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 + | grub_pata_regget (dev, GRUB_ATAPI_REG_CNTLOW); + grub_dprintf("pata", "DRQ count=%u\n", cnt); + + /* Count of last transfer may be uneven. */ + if (! (0 < cnt && cnt <= parms->size - nread + && (! (cnt & 1) || cnt == parms->size - nread))) + return grub_error (GRUB_ERR_READ_ERROR, + "invalid ATAPI transfer count"); + } + else + cnt = GRUB_DISK_SECTOR_SIZE; + if (cnt > parms->size - nread) + cnt = parms->size - nread; + + if (parms->write) + grub_pata_pio_write (dev, (char *) parms->buffer + nread, cnt); + else + grub_pata_pio_read (dev, (char *) parms->buffer + nread, cnt); + + nread += cnt; + } + if (parms->write) + { + /* Check for write error. */ + if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + if (grub_pata_regget (dev, GRUB_ATA_REG_STATUS) + & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error"); + } + parms->size = nread; + + /* Return registers. */ + for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++) + parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES] = grub_pata_regget (dev, i); + + grub_dprintf ("pata", "status=0x%x, error=0x%x, sectors=0x%x\n", + parms->taskfile.status, + parms->taskfile.error, + parms->taskfile.sectors); + + if (parms->taskfile.status + & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + return grub_error (GRUB_ERR_READ_ERROR, "PATA passthrough failed"); + + return GRUB_ERR_NONE; +} + +static grub_err_t +check_device (struct grub_pata_device *dev) +{ + grub_pata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); + grub_pata_wait (); + + /* Try to detect if the port is in use by writing to it, + waiting for a while and reading it again. If the value + was preserved, there is a device connected. */ + grub_pata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); + grub_pata_wait (); + grub_uint8_t sec = grub_pata_regget (dev, GRUB_ATA_REG_SECTORS); + grub_dprintf ("ata", "sectors=0x%x\n", sec); + if (sec != 0x5A) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected"); + + /* The above test may detect a second (slave) device + connected to a SATA controller which supports only one + (master) device. It is not safe to use the status register + READY bit to check for controller channel existence. Some + ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */ + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_pata_device_initialize (int port, int device, int addr, int addr2) +{ + struct grub_pata_device *dev; + struct grub_pata_device **devp; + grub_err_t err; + + grub_dprintf ("pata", "detecting device %d,%d (0x%x, 0x%x)\n", + port, device, addr, addr2); + + dev = grub_malloc (sizeof(*dev)); + if (! dev) + return grub_errno; + + /* Setup the device information. */ + dev->port = port; + dev->device = device; + dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; + dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; + dev->next = NULL; + + /* Register the device. */ + for (devp = &grub_pata_devices; *devp; devp = &(*devp)->next); + *devp = dev; + + err = check_device (dev); + if (err) + grub_print_error (); + + return 0; +} + +static int NESTED_FUNC_ATTR +grub_pata_pciinit (grub_pci_device_t dev, + grub_pci_id_t pciid) +{ + static int compat_use[2] = { 0 }; + grub_pci_address_t addr; + grub_uint32_t class; + grub_uint32_t bar1; + grub_uint32_t bar2; + int rega; + int regb; + int i; + static int controller = 0; + int cs5536 = 0; + int nports = 2; + + /* Read class. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + + /* AMD CS5536 Southbridge. */ + if (pciid == GRUB_CS5536_PCIID) + { + cs5536 = 1; + nports = 1; + } + + /* Check if this class ID matches that of a PCI IDE Controller. */ + if (!cs5536 && (class >> 16 != 0x0101)) + return 0; + + for (i = 0; i < nports; i++) + { + /* Set to 0 when the channel operated in compatibility mode. */ + int compat; + + /* We don't support non-compatibility mode for CS5536. */ + if (cs5536) + compat = 0; + else + compat = (class >> (8 + 2 * i)) & 1; + + rega = 0; + regb = 0; + + /* If the channel is in compatibility mode, just assign the + default registers. */ + if (compat == 0 && !compat_use[i]) + { + rega = grub_pata_ioaddress[i]; + regb = grub_pata_ioaddress2[i]; + compat_use[i] = 1; + } + else if (compat) + { + /* Read the BARs, which either contain a mmapped IO address + or the IO port address. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i); + bar1 = grub_pci_read (addr); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i + + sizeof (grub_uint32_t)); + bar2 = grub_pci_read (addr); + + /* Check if the BARs describe an IO region. */ + if ((bar1 & 1) && (bar2 & 1)) + { + rega = bar1 & ~3; + regb = bar2 & ~3; + } + } + + grub_dprintf ("pata", + "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n", + grub_pci_get_bus (dev), grub_pci_get_device (dev), + grub_pci_get_function (dev), compat, rega, regb); + + if (rega && regb) + { + grub_errno = GRUB_ERR_NONE; + grub_pata_device_initialize (controller * 2 + i, 0, rega, regb); + + /* Most errors raised by grub_ata_device_initialize() are harmless. + They just indicate this particular drive is not responding, most + likely because it doesn't exist. We might want to ignore specific + error types here, instead of printing them. */ + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + + grub_pata_device_initialize (controller * 2 + i, 1, rega, regb); + + /* Likewise. */ + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + } + } + + controller++; + + return 0; +} + +static grub_err_t +grub_pata_initialize (void) +{ + grub_pci_iterate (grub_pata_pciinit); + return 0; +} + +static grub_err_t +grub_pata_open (int id, int devnum, struct grub_ata *ata) +{ + struct grub_pata_device *dev; + struct grub_pata_device *devfnd = 0; + grub_err_t err; + + if (id != GRUB_SCSI_SUBSYSTEM_PATA) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a PATA device"); + + for (dev = grub_pata_devices; dev; dev = dev->next) + { + if (dev->port * 2 + dev->device == devnum) + { + devfnd = dev; + break; + } + } + + grub_dprintf ("pata", "opening PATA dev `ata%d'\n", devnum); + + if (! devfnd) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such PATA device"); + + err = check_device (devfnd); + if (err) + return err; + + ata->data = devfnd; + + return GRUB_ERR_NONE; +} + +static int +grub_pata_iterate (int (*hook) (int id, int bus)) +{ + struct grub_pata_device *dev; + + for (dev = grub_pata_devices; dev; dev = dev->next) + if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device)) + return 1; + + return 0; +} + + +static struct grub_ata_dev grub_pata_dev = + { + .iterate = grub_pata_iterate, + .open = grub_pata_open, + .readwrite = grub_pata_readwrite, + }; + + GRUB_MOD_INIT(ata_pthru) { - /* Register ATA pass through function. */ - grub_disk_ata_pass_through = grub_ata_pass_through; + /* To prevent two drivers operating on the same disks. */ + grub_disk_firmware_is_tainted = 1; + if (grub_disk_firmware_fini) + { + grub_disk_firmware_fini (); + grub_disk_firmware_fini = NULL; + } + + /* ATA initialization. */ + grub_pata_initialize (); + + grub_ata_dev_register (&grub_pata_dev); } GRUB_MOD_FINI(ata_pthru) { - if (grub_disk_ata_pass_through == grub_ata_pass_through) - grub_disk_ata_pass_through = NULL; + grub_ata_dev_unregister (&grub_pata_dev); } diff --git a/disk/scsi.c b/disk/scsi.c index 60192bef5..f0594e7c7 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -30,6 +30,12 @@ static grub_scsi_dev_t grub_scsi_dev_list; +char grub_scsi_names[GRUB_SCSI_NUM_SUBSYSTEMS][5] = { + [GRUB_SCSI_SUBSYSTEM_USBMS] = "usb", + [GRUB_SCSI_SUBSYSTEM_PATA] = "ata", + [GRUB_SCSI_SUBSYSTEM_AHCI] = "ahci" +}; + void grub_scsi_dev_register (grub_scsi_dev_t dev) { @@ -318,9 +324,9 @@ grub_scsi_iterate (int (*hook) (const char *name)) { grub_scsi_dev_t p; - auto int scsi_iterate (int bus, int luns); + auto int scsi_iterate (int id, int bus, int luns); - int scsi_iterate (int bus, int luns) + int scsi_iterate (int id, int bus, int luns) { int i; @@ -329,7 +335,7 @@ grub_scsi_iterate (int (*hook) (const char *name)) { char *sname; int ret; - sname = grub_xasprintf ("%s%d", p->name, bus); + sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus); if (!sname) return 1; ret = hook (sname); @@ -343,7 +349,7 @@ grub_scsi_iterate (int (*hook) (const char *name)) { char *sname; int ret; - sname = grub_xasprintf ("%s%d%c", p->name, bus, 'a' + i); + sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i); if (!sname) return 1; ret = hook (sname); @@ -370,6 +376,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) int lun, bus; grub_uint64_t maxtime; const char *nameend; + unsigned id; nameend = name + grub_strlen (name) - 1; /* Try to detect a LUN ('a'-'z'), otherwise just use the first @@ -394,15 +401,25 @@ grub_scsi_open (const char *name, grub_disk_t disk) if (! scsi) return grub_errno; + for (id = 0; id < ARRAY_SIZE (grub_scsi_names); id++) + if (grub_strncmp (grub_scsi_names[id], name, nameend - name) == 0) + break; + + if (id == ARRAY_SIZE (grub_scsi_names)) + { + grub_free (scsi); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk"); + } + for (p = grub_scsi_dev_list; p; p = p->next) { - if (grub_strncmp (p->name, name, nameend - name) != 0) - continue; + if (p->open (id, bus, scsi)) + { + grub_errno = GRUB_ERR_NONE; + continue; + } - if (p->open (bus, scsi)) - continue; - - disk->id = grub_make_scsi_id (p->id, bus, lun); + disk->id = grub_make_scsi_id (id, bus, lun); disk->data = scsi; scsi->dev = p; scsi->lun = lun; @@ -484,7 +501,6 @@ grub_scsi_open (const char *name, grub_disk_t disk) } grub_free (scsi); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk"); } diff --git a/disk/usbms.c b/disk/usbms.c index 225761e0f..0ff2e6235 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -205,7 +205,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) static int -grub_usbms_iterate (int (*hook) (int bus, int luns)) +grub_usbms_iterate (int (*hook) (int id, int bus, int luns)) { unsigned i; @@ -214,7 +214,7 @@ grub_usbms_iterate (int (*hook) (int bus, int luns)) for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) if (grub_usbms_devices[i]) { - if (hook (i, grub_usbms_devices[i]->luns)) + if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns)) return 1; } @@ -384,8 +384,12 @@ grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, } static grub_err_t -grub_usbms_open (int devnum, struct grub_scsi *scsi) +grub_usbms_open (int id, int devnum, struct grub_scsi *scsi) { + if (id != GRUB_SCSI_SUBSYSTEM_USBMS) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "not USB Mass Storage device"); + grub_usb_poll_devices (); if (!grub_usbms_devices[devnum]) @@ -400,8 +404,6 @@ grub_usbms_open (int devnum, struct grub_scsi *scsi) static struct grub_scsi_dev grub_usbms_dev = { - .name = "usb", - .id = GRUB_SCSI_SUBSYSTEM_USBMS, .iterate = grub_usbms_iterate, .open = grub_usbms_open, .read = grub_usbms_read, diff --git a/include/grub/ata.h b/include/grub/ata.h index 9e3aaf0e6..b1c6ead26 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -97,21 +97,64 @@ enum grub_ata_timeout_milliseconds GRUB_ATA_TOUT_DATA = 10000 /* 10s DATA I/O timeout. */ }; -struct grub_ata_device +typedef union { - /* IDE port to use. */ - int port; + grub_uint8_t raw[11]; + struct + { + union + { + grub_uint8_t features; + grub_uint8_t error; + }; + union + { + grub_uint8_t sectors; + grub_uint8_t atapi_ireason; + }; + union + { + grub_uint8_t lba_low; + grub_uint8_t sectnum; + }; + union + { + grub_uint8_t lba_mid; + grub_uint8_t cyllsb; + grub_uint8_t atapi_cntlow; + }; + union + { + grub_uint8_t lba_high; + grub_uint8_t cylmsb; + grub_uint8_t atapi_cnthigh; + }; + grub_uint8_t disk; + union + { + grub_uint8_t cmd; + grub_uint8_t status; + }; + grub_uint8_t sectors48; + grub_uint8_t lba48_low; + grub_uint8_t lba48_mid; + grub_uint8_t lba48_high; + }; +} grub_ata_regs_t; - /* IO addresses on which the registers for this device can be - found. */ - grub_port_t ioaddress; - grub_port_t ioaddress2; - - /* Two devices can be connected to a single cable. Use this field - to select device 0 (commonly known as "master") or device 1 - (commonly known as "slave"). */ - int device; +/* ATA pass through parameters and function. */ +struct grub_disk_ata_pass_through_parms +{ + grub_ata_regs_t taskfile; + void * buffer; + grub_size_t size; + int write; + void *cmd; + int cmdsize; +}; +struct grub_ata +{ /* Addressing methods available for accessing this device. If CHS is only available, use that. Otherwise use LBA, except for the high sectors. In that case use LBA48. */ @@ -128,47 +171,36 @@ struct grub_ata_device /* Set to 0 for ATA, set to 1 for ATAPI. */ int atapi; - struct grub_ata_device *next; + void *data; + + struct grub_ata_dev *dev; }; -grub_err_t EXPORT_FUNC(grub_ata_wait_not_busy) (struct grub_ata_device *dev, - int milliseconds); -grub_err_t EXPORT_FUNC(grub_ata_wait_drq) (struct grub_ata_device *dev, - int rw, int milliseconds); -void EXPORT_FUNC(grub_ata_pio_read) (struct grub_ata_device *dev, - char *buf, grub_size_t size); +typedef struct grub_ata *grub_ata_t; -static inline void -grub_ata_regset (struct grub_ata_device *dev, int reg, int val) +struct grub_ata_dev { - grub_outb (val, dev->ioaddress + reg); -} + /* Call HOOK with each device name, until HOOK returns non-zero. */ + int (*iterate) (int (*hook) (int id, int bus)); -static inline grub_uint8_t -grub_ata_regget (struct grub_ata_device *dev, int reg) -{ - return grub_inb (dev->ioaddress + reg); -} + /* Open the device named NAME, and set up SCSI. */ + grub_err_t (*open) (int id, int bus, struct grub_ata *scsi); -static inline void -grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val) -{ - grub_outb (val, dev->ioaddress2 + reg); -} + /* Close the scsi device SCSI. */ + void (*close) (struct grub_ata *ata); -static inline grub_uint8_t -grub_ata_regget2 (struct grub_ata_device *dev, int reg) -{ - return grub_inb (dev->ioaddress2 + reg); -} + /* Read SIZE bytes from the device SCSI into BUF after sending the + command CMD of size CMDSIZE. */ + grub_err_t (*readwrite) (struct grub_ata *ata, + struct grub_disk_ata_pass_through_parms *parms); -static inline grub_err_t -grub_ata_check_ready (struct grub_ata_device *dev) -{ - if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) - return grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_STD); + /* The next scsi device. */ + struct grub_ata_dev *next; +}; - return GRUB_ERR_NONE; -} +typedef struct grub_ata_dev *grub_ata_dev_t; + +void grub_ata_dev_register (grub_ata_dev_t dev); +void grub_ata_dev_unregister (grub_ata_dev_t dev); #endif /* ! GRUB_ATA_HEADER */ diff --git a/include/grub/disk.h b/include/grub/disk.h index e7f807e0e..ac3fb6497 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -165,16 +165,5 @@ grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk); extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void); extern int EXPORT_VAR(grub_disk_firmware_is_tainted); - -/* ATA pass through parameters and function. */ -struct grub_disk_ata_pass_through_parms -{ - grub_uint8_t taskfile[8]; - void * buffer; - int size; -}; - -extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t, - struct grub_disk_ata_pass_through_parms *); - + #endif /* ! GRUB_DISK_HEADER */ diff --git a/include/grub/scsi.h b/include/grub/scsi.h index 289cd8e4a..081189fb0 100644 --- a/include/grub/scsi.h +++ b/include/grub/scsi.h @@ -29,10 +29,13 @@ struct grub_scsi; enum { GRUB_SCSI_SUBSYSTEM_USBMS, - GRUB_SCSI_SUBSYSTEM_ATAPI, - GRUB_SCSI_SUBSYSTEM_AHCI + GRUB_SCSI_SUBSYSTEM_PATA, + GRUB_SCSI_SUBSYSTEM_AHCI, + GRUB_SCSI_NUM_SUBSYSTEMS }; +extern char grub_scsi_names[GRUB_SCSI_NUM_SUBSYSTEMS][5]; + #define GRUB_SCSI_ID_SUBSYSTEM_SHIFT 24 #define GRUB_SCSI_ID_BUS_SHIFT 8 #define GRUB_SCSI_ID_LUN_SHIFT 0 @@ -46,16 +49,11 @@ grub_make_scsi_id (int subsystem, int bus, int lun) struct grub_scsi_dev { - /* The device name. */ - const char *name; - - grub_uint8_t id; - /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (int (*hook) (int bus, int luns)); + int (*iterate) (int (*hook) (int id, int bus, int luns)); /* Open the device named NAME, and set up SCSI. */ - grub_err_t (*open) (int bus, struct grub_scsi *scsi); + grub_err_t (*open) (int id, int bus, struct grub_scsi *scsi); /* Close the scsi device SCSI. */ void (*close) (struct grub_scsi *scsi); diff --git a/kern/disk.c b/kern/disk.c index ccd5f200f..84c48e65c 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -46,10 +46,6 @@ static struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM]; void (*grub_disk_firmware_fini) (void); int grub_disk_firmware_is_tainted; -grub_err_t (* grub_disk_ata_pass_through) (grub_disk_t, - struct grub_disk_ata_pass_through_parms *); - - #if 0 static unsigned long grub_disk_cache_hits; static unsigned long grub_disk_cache_misses; From faec81d97dd6b3cb58b631f4fcf426786f1db54f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Dec 2010 16:54:33 +0100 Subject: [PATCH 0545/1414] Add missing buffer specifications --- grub-core/disk/ata.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 04b81cd27..9f62546e1 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -72,6 +72,8 @@ grub_atapi_identify (struct grub_ata *dev) grub_memset (&parms, 0, sizeof (parms)); parms.taskfile.disk = 0; parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE; + parms.size = GRUB_DISK_SECTOR_SIZE; + parms.buffer = info; err = dev->dev->readwrite (dev, &parms); if (err) @@ -105,6 +107,7 @@ grub_ata_identify (struct grub_ata *dev) info16 = (grub_uint16_t *) info; grub_memset (&parms, 0, sizeof (parms)); parms.buffer = info; + parms.size = GRUB_DISK_SECTOR_SIZE; parms.taskfile.disk = 0; parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_DEVICE; From 22a7cc9a6f5e61de79b34f09c97a71a12dd370a2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Dec 2010 17:09:56 +0100 Subject: [PATCH 0546/1414] fix 3rd argument to scsi_iterate --- grub-core/disk/ata.c | 2 +- grub-core/disk/scsi.c | 4 ++-- grub-core/disk/usbms.c | 2 +- include/grub/scsi.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 9f62546e1..6f7f44227 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -508,7 +508,7 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi) } static int -grub_atapi_iterate (int (*hook_in) (int id, int bus, int luns)) +grub_atapi_iterate (int NESTED_FUNC_ATTR (*hook_in) (int id, int bus, int luns)) { auto int hook (int id, int bus); int hook (int id, int bus) diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index b989a98ad..015e5dce6 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -324,9 +324,9 @@ grub_scsi_iterate (int (*hook) (const char *name)) { grub_scsi_dev_t p; - auto int scsi_iterate (int id, int bus, int luns); + auto int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns); - int scsi_iterate (int id, int bus, int luns) + int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns) { int i; diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c index 4e1af7be3..8041c6c95 100644 --- a/grub-core/disk/usbms.c +++ b/grub-core/disk/usbms.c @@ -205,7 +205,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) static int -grub_usbms_iterate (int (*hook) (int id, int bus, int luns)) +grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns)) { unsigned i; diff --git a/include/grub/scsi.h b/include/grub/scsi.h index 3deb18f1b..5b6ccc9f4 100644 --- a/include/grub/scsi.h +++ b/include/grub/scsi.h @@ -50,7 +50,7 @@ grub_make_scsi_id (int subsystem, int bus, int lun) struct grub_scsi_dev { /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (int (*hook) (int id, int bus, int luns)); + int (*iterate) (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns)); /* Open the device named NAME, and set up SCSI. */ grub_err_t (*open) (int id, int bus, struct grub_scsi *scsi); From 8f5ac9e57050652378a9d54d9082ab331a775946 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Dec 2010 17:10:41 +0100 Subject: [PATCH 0547/1414] fix ATAPI support --- grub-core/disk/ata.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 6f7f44227..5015f8507 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -113,13 +113,12 @@ grub_ata_identify (struct grub_ata *dev) parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_DEVICE; err = dev->dev->readwrite (dev, &parms); - if (err) - return err; - if (parms.size != GRUB_DISK_SECTOR_SIZE) + if (err || parms.size != GRUB_DISK_SECTOR_SIZE) { grub_uint8_t sts = parms.taskfile.status; grub_free (info); + grub_errno = GRUB_ERR_NONE; if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR && (parms.taskfile.error & 0x04 /* ABRT */)) @@ -503,6 +502,7 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); scsi->data = ata; + scsi->luns = 1; return GRUB_ERR_NONE; } From ee2b985ef68f5522796057ef6d3055ad7d6dc5a1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Dec 2010 17:11:21 +0100 Subject: [PATCH 0548/1414] rearrange wait_not_busy --- grub-core/disk/pata.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index b6edf78d6..a24237a83 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -182,17 +182,18 @@ grub_pata_readwrite (struct grub_ata *disk, /* Start command. */ grub_pata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile.cmd); - /* Wait for !BSY. */ - if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - /* Check status. */ grub_int8_t sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS); grub_dprintf ("pata", "status=0x%x\n", sts); if (parms->cmdsize) { - grub_uint8_t irs = grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON); + grub_uint8_t irs; + /* Wait for !BSY. */ + if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + irs = grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON); /* OK if DRQ is asserted and interrupt reason is as expected. */ if (!((sts & GRUB_ATA_STATUS_DRQ) && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_CMD_OUT)) @@ -210,6 +211,11 @@ grub_pata_readwrite (struct grub_ata *disk, & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_DATA_IN))) { unsigned cnt; + + /* Wait for !BSY. */ + if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + if (parms->cmdsize) { cnt = grub_pata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 @@ -246,6 +252,10 @@ grub_pata_readwrite (struct grub_ata *disk, } parms->size = nread; + /* Wait for !BSY. */ + if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + /* Return registers. */ for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++) parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES] = grub_pata_regget (dev, i); From 908a8fc37a51aea0dd22d53494772456a210b900 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Dec 2010 19:48:55 +0100 Subject: [PATCH 0549/1414] Fix several AHCI problems --- grub-core/disk/ahci.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 946db82e1..1e28b3dc5 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -56,10 +56,12 @@ struct grub_ahci_hba_port grub_uint32_t intstatus; grub_uint32_t inten; grub_uint32_t command; - grub_uint32_t unused1[6]; + grub_uint32_t unused1[3]; + grub_uint32_t status; + grub_uint32_t unused2[2]; grub_uint32_t sata_active; grub_uint32_t command_issue; - grub_uint32_t unused2[17]; + grub_uint32_t unused3[17]; }; struct grub_ahci_hba @@ -195,6 +197,10 @@ grub_ahci_pciinit (grub_pci_device_t dev, if (!(hba->ports_implemented & (1 << i))) continue; + /* FIXME: support hotplugging. */ + if (!hba->ports[i].status) + continue; + command_list = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head)); if (!command_list) @@ -333,8 +339,11 @@ grub_ahci_readwrite (grub_ata_t disk, parms->cmdsize); dev->command_table[0].cfis[0] = GRUB_AHCI_FIS_REG_H2D; + dev->command_table[0].cfis[1] = 0x80; for (i = 0; i < sizeof (parms->taskfile.raw); i++) - dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i]; + dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i]; + + dev->command_table[0].cfis[7] |= (parms->cmdsize ? 0 : 0xE0); dev->command_table[0].prdt[0].data_base = grub_dma_get_phys (bufc); dev->command_table[0].prdt[0].unused = 0; @@ -345,12 +354,12 @@ grub_ahci_readwrite (grub_ata_t disk, grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size); grub_dprintf ("ahci", "AHCI command schedulded\n"); - dev->hba->ports[dev->port].inten = (1 << 5); - dev->hba->ports[dev->port].intstatus = (1 << 5); + dev->hba->ports[dev->port].inten = (1 << 2) | (1 << 5); + dev->hba->ports[dev->port].intstatus = (1 << 2) | (1 << 5); dev->hba->ports[dev->port].command_issue |= 1; dev->hba->ports[dev->port].command |= 1; - endtime = grub_get_time_ms () + 1000; + endtime = grub_get_time_ms () + 1000; while (!(dev->hba->ports[dev->port].intstatus & (1 << 5))) if (grub_get_time_ms () > endtime) { @@ -362,6 +371,7 @@ grub_ahci_readwrite (grub_ata_t disk, grub_dprintf ("ahci", "AHCI command completed succesfully\n"); dev->hba->ports[dev->port].command &= ~1; + dev->hba->ports[dev->port].command_issue &= ~1; if (!parms->write) grub_memcpy (parms->buffer, (char *) grub_dma_get_virt (bufc), parms->size); @@ -379,10 +389,8 @@ grub_ahci_open (int id, int devnum, struct grub_ata *ata) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an AHCI device"); FOR_LIST_ELEMENTS(dev, grub_ahci_devices) - { - if (dev->num == devnum) - break; - } + if (dev->num == devnum) + break; if (! dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such AHCI device"); From 51f7e1acb7355d15d83ff3f916cc80cc1827b96b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 02:53:20 +0100 Subject: [PATCH 0550/1414] DMA ATA commands support --- grub-core/disk/ahci.c | 1 + grub-core/disk/ata.c | 28 +++++++++++++++++++++++----- grub-core/disk/pata.c | 1 + include/grub/ata.h | 8 ++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 1e28b3dc5..4b5d195f2 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -398,6 +398,7 @@ grub_ahci_open (int id, int devnum, struct grub_ata *ata) grub_dprintf ("ahci", "opening AHCI dev `ahci%d'\n", dev->num); ata->data = dev; + ata->dma = 0; return GRUB_ERR_NONE; } diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 5015f8507..b33abf90d 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -255,8 +255,16 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0) { batch = 65536; - cmd = GRUB_ATA_CMD_READ_SECTORS_EXT; - cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT; + if (ata->dma) + { + cmd = GRUB_ATA_CMD_READ_SECTORS_DMA_EXT; + cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_DMA_EXT; + } + else + { + cmd = GRUB_ATA_CMD_READ_SECTORS_EXT; + cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT; + } } else { @@ -266,9 +274,17 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, batch = 256; else batch = 1; - cmd = GRUB_ATA_CMD_READ_SECTORS; - cmd_write = GRUB_ATA_CMD_WRITE_SECTORS; - } + if (ata->dma) + { + cmd = GRUB_ATA_CMD_READ_SECTORS_DMA; + cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_DMA; + } + else + { + cmd = GRUB_ATA_CMD_READ_SECTORS; + cmd_write = GRUB_ATA_CMD_WRITE_SECTORS; + } + } grub_size_t nsectors = 0; while (nsectors < size) @@ -285,6 +301,8 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, parms.taskfile.cmd = (! rw ? cmd : cmd_write); parms.buffer = buf; parms.size = batch * GRUB_DISK_SECTOR_SIZE; + if (ata->dma) + parms.dma = 1; err = ata->dev->readwrite (ata, &parms); if (err) diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index a24237a83..186caf6a2 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -474,6 +474,7 @@ grub_pata_open (int id, int devnum, struct grub_ata *ata) return err; ata->data = devfnd; + ata->dma = 0; return GRUB_ERR_NONE; } diff --git a/include/grub/ata.h b/include/grub/ata.h index b1c6ead26..bea74c180 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -82,6 +82,9 @@ enum grub_ata_commands GRUB_ATA_CMD_PACKET = 0xa0, GRUB_ATA_CMD_READ_SECTORS = 0x20, GRUB_ATA_CMD_READ_SECTORS_EXT = 0x24, + GRUB_ATA_CMD_READ_SECTORS_DMA = 0xc8, + GRUB_ATA_CMD_READ_SECTORS_DMA_EXT = 0x25, + GRUB_ATA_CMD_SECURITY_FREEZE_LOCK = 0xf5, GRUB_ATA_CMD_SET_FEATURES = 0xef, GRUB_ATA_CMD_SLEEP = 0xe6, @@ -89,6 +92,8 @@ enum grub_ata_commands GRUB_ATA_CMD_STANDBY_IMMEDIATE = 0xe0, GRUB_ATA_CMD_WRITE_SECTORS = 0x30, GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34, + GRUB_ATA_CMD_WRITE_SECTORS_DMA_EXT = 0x35, + GRUB_ATA_CMD_WRITE_SECTORS_DMA = 0xca, }; enum grub_ata_timeout_milliseconds @@ -151,6 +156,7 @@ struct grub_disk_ata_pass_through_parms int write; void *cmd; int cmdsize; + int dma; }; struct grub_ata @@ -171,6 +177,8 @@ struct grub_ata /* Set to 0 for ATA, set to 1 for ATAPI. */ int atapi; + int dma; + void *data; struct grub_ata_dev *dev; From 060d0c7ac2fbf763cc07efcb498c04c03b4cf197 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 03:06:07 +0100 Subject: [PATCH 0551/1414] working AHCI (at last) --- grub-core/disk/ahci.c | 182 +++++++++++++++++++++++++++++++++++------- 1 file changed, 152 insertions(+), 30 deletions(-) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 4b5d195f2..4d5ee692c 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -44,8 +44,8 @@ struct grub_ahci_prdt_entry struct grub_ahci_cmd_table { grub_uint8_t cfis[0x40]; - grub_uint8_t command[16]; - grub_uint32_t reserved[0xc]; + grub_uint8_t command[0x10]; + grub_uint8_t reserved[0x30]; struct grub_ahci_prdt_entry prdt[1]; }; @@ -56,14 +56,27 @@ struct grub_ahci_hba_port grub_uint32_t intstatus; grub_uint32_t inten; grub_uint32_t command; - grub_uint32_t unused1[3]; + grub_uint32_t unused1; + grub_uint32_t task_file_data; + grub_uint32_t sig; grub_uint32_t status; - grub_uint32_t unused2[2]; + grub_uint32_t unused2; + grub_uint32_t sata_error; grub_uint32_t sata_active; grub_uint32_t command_issue; - grub_uint32_t unused3[17]; + grub_uint32_t unused3; + grub_uint32_t fbs; + grub_uint32_t unused4[15]; }; +enum grub_ahci_hba_port_command + { + GRUB_AHCI_HBA_PORT_CMD_ST = 0x01, + GRUB_AHCI_HBA_PORT_CMD_FRE = 0x10, + GRUB_AHCI_HBA_PORT_CMD_CR = 0x8000, + GRUB_AHCI_HBA_PORT_CMD_FR = 0x4000, + }; + struct grub_ahci_hba { grub_uint32_t cap; @@ -76,6 +89,11 @@ struct grub_ahci_hba struct grub_ahci_hba_port ports[32]; }; +struct grub_ahci_received_fis +{ + char raw[4096]; +}; + enum { GRUB_AHCI_HBA_CAP_NPORTS_MASK = 0x1f @@ -83,6 +101,7 @@ enum enum { + GRUB_AHCI_HBA_GLOBAL_CONTROL_RESET = 0x00000001, GRUB_AHCI_HBA_GLOBAL_CONTROL_INTR_EN = 0x00000002, GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN = 0x80000000, }; @@ -106,8 +125,14 @@ struct grub_ahci_device volatile struct grub_ahci_cmd_head *command_list; struct grub_pci_dma_chunk *command_table_chunk; volatile struct grub_ahci_cmd_table *command_table; + struct grub_pci_dma_chunk *rfis; }; +static grub_err_t +grub_ahci_readwrite_real (struct grub_ahci_device *dev, + struct grub_disk_ata_pass_through_parms *parms); + + enum { GRUB_AHCI_CONFIG_READ = 0, @@ -160,10 +185,6 @@ grub_ahci_pciinit (grub_pci_device_t dev, hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK, sizeof (hba)); - hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; - - nports = (hba->cap & GRUB_AHCI_HBA_CAP_NPORTS_MASK) + 1; - if (! (hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_OS_OWNED)) { grub_uint64_t endtime; @@ -186,6 +207,11 @@ grub_ahci_pciinit (grub_pci_device_t dev, } else grub_dprintf ("ahci", "AHCI is already in OS mode\n"); + + hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; + + nports = (hba->cap & GRUB_AHCI_HBA_CAP_NPORTS_MASK) + 1; + grub_dprintf ("ahci", "%d AHCI ports\n", nports); for (i = 0; i < nports; i++) @@ -197,8 +223,9 @@ grub_ahci_pciinit (grub_pci_device_t dev, if (!(hba->ports_implemented & (1 << i))) continue; + grub_dprintf ("ahci", "status %d:%x\n", i, hba->ports[i].status); /* FIXME: support hotplugging. */ - if (!hba->ports[i].status) + if ((hba->ports[i].status & 0xf) != 0x3) continue; command_list = grub_memalign_dma32 (1024, @@ -224,6 +251,26 @@ grub_ahci_pciinit (grub_pci_device_t dev, grub_dprintf ("ahci", "found device ahci%d (port %d)\n", numdevs, i); + hba->ports[i].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; + while ((hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_FR)); + hba->ports[i].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; + while ((hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + + hba->ports[i].fbs = 2; + + adev->rfis = grub_memalign_dma32 (4096, + sizeof (struct grub_ahci_received_fis)); + grub_memset ((char *) grub_dma_get_virt (adev->rfis), 0, + sizeof (struct grub_ahci_received_fis)); + hba->ports[i].fis_base = grub_dma_get_phys (adev->rfis); + hba->ports[i].command |= GRUB_AHCI_HBA_PORT_CMD_FRE; + while (!(hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_FR)); + hba->ports[i].command |= GRUB_AHCI_HBA_PORT_CMD_ST; + while (!(hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + + hba->ports[i].command = (hba->ports[i].command & 0x0fffffff) + | (1 << 28) | 2 | 4; + adev->hba = hba; adev->port = i; adev->num = numdevs++; @@ -299,13 +346,26 @@ static const int register_map[11] = { 3 /* Features */, 10 /* LBA48 high */ }; static grub_err_t -grub_ahci_readwrite (grub_ata_t disk, - struct grub_disk_ata_pass_through_parms *parms) +grub_ahci_readwrite_real (struct grub_ahci_device *dev, + struct grub_disk_ata_pass_through_parms *parms) { - struct grub_ahci_device *dev = (struct grub_ahci_device *) disk->data; struct grub_pci_dma_chunk *bufc; grub_uint64_t endtime; unsigned i; + grub_err_t err = GRUB_ERR_NONE; + + grub_dprintf ("ahci", "AHCI tfd = %x\n", + dev->hba->ports[dev->port].task_file_data); + + if ((dev->hba->ports[dev->port].task_file_data & 0x80)) + { + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_ST; + while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + } + + dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error; grub_dprintf("ahci", "grub_ahci_read (size=%llu, cmdsize = %llu)\n", (unsigned long long) parms->size, @@ -319,14 +379,19 @@ grub_ahci_readwrite (grub_ata_t disk, bufc = grub_memalign_dma32 (1024, parms->size + (parms->size & 1)); + dev->hba->ports[dev->port].command |= 8; + + grub_dprintf ("ahci", "AHCI tfd = %x\n", + dev->hba->ports[dev->port].task_file_data); /* FIXME: support port multipliers. */ dev->command_list[0].config - = (4 << GRUB_AHCI_CONFIG_CFIS_LENGTH_SHIFT) - | GRUB_AHCI_CONFIG_CLEAR_R_OK + = (5 << GRUB_AHCI_CONFIG_CFIS_LENGTH_SHIFT) + // | GRUB_AHCI_CONFIG_CLEAR_R_OK | (0 << GRUB_AHCI_CONFIG_PMP_SHIFT) | (1 << GRUB_AHCI_CONFIG_PRDT_LENGTH_SHIFT) | (parms->cmdsize ? GRUB_AHCI_CONFIG_ATAPI : 0) - | (parms->write ? GRUB_AHCI_CONFIG_WRITE : GRUB_AHCI_CONFIG_READ); + | (parms->write ? GRUB_AHCI_CONFIG_WRITE : GRUB_AHCI_CONFIG_READ) + | (parms->taskfile.cmd == 8 ? (1 << 8) : 0); dev->command_list[0].transfered = 0; dev->command_list[0].command_table_base = grub_dma_get_phys (dev->command_table_chunk); @@ -344,40 +409,97 @@ grub_ahci_readwrite (grub_ata_t disk, dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i]; dev->command_table[0].cfis[7] |= (parms->cmdsize ? 0 : 0xE0); + grub_dprintf ("ahci", "cfis: %02x %02x %02x %02x %02x %02x %02x %02x\n", + dev->command_table[0].cfis[0], dev->command_table[0].cfis[1], + dev->command_table[0].cfis[2], dev->command_table[0].cfis[3], + dev->command_table[0].cfis[4], dev->command_table[0].cfis[5], + dev->command_table[0].cfis[6], dev->command_table[0].cfis[7]); + grub_dprintf ("ahci", "cfis: %02x %02x %02x %02x %02x %02x %02x %02x\n", + dev->command_table[0].cfis[8], dev->command_table[0].cfis[9], + dev->command_table[0].cfis[10], dev->command_table[0].cfis[11], + dev->command_table[0].cfis[12], dev->command_table[0].cfis[13], + dev->command_table[0].cfis[14], dev->command_table[0].cfis[15]); dev->command_table[0].prdt[0].data_base = grub_dma_get_phys (bufc); dev->command_table[0].prdt[0].unused = 0; dev->command_table[0].prdt[0].size = (parms->size + (parms->size & 1) - 1) | GRUB_AHCI_INTERRUPT_ON_COMPLETE; + grub_dprintf ("ahci", "PRDT = %" PRIxGRUB_UINT64_T ", %x, %x (%x)\n", + dev->command_table[0].prdt[0].data_base, + dev->command_table[0].prdt[0].unused, + dev->command_table[0].prdt[0].size, + (char *) &dev->command_table[0].prdt[0] + - (char *) &dev->command_table[0]); + if (parms->write) grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size); grub_dprintf ("ahci", "AHCI command schedulded\n"); - dev->hba->ports[dev->port].inten = (1 << 2) | (1 << 5); - dev->hba->ports[dev->port].intstatus = (1 << 2) | (1 << 5); + grub_dprintf ("ahci", "AHCI tfd = %x\n", + dev->hba->ports[dev->port].task_file_data); + dev->hba->ports[dev->port].inten = 0xffffffff;//(1 << 2) | (1 << 5); + dev->hba->ports[dev->port].intstatus = 0xffffffff;//(1 << 2) | (1 << 5); + grub_dprintf ("ahci", "AHCI tfd = %x\n", + dev->hba->ports[dev->port].task_file_data); dev->hba->ports[dev->port].command_issue |= 1; - dev->hba->ports[dev->port].command |= 1; + grub_dprintf ("ahci", "AHCI sig = %x\n", dev->hba->ports[dev->port].sig); + grub_dprintf ("ahci", "AHCI tfd = %x\n", + dev->hba->ports[dev->port].task_file_data); endtime = grub_get_time_ms () + 1000; - while (!(dev->hba->ports[dev->port].intstatus & (1 << 5))) + while ((dev->hba->ports[dev->port].command_issue & 1)) if (grub_get_time_ms () > endtime) { - grub_dprintf ("ahci", "AHCI timeout\n"); - dev->hba->ports[dev->port].command &= ~1; - /* FIXME: free resources. */ - return grub_error (GRUB_ERR_IO, "AHCI transfer timeouted"); + grub_dprintf ("ahci", "AHCI status <%x %x %x>\n", + dev->hba->ports[dev->port].command_issue, + dev->hba->ports[dev->port].intstatus, + dev->hba->ports[dev->port].task_file_data); + err = grub_error (GRUB_ERR_IO, "AHCI transfer timeouted"); + break; } - grub_dprintf ("ahci", "AHCI command completed succesfully\n"); - dev->hba->ports[dev->port].command &= ~1; - dev->hba->ports[dev->port].command_issue &= ~1; + grub_dprintf ("ahci", "AHCI command completed <%x %x %x %x %x, %x %x>\n", + dev->hba->ports[dev->port].command_issue, + dev->hba->ports[dev->port].intstatus, + dev->hba->ports[dev->port].task_file_data, + dev->command_list[0].transfered, + dev->hba->ports[dev->port].sata_error, + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x00], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x18]); + grub_dprintf ("ahci", + "last PIO FIS %08x %08x %08x %08x %08x %08x %08x %08x\n", + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x08], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x09], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0a], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0b], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0c], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0d], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0e], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0f]); + grub_dprintf ("ahci", + "last REG FIS %08x %08x %08x %08x %08x %08x %08x %08x\n", + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x10], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x11], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x12], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x13], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x14], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x15], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x16], + ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x17]); if (!parms->write) grub_memcpy (parms->buffer, (char *) grub_dma_get_virt (bufc), parms->size); grub_dma_free (bufc); - return GRUB_ERR_NONE; + return err; +} + +static grub_err_t +grub_ahci_readwrite (grub_ata_t disk, + struct grub_disk_ata_pass_through_parms *parms) +{ + return grub_ahci_readwrite_real (disk->data, parms); } static grub_err_t @@ -415,8 +537,8 @@ static struct grub_ata_dev grub_ahci_dev = GRUB_MOD_INIT(ahci) { /* To prevent two drivers operating on the same disks. */ - // grub_disk_firmware_is_tainted = 1; - if (0 && grub_disk_firmware_fini) + grub_disk_firmware_is_tainted = 1; + if (grub_disk_firmware_fini) { grub_disk_firmware_fini (); grub_disk_firmware_fini = NULL; From 188ac234bd37cd6c0fbf649d1f09cb1a0f114f5e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 03:12:49 +0100 Subject: [PATCH 0552/1414] use DMA for AHCI commands --- grub-core/disk/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 4d5ee692c..d9b95df37 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -520,7 +520,7 @@ grub_ahci_open (int id, int devnum, struct grub_ata *ata) grub_dprintf ("ahci", "opening AHCI dev `ahci%d'\n", dev->num); ata->data = dev; - ata->dma = 0; + ata->dma = 1; return GRUB_ERR_NONE; } From a934071d76d66b4b1a36ec73240249363392351f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 03:22:12 +0100 Subject: [PATCH 0553/1414] Remove unused pata ioaddress2 --- grub-core/disk/pata.c | 36 ++++++++---------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index 186caf6a2..940a9a5f0 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -29,8 +29,6 @@ /* At the moment, only two IDE ports are supported. */ static const grub_port_t grub_pata_ioaddress[] = { GRUB_ATA_CH0_PORT1, GRUB_ATA_CH1_PORT1 }; -static const grub_port_t grub_pata_ioaddress2[] = { GRUB_ATA_CH0_PORT2, - GRUB_ATA_CH1_PORT2 }; struct grub_pata_device { @@ -40,7 +38,6 @@ struct grub_pata_device /* IO addresses on which the registers for this device can be found. */ grub_port_t ioaddress; - grub_port_t ioaddress2; /* Two devices can be connected to a single cable. Use this field to select device 0 (commonly known as "master") or device 1 @@ -64,18 +61,6 @@ grub_pata_regget (struct grub_pata_device *dev, int reg) return grub_inb (dev->ioaddress + reg); } -static inline void -grub_pata_regset2 (struct grub_pata_device *dev, int reg, int val) -{ - grub_outb (val, dev->ioaddress2 + reg); -} - -static inline grub_uint8_t -grub_pata_regget2 (struct grub_pata_device *dev, int reg) -{ - return grub_inb (dev->ioaddress2 + reg); -} - /* Wait for !BSY. */ static grub_err_t grub_pata_wait_not_busy (struct grub_pata_device *dev, int milliseconds) @@ -298,14 +283,14 @@ check_device (struct grub_pata_device *dev) } static grub_err_t -grub_pata_device_initialize (int port, int device, int addr, int addr2) +grub_pata_device_initialize (int port, int device, int addr) { struct grub_pata_device *dev; struct grub_pata_device **devp; grub_err_t err; - grub_dprintf ("pata", "detecting device %d,%d (0x%x, 0x%x)\n", - port, device, addr, addr2); + grub_dprintf ("pata", "detecting device %d,%d (0x%x)\n", + port, device, addr); dev = grub_malloc (sizeof(*dev)); if (! dev) @@ -315,7 +300,6 @@ grub_pata_device_initialize (int port, int device, int addr, int addr2) dev->port = port; dev->device = device; dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; - dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; dev->next = NULL; /* Register the device. */ @@ -339,7 +323,6 @@ grub_pata_pciinit (grub_pci_device_t dev, grub_uint32_t bar1; grub_uint32_t bar2; int rega; - int regb; int i; static int controller = 0; int cs5536 = 0; @@ -372,14 +355,12 @@ grub_pata_pciinit (grub_pci_device_t dev, compat = (class >> (8 + 2 * i)) & 1; rega = 0; - regb = 0; /* If the channel is in compatibility mode, just assign the default registers. */ if (compat == 0 && !compat_use[i]) { rega = grub_pata_ioaddress[i]; - regb = grub_pata_ioaddress2[i]; compat_use[i] = 1; } else if (compat) @@ -398,19 +379,18 @@ grub_pata_pciinit (grub_pci_device_t dev, if ((bar1 & 1) && (bar2 & 1)) { rega = bar1 & ~3; - regb = bar2 & ~3; } } grub_dprintf ("pata", - "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n", + "PCI dev (%d,%d,%d) compat=%d rega=0x%x\n", grub_pci_get_bus (dev), grub_pci_get_device (dev), - grub_pci_get_function (dev), compat, rega, regb); + grub_pci_get_function (dev), compat, rega); - if (rega && regb) + if (rega) { grub_errno = GRUB_ERR_NONE; - grub_pata_device_initialize (controller * 2 + i, 0, rega, regb); + grub_pata_device_initialize (controller * 2 + i, 0, rega); /* Most errors raised by grub_ata_device_initialize() are harmless. They just indicate this particular drive is not responding, most @@ -422,7 +402,7 @@ grub_pata_pciinit (grub_pci_device_t dev, grub_errno = GRUB_ERR_NONE; } - grub_pata_device_initialize (controller * 2 + i, 1, rega, regb); + grub_pata_device_initialize (controller * 2 + i, 1, rega); /* Likewise. */ if (grub_errno) From d9675dbee3525def248571a7937e69fdec7afab0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 03:47:51 +0100 Subject: [PATCH 0554/1414] Move 0xE0 to callers rather than to have it in drivers --- grub-core/commands/hdparm.c | 4 ++++ grub-core/disk/ahci.c | 1 - grub-core/disk/ata.c | 10 +++++----- grub-core/disk/pata.c | 5 ++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c index 0154ece57..800bfa06d 100644 --- a/grub-core/commands/hdparm.c +++ b/grub-core/commands/hdparm.c @@ -72,6 +72,8 @@ grub_hdparm_do_ata_cmd (grub_ata_t ata, grub_uint8_t cmd, apt.taskfile.cmd = cmd; apt.taskfile.features = features; apt.taskfile.sectors = sectors; + apt.taskfile.disk = 0xE0; + apt.buffer = buffer; apt.size = size; @@ -88,6 +90,7 @@ grub_hdparm_do_check_powermode_cmd (grub_ata_t ata) grub_memset (&apt, 0, sizeof (apt)); apt.taskfile.cmd = GRUB_ATA_CMD_CHECK_POWER_MODE; + apt.taskfile.disk = 0xE0; if (ata->dev->readwrite (ata, &apt)) return -1; @@ -105,6 +108,7 @@ grub_hdparm_do_smart_cmd (grub_ata_t ata, grub_uint8_t features) apt.taskfile.features = features; apt.taskfile.lba_mid = 0x4f; apt.taskfile.lba_high = 0xc2; + apt.taskfile.disk = 0xE0; if (ata->dev->readwrite (ata, &apt)) return -1; diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index d9b95df37..3160523ce 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -408,7 +408,6 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, for (i = 0; i < sizeof (parms->taskfile.raw); i++) dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i]; - dev->command_table[0].cfis[7] |= (parms->cmdsize ? 0 : 0xE0); grub_dprintf ("ahci", "cfis: %02x %02x %02x %02x %02x %02x %02x %02x\n", dev->command_table[0].cfis[0], dev->command_table[0].cfis[1], dev->command_table[0].cfis[2], dev->command_table[0].cfis[3], diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index b33abf90d..494325aa5 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -70,7 +70,7 @@ grub_atapi_identify (struct grub_ata *dev) return grub_errno; grub_memset (&parms, 0, sizeof (parms)); - parms.taskfile.disk = 0; + parms.taskfile.disk = 0xE0; parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE; parms.size = GRUB_DISK_SECTOR_SIZE; parms.buffer = info; @@ -108,7 +108,7 @@ grub_ata_identify (struct grub_ata *dev) grub_memset (&parms, 0, sizeof (parms)); parms.buffer = info; parms.size = GRUB_DISK_SECTOR_SIZE; - parms.taskfile.disk = 0; + parms.taskfile.disk = 0xE0; parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_DEVICE; @@ -196,7 +196,7 @@ grub_ata_setaddress (struct grub_ata *dev, "sector %d cannot be addressed " "using CHS addressing", sector); - parms->taskfile.disk = head; + parms->taskfile.disk = 0xE0 | head; parms->taskfile.sectnum = sect; parms->taskfile.cyllsb = cylinder & 0xFF; parms->taskfile.cylmsb = cylinder >> 8; @@ -207,7 +207,7 @@ grub_ata_setaddress (struct grub_ata *dev, case GRUB_ATA_LBA: if (size == 256) size = 0; - parms->taskfile.disk = ((sector >> 24) & 0x0F); + parms->taskfile.disk = 0xE0 | ((sector >> 24) & 0x0F); parms->taskfile.sectors = size; parms->taskfile.lba_low = sector & 0xFF; @@ -219,7 +219,7 @@ grub_ata_setaddress (struct grub_ata *dev, if (size == 65536) size = 0; - parms->taskfile.disk = 0; + parms->taskfile.disk = 0xE0; /* Set "Previous". */ parms->taskfile.sectors = size & 0xFF; diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index 940a9a5f0..f9111bc5f 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -151,9 +151,8 @@ grub_pata_readwrite (struct grub_ata *disk, parms->taskfile.lba_low, parms->size); /* Set registers. */ - grub_pata_regset (dev, GRUB_ATA_REG_DISK, (parms->cmdsize ? 0 : 0xE0) - | dev->device << 4 - | (parms->taskfile.disk & 0xf)); + grub_pata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) + | (parms->taskfile.disk & 0xef)); if (grub_pata_check_ready (dev)) return grub_errno; From d1e517eb20c2e5e14bdd8eea7168538f9f15a67c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 12:11:54 +0100 Subject: [PATCH 0555/1414] extend --disk-module to AHCI and USB --- grub-core/bus/usb/ohci.c | 8 ++++++-- grub-core/disk/ahci.c | 38 ++++++++++++++++++++++++++++++++++++++ util/grub-install.in | 14 +++++++++++--- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 8adaee6e0..577f35259 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -1422,18 +1422,22 @@ static struct grub_usb_controller_dev usb_controller = .detect_dev = grub_ohci_detect_dev }; +static void *fini_hnd; + GRUB_MOD_INIT(ohci) { COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_td) == 32); COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_ed) == 16); grub_ohci_inithw (); grub_usb_controller_dev_register (&usb_controller); - grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); + fini_hnd = grub_loader_register_preboot_hook (grub_ohci_fini_hw, + grub_ohci_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(ohci) { grub_ohci_fini_hw (0); + grub_loader_unregister_preboot_hook (fini_hnd); grub_usb_controller_dev_unregister (&usb_controller); } diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 3160523ce..61ca7e4d6 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -25,6 +25,7 @@ #include #include #include +#include struct grub_ahci_cmd_head { @@ -296,6 +297,34 @@ grub_ahci_initialize (void) return grub_errno; } +static grub_err_t +grub_ahci_fini_hw (int noreturn __attribute__ ((unused))) +{ + struct grub_ahci_device *dev, *next; + + for (dev = grub_ahci_devices; dev; dev = next) + { + next = dev->next; + dev->hba->ports[dev->num].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; + while ((dev->hba->ports[dev->num].command & GRUB_AHCI_HBA_PORT_CMD_FR)); + dev->hba->ports[dev->num].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; + while ((dev->hba->ports[dev->num].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + grub_dma_free (dev->command_list_chunk); + grub_dma_free (dev->command_table_chunk); + grub_dma_free (dev->rfis); + + grub_free (dev); + } + grub_ahci_devices = NULL; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ahci_restore_hw (void) +{ + return grub_ahci_initialize (); +} + @@ -533,6 +562,8 @@ static struct grub_ata_dev grub_ahci_dev = +static void *fini_hnd; + GRUB_MOD_INIT(ahci) { /* To prevent two drivers operating on the same disks. */ @@ -548,9 +579,16 @@ GRUB_MOD_INIT(ahci) /* AHCI devices are handled by scsi.mod. */ grub_ata_dev_register (&grub_ahci_dev); + + fini_hnd = grub_loader_register_preboot_hook (grub_ahci_fini_hw, + grub_ahci_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(ahci) { + grub_ahci_fini_hw (0); + grub_loader_unregister_preboot_hook (fini_hnd); + grub_ata_dev_unregister (&grub_ahci_dev); } diff --git a/util/grub-install.in b/util/grub-install.in index b9e833360..6259b1c4a 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -77,7 +77,7 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then elif [ "${platform}" = "ieee1275" ] || [ "${platform}" = "efi" ] ; then disk_module= else - disk_module=ata + disk_module=native fi # Usage: usage @@ -114,7 +114,7 @@ Install GRUB on your drive. EOF if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then cat < Date: Sat, 25 Dec 2010 13:44:31 +0100 Subject: [PATCH 0556/1414] avoid throwing data away on pxefs_open. Reported by : Seth Goldberg --- grub-core/net/i386/pc/pxe.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/grub-core/net/i386/pc/pxe.c b/grub-core/net/i386/pc/pxe.c index fd1447b40..c07aa78f9 100644 --- a/grub-core/net/i386/pc/pxe.c +++ b/grub-core/net/i386/pc/pxe.c @@ -117,7 +117,7 @@ grub_pxefs_open (struct grub_file *file, const char *name) struct grub_pxe_data *data; grub_file_t file_int, bufio; - data = grub_malloc (sizeof (*data)); + data = grub_zalloc (sizeof (*data) + grub_strlen (name) + 1); if (!data) return grub_errno; @@ -135,7 +135,10 @@ grub_pxefs_open (struct grub_file *file, const char *name) err = grub_net_resolve_address (file->device->net->name + sizeof ("pxe,") - 1, &addr); if (err) - return err; + { + grub_free (data); + return err; + } } else { @@ -144,7 +147,10 @@ grub_pxefs_open (struct grub_file *file, const char *name) } err = grub_net_route_address (addr, &gateway, &interf); if (err) - return err; + { + grub_free (data); + return err; + } data->server_ip = addr.ipv4; data->gateway_ip = gateway.ipv4; } @@ -160,7 +166,10 @@ grub_pxefs_open (struct grub_file *file, const char *name) grub_strcpy ((char *)&c.c1.filename[0], name); grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry); if (c.c1.status) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + { + grub_free (data); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + } file->size = c.c1.file_size; @@ -168,11 +177,10 @@ grub_pxefs_open (struct grub_file *file, const char *name) c.c2.packet_size = grub_pxe_blksize; grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2, pxe_rm_entry); if (c.c2.status) - return grub_error (GRUB_ERR_BAD_FS, "open fails"); - - data = grub_zalloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1); - if (! data) - return grub_errno; + { + grub_free (data); + return grub_error (GRUB_ERR_BAD_FS, "open fails"); + } data->block_size = c.c2.packet_size; grub_strcpy (data->filename, name); From 0354b8672cfceed56851c9bad14edfe6a33050b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 14:09:36 +0100 Subject: [PATCH 0557/1414] * grub-core/commands/acpihalt.c (grub_acpi_halt): Sleep for 1.5 before writing an error message because of async power management. * grub-core/kern/mips/yeeloong/init.c (grub_halt): Likewise. (grub_reboot): Likewise. --- ChangeLog | 7 +++++++ grub-core/commands/acpihalt.c | 3 +++ grub-core/kern/mips/yeeloong/init.c | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index 79eeae387..452455966 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-25 Vladimir Serbinenko + + * grub-core/commands/acpihalt.c (grub_acpi_halt): Sleep for 1.5 before + writing an error message because of async power management. + * grub-core/kern/mips/yeeloong/init.c (grub_halt): Likewise. + (grub_reboot): Likewise. + 2010-12-23 Jordan Uggla * tests/util/grub-shell.in: Suppress "ACPI shutdown failed" error to diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 2789e2eca..9a4cda521 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -36,6 +36,7 @@ typedef uint8_t grub_uint8_t; #ifndef GRUB_DSDT_TEST #include +#include #include #endif @@ -324,6 +325,8 @@ grub_acpi_halt (void) } } + grub_millisleep (1500); + grub_printf ("ACPI shutdown failed\n"); } #endif diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index cc7c16806..cadb10773 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -223,6 +223,8 @@ grub_halt (void) grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) & ~GRUB_CPU_LOONGSON_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); + grub_millisleep (1500); + grub_printf ("Shutdown failed\n"); grub_refresh (); while (1); @@ -239,6 +241,8 @@ grub_reboot (void) { grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); + grub_millisleep (1500); + grub_printf ("Reboot failed\n"); grub_refresh (); while (1); From 3c51ecb82b7ab1a94a296c530bd5f4ffdb7a2eab Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 15:47:23 +0100 Subject: [PATCH 0558/1414] Fix adressing mode mismatch --- grub-core/disk/ata.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 494325aa5..3fecb98dd 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -173,9 +173,10 @@ static grub_err_t grub_ata_setaddress (struct grub_ata *dev, struct grub_disk_ata_pass_through_parms *parms, grub_disk_addr_t sector, - grub_size_t size) + grub_size_t size, + grub_ata_addressing_t addressing) { - switch (dev->addr) + switch (addressing) { case GRUB_ATA_CHS: { @@ -297,7 +298,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, grub_dprintf("ata", "rw=%d, sector=%llu, batch=%llu\n", rw, (unsigned long long) sector, (unsigned long long) batch); grub_memset (&parms, 0, sizeof (parms)); - grub_ata_setaddress (ata, &parms, sector, batch); + grub_ata_setaddress (ata, &parms, sector, batch, addressing); parms.taskfile.cmd = (! rw ? cmd : cmd_write); parms.buffer = buf; parms.size = batch * GRUB_DISK_SECTOR_SIZE; From c76ae9b4da785c43dba8478768dd346f5c0b4d59 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 17:40:00 +0100 Subject: [PATCH 0559/1414] set parms.write on disk write --- grub-core/disk/ata.c | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 3fecb98dd..c7cde3166 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -302,6 +302,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, parms.taskfile.cmd = (! rw ? cmd : cmd_write); parms.buffer = buf; parms.size = batch * GRUB_DISK_SECTOR_SIZE; + parms.write = rw; if (ata->dma) parms.dma = 1; From 9797178671d1044cf9fc13648152ea2ea5e76e41 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 18:02:43 +0100 Subject: [PATCH 0560/1414] Accept ports in state 1 --- grub-core/disk/ahci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 61ca7e4d6..b348ce3d0 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -220,13 +220,15 @@ grub_ahci_pciinit (grub_pci_device_t dev, struct grub_ahci_device *adev; struct grub_pci_dma_chunk *command_list; struct grub_pci_dma_chunk *command_table; + grub_uint32_t st; if (!(hba->ports_implemented & (1 << i))) continue; grub_dprintf ("ahci", "status %d:%x\n", i, hba->ports[i].status); /* FIXME: support hotplugging. */ - if ((hba->ports[i].status & 0xf) != 0x3) + st = hba->ports[i].status; + if ((st & 0xf) != 0x3 && (st & 0xf) != 0x1) continue; command_list = grub_memalign_dma32 (1024, From c4855fdc79c3291e907a1080accbc1b4c60abd75 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Dec 2010 18:16:01 +0100 Subject: [PATCH 0561/1414] * util/grub.d/30_os-prober.in: Don't emit drivemap directive for Windows Server 2008. Reported by: Devin Giddings. --- ChangeLog | 6 ++++++ util/grub.d/30_os-prober.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 452455966..43c4dbacb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-25 Vladimir Serbinenko + + * util/grub.d/30_os-prober.in: Don't emit drivemap directive for + Windows Server 2008. + Reported by: Devin Giddings. + 2010-12-25 Vladimir Serbinenko * grub-core/commands/acpihalt.c (grub_acpi_halt): Sleep for 1.5 before diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 728ac2378..d9d4b0a96 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -111,7 +111,7 @@ EOF prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/" case ${LONGNAME} in - Windows\ Vista*|Windows\ 7*) + Windows\ Vista*|Windows\ 7*|Windows\ Server\ 2008*) ;; *) cat << EOF From 022d01b8078e3277a534f43eb58484ec2c4a3911 Mon Sep 17 00:00:00 2001 From: Shea Levy <> Date: Sat, 25 Dec 2010 18:21:46 +0100 Subject: [PATCH 0562/1414] * grub-core/genmod.sh.in: Use @OBJCOPY@ rather than objcopy. --- ChangeLog | 4 ++++ grub-core/genmod.sh.in | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43c4dbacb..3a20e6346 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-12-25 Shea Levy + + * grub-core/genmod.sh.in: Use @OBJCOPY@ rather than objcopy. + 2010-12-25 Vladimir Serbinenko * util/grub.d/30_os-prober.in: Don't emit drivemap directive for diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in index 8dfd5d347..b97f3e1c7 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -35,7 +35,7 @@ deps=`grep ^$modname: $moddep | sed s@^.*:@@` rm -f $tmpfile $outfile # stripout .modname and .moddeps sections from input module -objcopy -R .modname -R .moddeps $infile $tmpfile +@OBJCOPY@ -R .modname -R .moddeps $infile $tmpfile # Attach .modname and .moddeps sections t1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 @@ -45,9 +45,9 @@ t2=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 for dep in $deps; do printf "$dep\0" >> $t2; done if test -n "$deps"; then - objcopy --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile + @OBJCOPY@ --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile else - objcopy --add-section .modname=$t1 $tmpfile + @OBJCOPY@ --add-section .modname=$t1 $tmpfile fi rm -f $t1 $t2 From 190a011a8b15506f0403ba77a587fa63fe7c7e2a Mon Sep 17 00:00:00 2001 From: Jeroen Dekkers Date: Sat, 25 Dec 2010 22:32:54 +0100 Subject: [PATCH 0563/1414] * grub-core/disk/raid.c (insert_array): Don't add spurious members. --- ChangeLog | 4 ++++ grub-core/disk/raid.c | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a20e6346..249ec6bc6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-12-25 Jeroen Dekkers + + * grub-core/disk/raid.c (insert_array): Don't add spurious members. + 2010-12-25 Shea Levy * grub-core/genmod.sh.in: Use @OBJCOPY@ rather than objcopy. diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index f1b67a859..edc2b195d 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -522,14 +522,16 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* We found more members of the array than the array actually has according to its superblock. This shouldn't happen normally. */ - grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?", - array->total_devs); + return grub_error (GRUB_ERR_BAD_DEVICE, + "superfluous RAID member (%d found)", + array->total_devs); if (array->members[new_array->index].device != NULL) /* We found multiple devices with the same number. Again, this shouldn't happen. */ - grub_dprintf ("raid", "Found two disks with the number %d?!?", - new_array->number); + return grub_error (GRUB_ERR_BAD_DEVICE, + "found two disks with the number %d", + new_array->number); if (new_array->disk_size < array->disk_size) array->disk_size = new_array->disk_size; From b28fd807eb6e6ec74964715e0bfd3c32b0dbb449 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Dec 2010 00:38:20 +0100 Subject: [PATCH 0564/1414] 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 0565/1414] 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 5c408d0f50396e832b386e6f7678a5b401dbde84 Mon Sep 17 00:00:00 2001 From: Mirko Parthey Date: Sun, 26 Dec 2010 20:49:08 +0100 Subject: [PATCH 0566/1414] * grub-core/boot/i386/pc/boot.S: Fix %es:%bx pointing to nowhere on floppy probe. --- ChangeLog | 5 +++++ grub-core/boot/i386/pc/boot.S | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 249ec6bc6..80f5ef568 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-12-25 Mirko Parthey + + * grub-core/boot/i386/pc/boot.S: Fix %es:%bx pointing to nowhere on + floppy probe. + 2010-12-25 Jeroen Dekkers * grub-core/disk/raid.c (insert_array): Don't add spurious members. diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index 320918566..635599a24 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -459,6 +459,8 @@ fd_probe_error_string: .asciz "Floppy" 1: /* perform read */ movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + movw %bx, %es + xorw %bx, %bx movw $0x201, %ax movb $0, %ch movb $0, %dh From 0b2db94300dca2b7597e3fbf6ade3a1cebd72c19 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Dec 2010 21:15:31 +0100 Subject: [PATCH 0567/1414] Handling of files of unknown size is currently limited. They can't be used e.g. for initrd or modules. Moreover gzip handling of not easily seekable files is buggy. Disable unknown file size for now. May be inefficient but works. * grub-core/io/gzio.c (test_header): Always retrieve the file size. * grub-core/io/xzio.c (grub_xzio_open): Likewise. --- ChangeLog | 10 ++++++++++ grub-core/io/gzio.c | 25 ++++++++++++------------- grub-core/io/xzio.c | 3 ++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 80f5ef568..0c701a342 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-12-26 Vladimir Serbinenko + + Handling of files of unknown size is currently limited. They can't be + used e.g. for initrd or modules. Moreover gzip handling of not + easily seekable files is buggy. Disable unknown file size for now. May + be inefficient but works. + + * grub-core/io/gzio.c (test_header): Always retrieve the file size. + * grub-core/io/xzio.c (grub_xzio_open): Likewise. + 2010-12-25 Mirko Parthey * grub-core/boot/i386/pc/boot.S: Fix %es:%bx pointing to nowhere on diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 43b67c373..f563d7b92 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -212,19 +212,18 @@ test_header (grub_file_t file) gzio->data_offset = grub_file_tell (gzio->file); - grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4); - - if (grub_file_seekable (gzio->file)) - { - if (grub_file_read (gzio->file, &orig_len, 4) != 4) - { - grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format"); - return 0; - } - } - /* FIXME: this does not handle files whose original size is over 4GB. - But how can we know the real original size? */ - file->size = grub_le_to_cpu32 (orig_len); + /* FIXME: don't do this on not easily seekable files. */ + { + grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4); + if (grub_file_read (gzio->file, &orig_len, 4) != 4) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format"); + return 0; + } + /* FIXME: this does not handle files whose original size is over 4GB. + But how can we know the real original size? */ + file->size = grub_le_to_cpu32 (orig_len); + } initialize_tables (file); diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index 1a22bdc70..37be1790f 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -222,7 +222,8 @@ grub_xzio_open (grub_file_t io) xzio->buf.out_pos = 0; xzio->buf.out_size = XZBUFSIZ; - if (!test_header (file) || !(grub_file_seekable (io) && test_footer (file))) + /* FIXME: don't test footer on not easily seekable files. */ + if (!test_header (file) || !test_footer (file)) { grub_errno = GRUB_ERR_NONE; grub_file_seek (io, 0); From 25dd47804dc8f314ad2061c0d0a50e5827f1de51 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Dec 2010 07:06:41 +0100 Subject: [PATCH 0568/1414] Don't use disk subsystem in freebsd_boot. * grub-core/loader/i386/bsd.c (freebsd_bootdev): New variable. (freebsd_biosdev): Likewise. (grub_freebsd_boot): Use freebsd_bootdev and freebsd_biosdev. (grub_cmd_freebsd): Set freebsd_bootdev and freebsd_biosdev. --- ChangeLog | 9 +++++++++ grub-core/loader/i386/bsd.c | 17 ++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c701a342..0e4a725a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-12-27 Vladimir Serbinenko + + Don't use disk subsystem in freebsd_boot. + + * grub-core/loader/i386/bsd.c (freebsd_bootdev): New variable. + (freebsd_biosdev): Likewise. + (grub_freebsd_boot): Use freebsd_bootdev and freebsd_biosdev. + (grub_cmd_freebsd): Set freebsd_bootdev and freebsd_biosdev. + 2010-12-26 Vladimir Serbinenko Handling of files of unknown size is currently limited. They can't be diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 91cae418c..84cf1a17f 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -521,6 +521,8 @@ grub_netbsd_list_modules (void) /* This function would be here but it's under different license. */ #include "bsd_pagetable.c" +static grub_uint32_t freebsd_bootdev, freebsd_biosdev; + static grub_err_t grub_freebsd_boot (void) { @@ -528,7 +530,6 @@ grub_freebsd_boot (void) grub_uint8_t *p, *p0; grub_addr_t p_target; grub_size_t p_size = 0; - grub_uint32_t bootdev, biosdev, unit, slice, part; grub_err_t err; grub_size_t tag_buf_len = 0; @@ -564,11 +565,7 @@ grub_freebsd_boot (void) bi.version = FREEBSD_BOOTINFO_VERSION; bi.length = sizeof (bi); - grub_bsd_get_device (&biosdev, &unit, &slice, &part); - bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) + - (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); - - bi.boot_device = biosdev; + bi.boot_device = freebsd_biosdev; p_size = 0; grub_env_iterate (iterate_env_count); @@ -741,7 +738,7 @@ grub_freebsd_boot (void) state.ebp = stack_target; stack[0] = entry; /* "Return" address. */ stack[1] = bootflags | FREEBSD_RB_BOOTINFO; - stack[2] = bootdev; + stack[2] = freebsd_bootdev; stack[3] = 0; stack[4] = 0; stack[5] = 0; @@ -1371,6 +1368,8 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) { + grub_uint32_t unit, slice, part; + kern_end = ALIGN_PAGE (kern_end); if (is_elf_kernel) { @@ -1414,6 +1413,10 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) if (err) return err; } + grub_bsd_get_device (&freebsd_biosdev, &unit, &slice, &part); + freebsd_bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) + + (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); + grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0); } From c76386454e2e2214c3082b26ab99f1e733cac5eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Dec 2010 07:09:43 +0100 Subject: [PATCH 0569/1414] Avoid using Reed-Solomon with 0 redundancy. * grub-core/kern/i386/pc/startup.S: Remove 0-data check. * grub-core/lib/reed_solomon.c (decode_block): Do not proceed on 0 data or 0 redundancy. (grub_reed_solomon_add_redundancy): Do not proceed with 0 redundancy. (grub_reed_solomon_recover): Likewise. --- ChangeLog | 10 ++++++++++ grub-core/kern/i386/pc/startup.S | 2 -- grub-core/lib/reed_solomon.c | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0e4a725a5..d7606da2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-12-27 Vladimir Serbinenko + + Avoid using Reed-Solomon with 0 redundancy. + + * grub-core/kern/i386/pc/startup.S: Remove 0-data check. + * grub-core/lib/reed_solomon.c (decode_block): Do not proceed on 0 data + or 0 redundancy. + (grub_reed_solomon_add_redundancy): Do not proceed with 0 redundancy. + (grub_reed_solomon_recover): Likewise. + 2010-12-27 Vladimir Serbinenko Don't use disk subsystem in freebsd_boot. diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 7aebc8b38..e78a0aa9a 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -151,8 +151,6 @@ LOCAL (codestart): addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx movl reed_solomon_redundancy, %ecx leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax - testl %edx, %edx - jz post_reed_solomon call EXT_C (grub_reed_solomon_recover) jmp post_reed_solomon diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 6f571550a..9a40e2f98 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -372,6 +372,10 @@ decode_block (gf_single_t *ptr, grub_size_t s, grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; gf_single_t m[ds + rr]; + /* Nothing to do. */ + if (!ds || !rr) + continue; + for (j = 0; j < (int) ds; j++) m[j] = ptr[SECTOR_SIZE * j + i]; for (j = 0; j < (int) rr; j++) @@ -414,6 +418,10 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, gf_single_t *ptr = buffer; gf_single_t *rptr = ptr + s; + /* Nothing to do. */ + if (!rs) + return; + while (s > 0) { grub_size_t tt; @@ -441,6 +449,10 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) gf_single_t *ptr = ptr_; gf_single_t *rptr = ptr + s; + /* Nothing to do. */ + if (!rs) + return; + #if defined (STANDALONE) init_inverts (); #endif @@ -454,8 +466,8 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) tt = cs + crs; if (tt > MAX_BLOCK_SIZE) { - cs = cs * MAX_BLOCK_SIZE / tt; - crs = crs * MAX_BLOCK_SIZE / tt; + cs = (cs * MAX_BLOCK_SIZE) / tt; + crs = (crs * MAX_BLOCK_SIZE) / tt; } decode_block (ptr, cs, rptr, crs); ptr += cs; From 693db2df5615ce6297031e04361b7bcb4b0fd571 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Dec 2010 07:18:24 +0100 Subject: [PATCH 0570/1414] * grub-core/loader/xnu.c (grub_cmd_xnu_kext): Abort if no kernel is loaded (grub_cmd_xnu_kextdir): Likewise. (grub_cmd_xnu_splash): Likewise. --- ChangeLog | 7 +++++++ grub-core/loader/xnu.c | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/ChangeLog b/ChangeLog index d7606da2a..31aa19bad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-27 Vladimir Serbinenko + + * grub-core/loader/xnu.c (grub_cmd_xnu_kext): Abort if no kernel + is loaded + (grub_cmd_xnu_kextdir): Likewise. + (grub_cmd_xnu_splash): Likewise. + 2010-12-27 Vladimir Serbinenko Avoid using Reed-Solomon with 0 redundancy. diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index d0b32dc6f..02151dd9c 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -1198,6 +1198,10 @@ grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)), int argc, char *args[]) { grub_file_t binfile = 0; + + if (! grub_xnu_heap_size) + return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); + if (argc == 2) { /* User explicitly specified plist and binary. */ @@ -1229,6 +1233,9 @@ grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)), if (argc != 1 && argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required"); + if (! grub_xnu_heap_size) + return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); + if (argc == 1) return grub_xnu_scan_dir_for_kexts (args[0], "console,root,local-root,network-root", @@ -1370,6 +1377,9 @@ grub_cmd_xnu_splash (grub_extcmd_context_t ctxt, if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + if (! grub_xnu_heap_size) + return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded"); + if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set && grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg, "stretch") == 0) From 14b48a19c21667755e3080b5aa4bf231693d7346 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Dec 2010 07:19:51 +0100 Subject: [PATCH 0571/1414] * grub-core/loader/xnu.c (grub_cmd_xnu_kernel) [! GRUB_MACHINE_EFI]: Preload EFIemu. (grub_cmd_xnu_kernel64) [! GRUB_MACHINE_EFI]: Likewise. --- ChangeLog | 6 ++++++ grub-core/loader/xnu.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index 31aa19bad..9c1d85dcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-27 Vladimir Serbinenko + + * grub-core/loader/xnu.c (grub_cmd_xnu_kernel) [! GRUB_MACHINE_EFI]: + Preload EFIemu. + (grub_cmd_xnu_kernel64) [! GRUB_MACHINE_EFI]: Likewise. + 2010-12-27 Vladimir Serbinenko * grub-core/loader/xnu.c (grub_cmd_xnu_kext): Abort if no kernel diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 02151dd9c..95857951a 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -34,6 +34,10 @@ #include #include +#if defined (__i386) && !defined (GRUB_MACHINE_EFI) +#include +#endif + struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; static int driversnum = 0; @@ -424,6 +428,12 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; +#if defined (__i386) && !defined (GRUB_MACHINE_EFI) + err = grub_efiemu_autocore (); + if (err) + return err; +#endif + grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); @@ -529,6 +539,12 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; +#if defined (__i386) && !defined (GRUB_MACHINE_EFI) + err = grub_efiemu_autocore (); + if (err) + return err; +#endif + grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0); grub_xnu_lock (); From 406a552051bdda5fa07de20a10ccfa7910ca946b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Dec 2010 10:43:04 +0100 Subject: [PATCH 0572/1414] Add plan9 to OS support table --- docs/grub.texi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/grub.texi b/docs/grub.texi index 54a2d8791..6878a645a 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 Plan9 @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 Plan9 @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 Plan9 @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 Plan9 @tab no (1) @item FreeBSD bootloader @tab crashes (1) @item 32-bit kFreeBSD @tab crashes (6) @item 64-bit kFreeBSD @tab crashes (6) From b12b923e6335dd87944b49de08a021fac0c04b1b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 Dec 2010 12:37:35 +0100 Subject: [PATCH 0573/1414] * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Silence spurious warning. Reported by: crocket --- ChangeLog | 6 ++++++ grub-core/loader/i386/bsdXX.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9c1d85dcd..dae48b0e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-31 Vladimir Serbinenko + + * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Silence + spurious warning. + Reported by: crocket + 2010-12-27 Vladimir Serbinenko * grub-core/loader/xnu.c (grub_cmd_xnu_kernel) [! GRUB_MACHINE_EFI]: diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index 29892e5fb..2dd180509 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -511,7 +511,7 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, grub_err_t err; Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = NULL; err = read_headers (file, &e, &shdr); if (err) From 307806cb53c3e5ef0dd15b8e8aba23b354b42416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 Dec 2010 14:55:55 +0100 Subject: [PATCH 0574/1414] * grub-core/partmap/amiga.c (GRUB_AMIGA_RDSK_MAGIC): New define. (amiga_partition_map_iterate): Use grub_memcmp instead of grub_strcmp. Reported by:EHeM. --- ChangeLog | 6 ++++++ grub-core/partmap/amiga.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dae48b0e6..c9339e164 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-31 Vladimir Serbinenko + + * grub-core/partmap/amiga.c (GRUB_AMIGA_RDSK_MAGIC): New define. + (amiga_partition_map_iterate): Use grub_memcmp instead of grub_strcmp. + Reported by:EHeM. + 2010-12-31 Vladimir Serbinenko * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Silence diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c index f21c5b243..a3ea3499c 100644 --- a/grub-core/partmap/amiga.c +++ b/grub-core/partmap/amiga.c @@ -27,6 +27,7 @@ struct grub_amiga_rdsk { /* "RDSK". */ grub_uint8_t magic[4]; +#define GRUB_AMIGA_RDSK_MAGIC "RDSK" grub_uint32_t size; grub_int32_t checksum; grub_uint32_t scsihost; @@ -87,7 +88,8 @@ amiga_partition_map_iterate (grub_disk_t disk, if (grub_disk_read (disk, pos, 0, sizeof (rdsk), &rdsk)) return grub_errno; - if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0) + if (grub_memcmp (rdsk.magic, GRUB_AMIGA_RDSK_MAGIC, + sizeof (rdsk.magic)) == 0) { /* Found the first PART block. */ next = grub_be_to_cpu32 (rdsk.partitionlst); From 275bff5f000f1d424dd86841f10ef79d4fc6c665 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 Dec 2010 15:00:45 +0100 Subject: [PATCH 0575/1414] * grub-core/partmap/amiga.c (GRUB_AMIGA_PART_MAGIC): New define. (amiga_partition_map_iterate): Check "PART" magic to avoid a very long loop in case of incorrect amiga partmap. --- ChangeLog | 6 ++++++ grub-core/partmap/amiga.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index c9339e164..505c1cc0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-12-31 Vladimir Serbinenko + + * grub-core/partmap/amiga.c (GRUB_AMIGA_PART_MAGIC): New define. + (amiga_partition_map_iterate): Check "PART" magic to avoid a very long + loop in case of incorrect amiga partmap. + 2010-12-31 Vladimir Serbinenko * grub-core/partmap/amiga.c (GRUB_AMIGA_RDSK_MAGIC): New define. diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c index a3ea3499c..1e0f23402 100644 --- a/grub-core/partmap/amiga.c +++ b/grub-core/partmap/amiga.c @@ -44,6 +44,7 @@ struct grub_amiga_partition { /* "PART". */ grub_uint8_t magic[4]; +#define GRUB_AMIGA_PART_MAGIC "PART" grub_int32_t size; grub_int32_t checksum; grub_uint32_t scsihost; @@ -110,6 +111,9 @@ amiga_partition_map_iterate (grub_disk_t disk, if (grub_disk_read (disk, next, 0, sizeof (apart), &apart)) return grub_errno; + if (grub_memcmp (apart.magic, GRUB_AMIGA_PART_MAGIC, + sizeof (apart.magic)) == 0) + /* Calculate the first block and the size of the partition. */ part.start = (grub_be_to_cpu32 (apart.lowcyl) * grub_be_to_cpu32 (apart.heads) From b9cd13659cce5dd2414e962c02042c9ece90b918 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 31 Dec 2010 15:22:36 +0100 Subject: [PATCH 0576/1414] 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 0577/1414] 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 1b394975e927af0533d42fc516dfc36d57a6692b Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 31 Dec 2010 22:49:42 +0000 Subject: [PATCH 0578/1414] * util/grub.d/20_linux_xen.in (linux_entry): Correctly capitalize Xen and reorder menu item wording to make it clearer that this entry will launch Xen. Print separate messages when loading Xen and Linux. --- ChangeLog | 7 +++++++ util/grub.d/20_linux_xen.in | 12 +++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 505c1cc0d..9881baee9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-31 Ian Campbell + + * util/grub.d/20_linux_xen.in (linux_entry): Correctly capitalize + Xen and reorder menu item wording to make it clearer that this entry + will launch Xen. Print separate messages when loading Xen and + Linux. + 2010-12-31 Vladimir Serbinenko * grub-core/partmap/amiga.c (GRUB_AMIGA_PART_MAGIC): New define. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index a90211f44..ee49cd903 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -60,11 +60,11 @@ linux_entry () args="$5" xen_args="$6" if ${recovery} ; then - title="$(gettext_quoted "%s, with Linux %s and XEN %s (recovery mode)")" + title="$(gettext_quoted "%s, with Xen %s and Linux %s (recovery mode)")" else - title="$(gettext_quoted "%s, with Linux %s and XEN %s")" + title="$(gettext_quoted "%s, with Xen %s and Linux %s")" fi - printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" "${xen_version}" + printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${xen_version}" "${version}" if ! ${recovery} ; then save_default_entry | sed -e "s/^/\t/" fi @@ -73,10 +73,12 @@ linux_entry () prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi printf '%s\n' "${prepare_boot_cache}" - message="$(gettext_printf "Loading Linux %s ..." ${version})" + xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})" + lmessage="$(gettext_printf "Loading Linux %s ..." ${version})" cat << EOF - echo '$message' + echo '$xmessage' multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} + echo '$lmessage' module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then From 3a04c65d008246c29d8a0b86fb66770ac6d6634f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 Jan 2011 15:13:03 +0100 Subject: [PATCH 0579/1414] 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 0580/1414] 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 0581/1414] 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 0582/1414] 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 0583/1414] 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 0584/1414] 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 0585/1414] 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 0586/1414] 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 0587/1414] 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 0588/1414] 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 0589/1414] 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 0590/1414] 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 0591/1414] 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 0592/1414] 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 323a8e9c6413ea90030c24d663f4c4f12a7a1ffd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Jan 2011 14:16:42 +0100 Subject: [PATCH 0593/1414] * util/grub-mkfont.c (main): Report errors in FT_New_Face. --- ChangeLog | 4 ++++ util/grub-mkfont.c | 13 ++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9881baee9..7f5a316fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-03 Vladimir Serbinenko + + * util/grub-mkfont.c (main): Report errors in FT_New_Face. + 2010-12-31 Ian Campbell * util/grub.d/20_linux_xen.in (linux_entry): Correctly capitalize diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index fff6a619e..983ac7065 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -1146,11 +1146,18 @@ main (int argc, char *argv[]) { FT_Face ft_face; int size; + FT_Error err; - if (FT_New_Face (ft_lib, argv[optind], font_index, &ft_face)) + err = FT_New_Face (ft_lib, argv[optind], font_index, &ft_face); + if (err) { - grub_util_info ("can't open file %s, index %d", argv[optind], - font_index); + grub_printf ("can't open file %s, index %d: error %d", argv[optind], + font_index, err); + if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) + printf (": %s\n", ft_errmsgs[err]); + else + printf ("\n"); + continue; } From 469ee10a7f8637ce676fd3c8f43094f4235c020a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Jan 2011 14:33:43 +0100 Subject: [PATCH 0594/1414] * util/grub-install.in: Correctly use bootloader_id and not GRUB_DISTRIBUTOR on efibootmgr line. --- ChangeLog | 5 +++++ util/grub-install.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7f5a316fc..f7b08c1e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-03 Vladimir Serbinenko + + * util/grub-install.in: Correctly use bootloader_id and not + GRUB_DISTRIBUTOR on efibootmgr line. + 2011-01-03 Vladimir Serbinenko * util/grub-mkfont.c (main): Report errors in FT_New_Face. 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 4af0504b724b89d7e8057e64a6260a4d04781ffd Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Mon, 3 Jan 2011 15:30:41 +0100 Subject: [PATCH 0595/1414] * grub-core/fs/hfsplus.c: Make parent unsigned. (grub_hfsplus_cmp_catkey): Don't compare using subtraction, it overflows. (grub_hfsplus_cmp_extkey): Likewise --- ChangeLog | 7 +++++++ grub-core/fs/hfsplus.c | 33 +++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index f7b08c1e6..d89cb8618 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-03 Dave Vasilevsky + + * grub-core/fs/hfsplus.c: Make parent unsigned. + (grub_hfsplus_cmp_catkey): Don't compare using subtraction, it + overflows. + (grub_hfsplus_cmp_extkey): Likewise + 2011-01-03 Vladimir Serbinenko * util/grub-install.in: Correctly use bootloader_id and not diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index bcb8e9584..7d7115ce3 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -178,7 +178,7 @@ enum grub_hfsplus_filetype /* Internal representation of a catalog key. */ struct grub_hfsplus_catkey_internal { - int parent; + grub_uint32_t parent; char *name; }; @@ -520,9 +520,12 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, int i; int diff; - diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent; - if (diff) - return diff; + /* Safe unsigned comparison */ + grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent); + if (aparent > catkey_b->parent) + return 1; + if (aparent < catkey_b->parent) + return -1; /* Change the filename in keya so the endianness is correct. */ for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) @@ -555,15 +558,21 @@ grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, { struct grub_hfsplus_extkey *extkey_a = &keya->extkey; struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey; - int diff; + grub_uint32_t akey; - diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid; - - if (diff) - return diff; - - diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start; - return diff; + /* Safe unsigned comparison */ + akey = grub_be_to_cpu32 (extkey_a->fileid); + if (akey > extkey_b->fileid) + return 1; + if (akey < extkey_b->fileid) + return -1; + + akey = grub_be_to_cpu32 (extkey_a->start); + if (akey > extkey_b->start) + return 1; + if (akey < extkey_b->start) + return -1; + return 0; } static char * From fb7ab4a99ba343167d3d0c5a8affa38c8dc057bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Jan 2011 15:54:59 +0100 Subject: [PATCH 0596/1414] add missing == 0 --- grub-core/net/net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 54663f4b0..d3b4c74db 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -199,7 +199,7 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[1])) + if (grub_strcmp (inter->name, args[1]) == 0) break; if (inter == NULL) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); @@ -730,7 +730,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, "4 arguments expected"); FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[1])) + if (grub_strcmp (inter->name, args[1]) == 0) break; if (!inter) From 7a1d4deec9267fc56ed50507b5a7fa9d96e3b610 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Jan 2011 15:59:20 +0100 Subject: [PATCH 0597/1414] Fix finalisation/restore --- grub-core/disk/ahci.c | 255 +++++++++++++++++++++++++++++++----------- 1 file changed, 192 insertions(+), 63 deletions(-) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index b348ce3d0..c67dbbe7e 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -157,6 +157,98 @@ enum static struct grub_ahci_device *grub_ahci_devices; static int numdevs; +static int +init_port (struct grub_ahci_device *dev) +{ + struct grub_pci_dma_chunk *command_list; + struct grub_pci_dma_chunk *command_table; + grub_uint64_t endtime; + + command_list = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head)); + if (!command_list) + return 1; + + command_table = grub_memalign_dma32 (1024, + sizeof (struct grub_ahci_cmd_table)); + if (!command_table) + { + grub_dma_free (command_list); + return 1; + } + + grub_dprintf ("ahci", "found device ahci%d (port %d)\n", dev->num, dev->port); + + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; + endtime = grub_get_time_ms () + 1000; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't stop FR\n"); + goto out; + } + + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; + endtime = grub_get_time_ms () + 1000; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't stop CR\n"); + goto out; + } + + dev->hba->ports[dev->port].fbs = 2; + + dev->rfis = grub_memalign_dma32 (4096, + sizeof (struct grub_ahci_received_fis)); + grub_memset ((char *) grub_dma_get_virt (dev->rfis), 0, + sizeof (struct grub_ahci_received_fis)); + dev->hba->ports[dev->port].fis_base = grub_dma_get_phys (dev->rfis); + dev->hba->ports[dev->port].command_list_base + = grub_dma_get_phys (command_list); + dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_FRE; + while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't start FR\n"); + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; + goto out; + } + dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_ST; + while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't start CR\n"); + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_CR; + goto out_stop_fr; + } + + dev->hba->ports[dev->port].command + = (dev->hba->ports[dev->port].command & 0x0fffffff) | (1 << 28) | 2 | 4; + + dev->command_list_chunk = command_list; + dev->command_list = grub_dma_get_virt (command_list); + dev->command_table_chunk = command_table; + dev->command_table = grub_dma_get_virt (command_table); + dev->command_list->command_table_base + = grub_dma_get_phys (command_table); + + return 0; + out_stop_fr: + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; + endtime = grub_get_time_ms () + 1000; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't stop FR\n"); + break; + } + out: + grub_dma_free (command_list); + grub_dma_free (command_table); + grub_dma_free (dev->rfis); + return 1; +} + static int NESTED_FUNC_ATTR grub_ahci_pciinit (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) @@ -209,7 +301,50 @@ grub_ahci_pciinit (grub_pci_device_t dev, else grub_dprintf ("ahci", "AHCI is already in OS mode\n"); - hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; + if (~(hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN)) + grub_dprintf ("ahci", "AHCI is in compat mode. Switching\n"); + else + grub_dprintf ("ahci", "AHCI is in AHCI mode.\n"); + + for (i = 0; i < 5; i++) + { + hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; + grub_millisleep (1); + if (hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN) + break; + } + if (i == 5) + { + grub_dprintf ("ahci", "Couldn't put AHCI in AHCI mode\n"); + return 0; + } + + /* + { + grub_uint64_t endtime; + hba->global_control |= 1; + endtime = grub_get_time_ms () + 1000; + while (hba->global_control & 1) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't reset AHCI\n"); + return 0; + } + } + + for (i = 0; i < 5; i++) + { + hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; + grub_millisleep (1); + if (hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN) + break; + } + if (i == 5) + { + grub_dprintf ("ahci", "Couldn't put AHCI in AHCI mode\n"); + return 0; + } + */ nports = (hba->cap & GRUB_AHCI_HBA_CAP_NPORTS_MASK) + 1; @@ -218,8 +353,6 @@ grub_ahci_pciinit (grub_pci_device_t dev, for (i = 0; i < nports; i++) { struct grub_ahci_device *adev; - struct grub_pci_dma_chunk *command_list; - struct grub_pci_dma_chunk *command_table; grub_uint32_t st; if (!(hba->ports_implemented & (1 << i))) @@ -231,60 +364,20 @@ grub_ahci_pciinit (grub_pci_device_t dev, if ((st & 0xf) != 0x3 && (st & 0xf) != 0x1) continue; - command_list = grub_memalign_dma32 (1024, - sizeof (struct grub_ahci_cmd_head)); - if (!command_list) - return 1; - - command_table = grub_memalign_dma32 (1024, - sizeof (struct grub_ahci_cmd_table)); - if (!command_table) - { - grub_dma_free (command_list); - return 1; - } - adev = grub_malloc (sizeof (*adev)); if (!adev) - { - grub_dma_free (command_list); - grub_dma_free (command_table); - return 1; - } - - grub_dprintf ("ahci", "found device ahci%d (port %d)\n", numdevs, i); - - hba->ports[i].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - while ((hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_FR)); - hba->ports[i].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - while ((hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_CR)); - - hba->ports[i].fbs = 2; - - adev->rfis = grub_memalign_dma32 (4096, - sizeof (struct grub_ahci_received_fis)); - grub_memset ((char *) grub_dma_get_virt (adev->rfis), 0, - sizeof (struct grub_ahci_received_fis)); - hba->ports[i].fis_base = grub_dma_get_phys (adev->rfis); - hba->ports[i].command |= GRUB_AHCI_HBA_PORT_CMD_FRE; - while (!(hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_FR)); - hba->ports[i].command |= GRUB_AHCI_HBA_PORT_CMD_ST; - while (!(hba->ports[i].command & GRUB_AHCI_HBA_PORT_CMD_CR)); - - hba->ports[i].command = (hba->ports[i].command & 0x0fffffff) - | (1 << 28) | 2 | 4; + return 1; adev->hba = hba; adev->port = i; adev->num = numdevs++; - adev->command_list_chunk = command_list; - adev->command_list = grub_dma_get_virt (command_list); - adev->command_table_chunk = command_table; - adev->command_table = grub_dma_get_virt (command_table); - adev->command_list->command_table_base - = grub_dma_get_phys (command_table); - adev->hba->ports[i].command_list_base = grub_dma_get_phys (command_list); + if (init_port (adev)) + { + grub_free (adev); + return 1; + } + grub_list_push (GRUB_AS_LIST_P (&grub_ahci_devices), GRUB_AS_LIST (adev)); } @@ -302,29 +395,53 @@ grub_ahci_initialize (void) static grub_err_t grub_ahci_fini_hw (int noreturn __attribute__ ((unused))) { - struct grub_ahci_device *dev, *next; + struct grub_ahci_device *dev; - for (dev = grub_ahci_devices; dev; dev = next) + for (dev = grub_ahci_devices; dev; dev = dev->next) { - next = dev->next; - dev->hba->ports[dev->num].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - while ((dev->hba->ports[dev->num].command & GRUB_AHCI_HBA_PORT_CMD_FR)); - dev->hba->ports[dev->num].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - while ((dev->hba->ports[dev->num].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + grub_uint64_t endtime; + + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; + endtime = grub_get_time_ms () + 1000; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't stop FR\n"); + break; + } + + dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; + endtime = grub_get_time_ms () + 1000; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't stop CR\n"); + break; + } grub_dma_free (dev->command_list_chunk); grub_dma_free (dev->command_table_chunk); grub_dma_free (dev->rfis); - - grub_free (dev); + dev->command_list_chunk = NULL; + dev->command_table_chunk = NULL; + dev->rfis = NULL; } - grub_ahci_devices = NULL; return GRUB_ERR_NONE; } static grub_err_t grub_ahci_restore_hw (void) { - return grub_ahci_initialize (); + struct grub_ahci_device **pdev; + + for (pdev = &grub_ahci_devices; *pdev; pdev = &((*pdev)->next)) + if (init_port (*pdev)) + { + struct grub_ahci_device *odev; + odev = *pdev; + *pdev = (*pdev)->next; + grub_free (odev); + } + return GRUB_ERR_NONE; } @@ -391,9 +508,21 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, if ((dev->hba->ports[dev->port].task_file_data & 0x80)) { dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + endtime = grub_get_time_ms () + 1000; + while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't stop CR\n"); + break; + } dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_ST; - while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)); + endtime = grub_get_time_ms () + 1000; + while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) + if (grub_get_time_ms () > endtime) + { + grub_dprintf ("ahci", "couldn't start CR\n"); + break; + } } dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error; From 99d925aad45bb0f929a24957a43b83d50929cca4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 3 Jan 2011 23:56:45 +0000 Subject: [PATCH 0598/1414] * grub-core/bus/pci.c (grub_pci_iterate): Skip remaining functions on devices that do not implement function 0. --- ChangeLog | 5 +++++ grub-core/bus/pci.c | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d89cb8618..a4692b5a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-03 Colin Watson + + * grub-core/bus/pci.c (grub_pci_iterate): Skip remaining functions + on devices that do not implement function 0. + 2011-01-03 Dave Vasilevsky * grub-core/fs/hfsplus.c: Make parent unsigned. diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index bf14a8653..11101d42b 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -90,7 +90,14 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) /* Check if there is a device present. */ if (id >> 16 == 0xFFFF) - continue; + { + if (dev.function == 0) + /* Devices are required to implement function 0, so if + it's missing then there is no device here. */ + break; + else + continue; + } #ifdef GRUB_MACHINE_MIPS_YEELOONG /* Skip ghosts. */ From 5b1bdf12314a2a76168c0d03f729d33af9e2b778 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 4 Jan 2011 13:05:19 +0000 Subject: [PATCH 0599/1414] * grub-core/commands/legacycfg.c (GRUB_MOD_INIT): Fix typo in descriptions of extract_legacy_entries_source and extract_legacy_entries_configfile. Reported by: Seung Soo, Ha. --- ChangeLog | 7 +++++++ grub-core/commands/legacycfg.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a4692b5a7..b4a308e9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-04 Colin Watson + + * grub-core/commands/legacycfg.c (GRUB_MOD_INIT): Fix typo in + descriptions of extract_legacy_entries_source and + extract_legacy_entries_configfile. + Reported by: Seung Soo, Ha. + 2011-01-03 Colin Watson * grub-core/bus/pci.c (grub_pci_iterate): Skip remaining functions diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 80718196a..de392ac81 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -765,12 +765,12 @@ GRUB_MOD_INIT(legacycfg) = grub_register_command ("extract_legacy_entries_source", grub_cmd_legacy_source, N_("FILE"), - N_("Parse legacy config in same context taking onl entries")); + N_("Parse legacy config in same context taking only menu entries")); cmd_configfile_extract = grub_register_command ("extract_legacy_entries_configfile", grub_cmd_legacy_source, N_("FILE"), - N_("Parse legacy config in new context taking onl entries")); + N_("Parse legacy config in new context taking only menu entries")); cmd_kernel = grub_register_command ("legacy_kernel", grub_cmd_legacy_kernel, From 956384994b66a9c1a72876738d41b5e0e24b9022 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 Jan 2011 15:35:10 +0100 Subject: [PATCH 0600/1414] * grub-core/lib/reed_solomon.c (scratch) [! STANDALONE]: Remove leftover variable. --- ChangeLog | 5 +++++ grub-core/lib/reed_solomon.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index b4a308e9a..d40ea54aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-03 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (scratch) [! STANDALONE]: Remove leftover + variable. + 2011-01-04 Colin Watson * grub-core/commands/legacycfg.c (GRUB_MOD_INIT): Fix typo in diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 9a40e2f98..740a069ee 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -60,7 +60,9 @@ typedef grub_uint16_t gf_double_t; static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; #else +#if defined (STANDALONE) static char *scratch; +#endif static grub_uint8_t gf_invert[256]; #endif From e5146ca18b828a17e79a122b648fbd390e7bd122 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 Jan 2011 15:37:10 +0100 Subject: [PATCH 0601/1414] * grub-core/lib/reed_solomon.c (main) [TEST]: Reactivate normal test. --- ChangeLog | 6 +++++- grub-core/lib/reed_solomon.c | 9 +-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index d40ea54aa..505923fa9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2011-01-03 Vladimir Serbinenko +2011-01-04 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (main) [TEST]: Reactivate normal test. + +2011-01-04 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (scratch) [! STANDALONE]: Remove leftover variable. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 740a069ee..62aad3111 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -501,14 +501,10 @@ main (int argc, char **argv) fseek (in, 0, SEEK_END); s = ftell (in); fseek (in, 0, SEEK_SET); - rs = 1024 * ((s + MAX_BLOCK_SIZE - 1) / (MAX_BLOCK_SIZE - 1024)); + rs = s / 3; buf = xmalloc (s + rs + SECTOR_SIZE); fread (buf, 1, s, in); - s = 0x5fbb; - rs = 0x6af9; - -#if 0 grub_reed_solomon_add_redundancy (buf, s, rs); out = fopen ("tst_rs.bin", "wb"); @@ -520,9 +516,6 @@ main (int argc, char **argv) out = fopen ("tst_dam.bin", "wb"); fwrite (buf, 1, s + rs, out); fclose (out); -#endif - s = 0x5fbb; - rs = 0x6af9; grub_reed_solomon_recover (buf, s, rs); out = fopen ("tst_rec.bin", "wb"); From a0159f370da21f7dd264e7b4185f15907cca19ef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 Jan 2011 15:39:59 +0100 Subject: [PATCH 0602/1414] * grub-core/lib/reed_solomon.c (grub_reed_solomon_add_redundancy): Prevent overflow. (grub_reed_solomon_recover): Likewise. --- ChangeLog | 6 ++++++ grub-core/lib/reed_solomon.c | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 505923fa9..3e20a118b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-04 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (grub_reed_solomon_add_redundancy): + Prevent overflow. + (grub_reed_solomon_recover): Likewise. + 2011-01-04 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (main) [TEST]: Reactivate normal test. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 62aad3111..e500ba32d 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -433,8 +433,8 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, tt = cs + crs; if (tt > MAX_BLOCK_SIZE) { - cs = (cs * MAX_BLOCK_SIZE) / tt; - crs = (crs * MAX_BLOCK_SIZE) / tt; + cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; + crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; } encode_block (ptr, cs, rptr, crs); ptr += cs; @@ -468,8 +468,8 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) tt = cs + crs; if (tt > MAX_BLOCK_SIZE) { - cs = (cs * MAX_BLOCK_SIZE) / tt; - crs = (crs * MAX_BLOCK_SIZE) / tt; + cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; + crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; } decode_block (ptr, cs, rptr, crs); ptr += cs; From 446fa40081ab2602dcad9ebdfc4564e63fed1c76 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 Jan 2011 15:42:47 +0100 Subject: [PATCH 0603/1414] * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Workaround buggy BIOSes. --- ChangeLog | 5 +++++ grub-core/disk/i386/pc/biosdisk.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3e20a118b..f3fa4d4c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-04 Vladimir Serbinenko + + * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Workaround buggy + BIOSes. + 2011-01-04 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (grub_reed_solomon_add_redundancy): diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 3f9015fb9..069bb0b59 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -624,6 +624,11 @@ GRUB_MOD_INIT(biosdisk) ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) cd_drive = cdrp->drive_no; + /* Since diskboot.S rejects devices over 0x90 it must be a CD booted with + cdboot.S + */ + if (grub_boot_drive >= 0x90) + cd_drive = grub_boot_drive; grub_disk_dev_register (&grub_biosdisk_dev); } From ebc71d284cae71f142486b7f6b98fbd978af3833 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 Jan 2011 18:15:27 +0100 Subject: [PATCH 0604/1414] * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Check md/%s names. Reported by: David Pravec. --- ChangeLog | 6 ++++++ grub-core/kern/emu/getroot.c | 11 +++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3fa4d4c0..bba94dfd9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-04 Vladimir Serbinenko + + * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Check md/%s + names. + Reported by: David Pravec. + 2011-01-04 Vladimir Serbinenko * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Workaround buggy diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index f51dcd770..5356685e9 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -794,11 +794,18 @@ grub_util_get_grub_dev (const char *os_dev) #ifdef __linux__ { char *mdadm_name = get_mdadm_name (os_dev); + struct stat st; if (mdadm_name) { - free (grub_dev); - grub_dev = xasprintf ("md/%s", mdadm_name); + char *newname; + newname = xasprintf ("/dev/md/%s", mdadm_name); + if (stat (newname, &st) == 0) + { + free (grub_dev); + grub_dev = xasprintf ("md/%s", mdadm_name); + } + free (newname); free (mdadm_name); } } From 9eae2084f405a7ae3ac25b87daf23c224956fd42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 4 Jan 2011 19:08:03 +0100 Subject: [PATCH 0605/1414] * grub-core/lib/efi/relocator.c (grub_relocator_firmware_fill_events): Ignore the memory post-4G. (grub_relocator_firmware_alloc_region): Additional debug statement. --- ChangeLog | 6 ++++++ grub-core/lib/efi/relocator.c | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bba94dfd9..cda79b44a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-04 Vladimir Serbinenko + + * grub-core/lib/efi/relocator.c (grub_relocator_firmware_fill_events): + Ignore the memory post-4G. + (grub_relocator_firmware_alloc_region): Additional debug statement. + 2011-01-04 Vladimir Serbinenko * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Check md/%s diff --git a/grub-core/lib/efi/relocator.c b/grub-core/lib/efi/relocator.c index fc4de834b..0d346bea3 100644 --- a/grub-core/lib/efi/relocator.c +++ b/grub-core/lib/efi/relocator.c @@ -62,13 +62,25 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) (char *) desc < ((char *) descs + mmapsize); desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { + grub_uint64_t start = desc->physical_start; + grub_uint64_t end = desc->physical_start + (desc->num_pages << 12); + + /* post-4G addresses are never supported on 32-bit EFI. + Moreover it has been reported that some 64-bit EFI contrary to the + spec don't map post-4G pages. So if you enable post-4G allocations, + map pages manually or check that they are mapped. + */ + if (end >= 0x100000000ULL) + end = 0x100000000ULL; + if (end <= start) + continue; if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) continue; events[counter].type = REG_FIRMWARE_START; - events[counter].pos = desc->physical_start; + events[counter].pos = start; counter++; events[counter].type = REG_FIRMWARE_END; - events[counter].pos = desc->physical_start + (desc->num_pages << 12); + events[counter].pos = end; counter++; } @@ -85,6 +97,9 @@ grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size) if (grub_efi_is_finished) return 1; + grub_dprintf ("relocator", "EFI alloc: %llx, %llx\n", + (unsigned long long) start, (unsigned long long) size); + b = grub_efi_system_table->boot_services; status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS, GRUB_EFI_LOADER_DATA, size >> 12, &address); From 18a38098ad53654bc304271464e01fe0e090249e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Jan 2011 01:14:32 +0100 Subject: [PATCH 0606/1414] The E820 type 5 is BADRAM, not EXEC_CODE. * grub-core/loader/i386/bsd.c (GRUB_E820_EXEC_CODE): Removed. (GRUB_E820_BADRAM): New define. * grub-core/loader/i386/linux.c (grub_linux_boot): Translate code into reserved. Propagate BADRAM. * grub-core/loader/i386/bsd.c (GRUB_E820_EXEC_CODE): Removed. (GRUB_E820_BADRAM): New define. --- ChangeLog | 11 +++++++++++ grub-core/loader/i386/bsd.c | 2 +- grub-core/loader/i386/linux.c | 4 ++-- include/grub/i386/linux.h | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cda79b44a..41241e7a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-01-05 Vladimir Serbinenko + + The E820 type 5 is BADRAM, not EXEC_CODE. + + * grub-core/loader/i386/bsd.c (GRUB_E820_EXEC_CODE): Removed. + (GRUB_E820_BADRAM): New define. + * grub-core/loader/i386/linux.c (grub_linux_boot): Translate code + into reserved. Propagate BADRAM. + * grub-core/loader/i386/bsd.c (GRUB_E820_EXEC_CODE): Removed. + (GRUB_E820_BADRAM): New define. + 2011-01-04 Vladimir Serbinenko * grub-core/lib/efi/relocator.c (grub_relocator_firmware_fill_events): diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 84cf1a17f..08cdcda37 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -252,7 +252,7 @@ struct grub_e820_mmap #define GRUB_E820_RESERVED 2 #define GRUB_E820_ACPI 3 #define GRUB_E820_NVS 4 -#define GRUB_E820_EXEC_CODE 5 +#define GRUB_E820_BADRAM 5 static void generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf) diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 95aa6b456..ca88c7403 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -418,9 +418,9 @@ grub_linux_boot (void) addr, size, GRUB_E820_NVS); break; - case GRUB_MEMORY_CODE: + case GRUB_MEMORY_BADRAM: grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_EXEC_CODE); + addr, size, GRUB_E820_BADRAM); break; default: diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index 63f99db62..9ba83eee2 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -68,7 +68,7 @@ #define GRUB_E820_RESERVED 2 #define GRUB_E820_ACPI 3 #define GRUB_E820_NVS 4 -#define GRUB_E820_EXEC_CODE 5 +#define GRUB_E820_BADRAM 5 #define GRUB_E820_MAX_ENTRY 128 From 488f71f116916549766d4df50d364dc3400c50ba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Jan 2011 01:25:01 +0100 Subject: [PATCH 0607/1414] * grub-core/term/terminfo.c (grub_terminfo_readkey): Handle keys with CTRL. --- ChangeLog | 5 +++++ grub-core/term/terminfo.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 41241e7a0..0932ee7cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-05 Vladimir Serbinenko + + * grub-core/term/terminfo.c (grub_terminfo_readkey): Handle keys with + CTRL. + 2011-01-05 Vladimir Serbinenko The E820 type 5 is BADRAM, not EXEC_CODE. diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index d01811959..8450ea231 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -403,6 +403,8 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, /* Backspace: Ctrl-h. */ if (c == 0x7f) c = '\b'; + if (c < 0x20 && c != '\t' && c!= '\b' && c != '\n' && c != '\r') + c = GRUB_TERM_CTRL | (c - 1 + 'a'); *len = 1; keys[0] = c; return; From 4c3e4f37be31b5b1ed9e1928116f0d504faac937 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Jan 2011 01:28:28 +0100 Subject: [PATCH 0608/1414] * util/grub-install.in: Determine ofpathname, nvsetenv and efibootmgr only when needed. --- ChangeLog | 5 +++++ util/grub-install.in | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0932ee7cb..50da0e678 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-05 Vladimir Serbinenko + + * util/grub-install.in: Determine ofpathname, nvsetenv and efibootmgr + only when needed. + 2011-01-05 Vladimir Serbinenko * grub-core/term/terminfo.c (grub_terminfo_readkey): Handle keys with diff --git a/util/grub-install.in b/util/grub-install.in index 716582dfd..90360c279 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -56,9 +56,6 @@ debug_image= update_nvram=yes -ofpathname="`which ofpathname`" -nvsetenv="`which nvsetenv`" -efibootmgr="`which efibootmgr 2>/dev/null || true`" removable=no efi_quiet= @@ -585,6 +582,8 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" --device-map="${device_map}" "${install_device}" || exit 1 elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then if [ x"$update_nvram" = xyes ]; then + ofpathname="`which ofpathname`" + nvsetenv="`which nvsetenv`" set "$ofpathname" dummy if test -f "$1"; then : @@ -621,6 +620,7 @@ elif [ x"$platform" = xefi ]; then cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}" # Try to make this image bootable using the EFI Boot Manager, if available. + efibootmgr="`which efibootmgr`" if test "$removable" = no && test -n "$efi_distributor" && \ test -n "$efibootmgr"; then # On Linux, we need the efivars kernel modules. From b3f8d28ad0c629d7ae77318be9fe23f8a618d11f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Jan 2011 12:23:06 +0100 Subject: [PATCH 0609/1414] Run terminfo_cls on initing terminfo output to clear the screen and move the cursor to (0,0). * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_init_output): Call grub_terminfo_output_init. * grub-core/term/serial.c (grub_serial_term_output): Set .init. * grub-core/term/terminfo.c (grub_terminfo_output_init): New function. * include/grub/terminfo.h (grub_terminfo_output_init): New declaration. --- ChangeLog | 11 +++++++++++ grub-core/term/ieee1275/ofconsole.c | 2 ++ grub-core/term/serial.c | 1 + grub-core/term/terminfo.c | 7 +++++++ include/grub/terminfo.h | 1 + 5 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index 50da0e678..0159aab3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-01-05 Vladimir Serbinenko + + Run terminfo_cls on initing terminfo output to clear the screen and + move the cursor to (0,0). + + * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_init_output): + Call grub_terminfo_output_init. + * grub-core/term/serial.c (grub_serial_term_output): Set .init. + * grub-core/term/terminfo.c (grub_terminfo_output_init): New function. + * include/grub/terminfo.h (grub_terminfo_output_init): New declaration. + 2011-01-05 Vladimir Serbinenko * util/grub-install.in: Determine ofpathname, nvsetenv and efibootmgr diff --git a/grub-core/term/ieee1275/ofconsole.c b/grub-core/term/ieee1275/ofconsole.c index 2b0bddbbb..ab74f21da 100644 --- a/grub-core/term/ieee1275/ofconsole.c +++ b/grub-core/term/ieee1275/ofconsole.c @@ -170,6 +170,8 @@ grub_ofconsole_init_output (struct grub_term_output *term) grub_ofconsole_dimensions (); + grub_terminfo_output_init (term); + return 0; } diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index d36388359..e672a89d6 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -104,6 +104,7 @@ static struct grub_term_input grub_serial_term_input = static struct grub_term_output grub_serial_term_output = { .name = "serial", + .init = grub_terminfo_output_init, .putchar = grub_terminfo_putchar, .getwh = grub_terminfo_getwh, .getxy = grub_terminfo_getxy, diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 8450ea231..0a8c75c74 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -514,6 +514,13 @@ grub_terminfo_input_init (struct grub_term_input *termi) return GRUB_ERR_NONE; } +grub_err_t +grub_terminfo_output_init (struct grub_term_output *term) +{ + grub_terminfo_cls (term); + return GRUB_ERR_NONE; +} + /* GRUB Command. */ static grub_err_t diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 8317995d8..5a552b327 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -56,6 +56,7 @@ struct grub_terminfo_output_state void (*put) (struct grub_term_output *term, const int c); }; +grub_err_t EXPORT_FUNC(grub_terminfo_output_init) (struct grub_term_output *term); void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_term_output_t term, grub_uint8_t x, grub_uint8_t y); void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t term); From 304e349b7fcfeaaa2a340c0adf30a281b82e62ff Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 5 Jan 2011 11:41:12 +0000 Subject: [PATCH 0610/1414] 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 71b6a2b7a2d9d71cff26b39a941b0f7191bcea42 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 6 Jan 2011 11:09:17 +0000 Subject: [PATCH 0611/1414] * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): Fix prefix check to handle the case where dir ends with a slash (most significantly, "/" itself). Reported by: Michael Vogt. --- ChangeLog | 7 +++++++ grub-core/kern/emu/getroot.c | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0159aab3d..a6d62da6c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-06 Colin Watson + + * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): + Fix prefix check to handle the case where dir ends with a slash + (most significantly, "/" itself). + Reported by: Michael Vogt. + 2011-01-05 Vladimir Serbinenko Run terminfo_cls on initing terminfo output to clear the screen and diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 5356685e9..aedef9e0e 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -135,8 +135,12 @@ find_root_device_from_mountinfo (const char *dir) continue; /* only a subtree is mounted */ enc_path_len = strlen (enc_path); + /* Check that enc_path is a prefix of dir. The prefix must either be + the entire string, or end with a slash, or be immediately followed + by a slash. */ if (strncmp (dir, enc_path, enc_path_len) != 0 || - (dir[enc_path_len] && dir[enc_path_len] != '/')) + (enc_path_len && dir[enc_path_len - 1] != '/' && + dir[enc_path_len] && dir[enc_path_len] != '/')) continue; /* This is a parent of the requested directory. /proc/self/mountinfo From 415502c26a4544292046fbb0b580b352cb346f5f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 6 Jan 2011 13:24:38 +0000 Subject: [PATCH 0612/1414] * tests/util/grub-shell.in: Set serial terminfo type to `dumb', to avoid causing test failures by clearing the screen. --- ChangeLog | 5 +++++ tests/util/grub-shell.in | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index a6d62da6c..a727bd4ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-06 Colin Watson + + * tests/util/grub-shell.in: Set serial terminfo type to `dumb', to + avoid causing test failures by clearing the screen. + 2011-01-06 Colin Watson * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index e35d6bc65..0213376d0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -119,6 +119,7 @@ cat <${cfgfile} grubshell=yes insmod serial serial +terminfo serial dumb terminal_input serial terminal_output serial EOF From 6383772c926fb299953c8830b0d115b55c110f0d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 6 Jan 2011 18:08:01 +0000 Subject: [PATCH 0613/1414] 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 014b68068d4136812f2e3dc16c986351e6fb2779 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 7 Jan 2011 13:27:34 +0100 Subject: [PATCH 0614/1414] =?UTF-8?q?=09*=20util/grub-setup.c=20(setup):?= =?UTF-8?q?=20Handle=20NetBSD=20and=20OpenBSD=20disklabels.=20=09Reported?= =?UTF-8?q?=20and=20tested=20by:=20Gr=C3=A9goire=20Sutre.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 5 +++++ util/grub-setup.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index a727bd4ec..d734d86b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-07 Vladimir Serbinenko + + * util/grub-setup.c (setup): Handle NetBSD and OpenBSD disklabels. + Reported and tested by: GrĂ©goire Sutre. + 2011-01-06 Colin Watson * tests/util/grub-shell.in: Set serial terminfo type to `dumb', to diff --git a/util/grub-setup.c b/util/grub-setup.c index 5f9b29f25..b4749b433 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -49,6 +49,7 @@ #include #include "progname.h" #include +#include #define _GNU_SOURCE 1 #include @@ -339,6 +340,12 @@ setup (const char *dir, { if (p->parent != container) return 0; + /* NetBSD and OpenBSD subpartitions have metadata inside a partition, + so they are safe to ignore. + */ + if (grub_strcmp (p->partmap->name, "netbsd") == 0 + || grub_strcmp (p->partmap->name, "openbsd") == 0) + return 0; if (dest_partmap == NULL) { dest_partmap = p->partmap; @@ -352,6 +359,15 @@ setup (const char *dir, grub_partition_iterate (dest_dev->disk, identify_partmap); + if (container && grub_strcmp (container->partmap->name, "msdos") == 0 + && dest_partmap + && (container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD + || container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD)) + { + grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet.")); + goto unable_to_embed; + } + fs = grub_fs_probe (dest_dev); if (!fs) grub_errno = GRUB_ERR_NONE; From 0ca09e6c528885b5af9b2f614d62f50f79fc413a Mon Sep 17 00:00:00 2001 From: Doug Nazar Date: Fri, 7 Jan 2011 14:41:44 +0100 Subject: [PATCH 0615/1414] * grub-core/disk/raid5_recover.c (grub_raid5_recover): Add missing array->members[i].start_sector. * grub-core/disk/raid6_recover.c (grub_raid6_recover): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/raid5_recover.c | 4 +++- grub-core/disk/raid6_recover.c | 18 +++++++++++++----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d734d86b6..c5cc7afa6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-07 Doug Nazar + + * grub-core/disk/raid5_recover.c (grub_raid5_recover): Add missing + array->members[i].start_sector. + * grub-core/disk/raid6_recover.c (grub_raid6_recover): Likewise. + 2011-01-07 Vladimir Serbinenko * util/grub-setup.c (setup): Handle NetBSD and OpenBSD disklabels. diff --git a/grub-core/disk/raid5_recover.c b/grub-core/disk/raid5_recover.c index 2cda67533..349eb0291 100644 --- a/grub-core/disk/raid5_recover.c +++ b/grub-core/disk/raid5_recover.c @@ -45,7 +45,9 @@ grub_raid5_recover (struct grub_raid_array *array, int disknr, if (i == disknr) continue; - err = grub_disk_read (array->members[i].device, sector, 0, size, buf2); + err = grub_disk_read (array->members[i].device, + array->members[i].start_sector + sector, + 0, size, buf2); if (err) { diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index 01daa2c79..dfaa60ea4 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -119,7 +119,8 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, else { if ((array->members[pos].device) && - (! grub_disk_read (array->members[pos].device, sector, + (! grub_disk_read (array->members[pos].device, + array->members[i].start_sector + sector, 0, size, buf))) { grub_raid_block_xor (pbuf, buf, size); @@ -150,7 +151,9 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, { /* One bad device */ if ((array->members[p].device) && - (! grub_disk_read (array->members[p].device, sector, 0, size, buf))) + (! grub_disk_read (array->members[p].device, + array->members[i].start_sector + sector, + 0, size, buf))) { grub_raid_block_xor (buf, pbuf, size); goto quit; @@ -163,7 +166,8 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, } grub_errno = GRUB_ERR_NONE; - if (grub_disk_read (array->members[q].device, sector, 0, size, buf)) + if (grub_disk_read (array->members[q].device, + array->members[i].start_sector + sector, 0, size, buf)) goto quit; grub_raid_block_xor (buf, qbuf, size); @@ -181,12 +185,16 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, goto quit; } - if (grub_disk_read (array->members[p].device, sector, 0, size, buf)) + if (grub_disk_read (array->members[p].device, + array->members[i].start_sector + sector, + 0, size, buf)) goto quit; grub_raid_block_xor (pbuf, buf, size); - if (grub_disk_read (array->members[q].device, sector, 0, size, buf)) + if (grub_disk_read (array->members[q].device, + array->members[i].start_sector + sector, + 0, size, buf)) goto quit; grub_raid_block_xor (qbuf, buf, size); From c0cf26da6b7662fd309b509b4238aa3877003f15 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 7 Jan 2011 16:17:24 +0100 Subject: [PATCH 0616/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Add missing endian transformations. * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. Based on report by: Doug Nazar. --- ChangeLog | 7 +++++++ grub-core/disk/mdraid1x_linux.c | 19 ++++++++++------- grub-core/disk/mdraid_linux.c | 37 +++++++++++++++++++-------------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5cc7afa6..0362abd51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-07 Vladimir Serbinenko + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Add missing + endian transformations. + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. + Based on report by: Doug Nazar. + 2011-01-07 Doug Nazar * grub-core/disk/raid5_recover.c (grub_raid5_recover): Add missing diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index b6a48b848..155210df3 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -143,24 +143,27 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, &sb)) return grub_errno; - if (sb.magic != SB_MAGIC) + if (grub_le_to_cpu32 (sb.magic) != SB_MAGIC) continue; { grub_uint64_t sb_size; struct grub_raid_super_1x *real_sb; + grub_uint32_t level; - if (sb.major_version != 1) + if (grub_le_to_cpu32 (sb.major_version) != 1) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported RAID version: %d", - sb.major_version); + grub_le_to_cpu32 (sb.major_version)); + + level = grub_le_to_cpu32 (sb.level); /* Multipath. */ - if ((int) sb.level == -4) - sb.level = 1; + if ((int) level == -4) + level = 1; - if (sb.level != 0 && sb.level != 1 && sb.level != 4 && - sb.level != 5 && sb.level != 6 && sb.level != 10) + if (level != 0 && level != 1 && level != 4 && + level != 5 && level != 6 && level != 10) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported RAID level: %d", sb.level); @@ -209,7 +212,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, grub_memcpy (array->uuid, real_sb->set_uuid, 16); - *start_sector = real_sb->data_offset; + *start_sector = grub_le_to_cpu64 (real_sb->data_offset); grub_free (real_sb); return 0; diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index dc0d80ffd..7aa48fd7a 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -167,6 +167,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, grub_uint64_t size; struct grub_raid_super_09 sb; grub_uint32_t *uuid; + grub_uint32_t level; /* The sector where the mdraid 0.90 superblock is stored, if available. */ size = grub_disk_get_size (disk); @@ -178,36 +179,40 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, return grub_errno; /* Look whether there is a mdraid 0.90 superblock. */ - if (sb.md_magic != SB_MAGIC) + if (grub_le_to_cpu32 (sb.md_magic) != SB_MAGIC) return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid"); - if (sb.major_version != 0 || sb.minor_version != 90) + if (grub_le_to_cpu32 (sb.major_version) != 0 + || grub_le_to_cpu32 (sb.minor_version) != 90) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported RAID version: %d.%d", - sb.major_version, sb.minor_version); + grub_le_to_cpu32 (sb.major_version), + grub_le_to_cpu32 (sb.minor_version)); /* FIXME: Check the checksum. */ + level = grub_le_to_cpu32 (sb.level); /* Multipath. */ - if ((int) sb.level == -4) - sb.level = 1; + if ((int) level == -4) + level = 1; - if (sb.level != 0 && sb.level != 1 && sb.level != 4 && - sb.level != 5 && sb.level != 6 && sb.level != 10) + if (level != 0 && level != 1 && level != 4 && + level != 5 && level != 6 && level != 10) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID level: %d", sb.level); - if (sb.this_disk.number == 0xffff || sb.this_disk.number == 0xfffe) + "unsupported RAID level: %d", level); + if (grub_le_to_cpu32 (sb.this_disk.number) == 0xffff + || grub_le_to_cpu32 (sb.this_disk.number) == 0xfffe) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "spares aren't implemented"); array->name = NULL; - array->number = sb.md_minor; - array->level = sb.level; - array->layout = sb.layout; - array->total_devs = sb.raid_disks; - array->disk_size = (sb.size) ? sb.size * 2 : sector; - array->chunk_size = sb.chunk_size >> 9; - array->index = sb.this_disk.number; + array->number = grub_le_to_cpu32 (sb.md_minor); + array->level = level; + array->layout = grub_le_to_cpu32 (sb.layout); + array->total_devs = grub_le_to_cpu32 (sb.raid_disks); + array->disk_size = (sb.size) ? grub_le_to_cpu32 (sb.size) * 2 : sector; + array->chunk_size = grub_le_to_cpu32 (sb.chunk_size) >> 9; + array->index = grub_le_to_cpu32 (sb.this_disk.number); array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) From e72d259fe113e41722904bb25e7a51ba6bc3239c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 7 Jan 2011 17:06:42 +0100 Subject: [PATCH 0617/1414] * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Take into account that inopos might be unaligned. --- ChangeLog | 5 +++++ grub-core/fs/xfs.c | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0362abd51..ca63b0e85 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-07 Vladimir Serbinenko + + * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Take into account that + inopos might be unaligned. + 2011-01-07 Vladimir Serbinenko * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Add missing diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 3d773856e..9f8dc28de 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -451,18 +451,27 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) { grub_uint64_t ino; - void *inopos = (((char *) de) + grub_uint8_t *inopos = (((grub_uint8_t *) de) + sizeof (struct grub_xfs_dir_entry) + de->len - 1); char name[de->len + 1]; + /* inopos might be unaligned. */ if (smallino) - { - ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos); - ino = grub_cpu_to_be64 (ino); - } + ino = (((grub_uint32_t) inopos[0]) << 24) + | (((grub_uint32_t) inopos[1]) << 16) + | (((grub_uint32_t) inopos[2]) << 8) + | (((grub_uint32_t) inopos[3]) << 0); else - ino = *(grub_uint64_t *) inopos; + ino = (((grub_uint64_t) inopos[0]) << 56) + | (((grub_uint64_t) inopos[1]) << 48) + | (((grub_uint64_t) inopos[2]) << 40) + | (((grub_uint64_t) inopos[3]) << 32) + | (((grub_uint64_t) inopos[4]) << 24) + | (((grub_uint64_t) inopos[5]) << 16) + | (((grub_uint64_t) inopos[6]) << 8) + | (((grub_uint64_t) inopos[7]) << 0); + ino = grub_cpu_to_be64 (ino); grub_memcpy (name, de->name, de->len); name[de->len] = '\0'; From 25953e10553dad2e378541a68686fc094603ec54 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 7 Jan 2011 17:09:39 +0100 Subject: [PATCH 0618/1414] Improve loaders' kernel command line handling. * grub-core/lib/cmdline.c: New file. * include/grub/lib/cmdline.h: Likewise. * grub-core/loader/i386/linux.c (grub_cmd_linux): Use grub_create_loader_cmdline to create kernel command line. * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Likewise. * grub-core/loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Likewise. * grub-core/loader/sparc64/ieee1275/linux.c (grub_cmd_linux): Likewise. * grub-core/Makefile.core.def (linux16): Add lib/cmdline.c on i386_pc. (linux): Add lib/cmdline.c on common. --- ChangeLog | 14 +++ grub-core/Makefile.core.def | 2 + grub-core/lib/cmdline.c | 105 ++++++++++++++++++++++ grub-core/loader/i386/linux.c | 26 ++---- grub-core/loader/i386/pc/linux.c | 25 ++---- grub-core/loader/powerpc/ieee1275/linux.c | 23 ++--- grub-core/loader/sparc64/ieee1275/linux.c | 22 ++--- include/grub/lib/cmdline.h | 31 +++++++ 8 files changed, 184 insertions(+), 64 deletions(-) create mode 100644 grub-core/lib/cmdline.c create mode 100644 include/grub/lib/cmdline.h diff --git a/ChangeLog b/ChangeLog index ca63b0e85..d1ddc8741 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-01-07 Szymon Janc + + Improve loaders' kernel command line handling. + + * grub-core/lib/cmdline.c: New file. + * include/grub/lib/cmdline.h: Likewise. + * grub-core/loader/i386/linux.c (grub_cmd_linux): Use + grub_create_loader_cmdline to create kernel command line. + * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Likewise. + * grub-core/loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Likewise. + * grub-core/loader/sparc64/ieee1275/linux.c (grub_cmd_linux): Likewise. + * grub-core/Makefile.core.def (linux16): Add lib/cmdline.c on i386_pc. + (linux): Add lib/cmdline.c on common. + 2011-01-07 Vladimir Serbinenko * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Take into account that diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 37c0ce970..094bbc835 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1149,6 +1149,7 @@ module = { module = { name = linux16; i386_pc = loader/i386/pc/linux.c; + i386_pc = lib/cmdline.c; enable = i386_pc; }; @@ -1183,6 +1184,7 @@ module = { mips = loader/mips/linux.c; powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; + common = lib/cmdline.c; enable = noemu; }; diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c new file mode 100644 index 000000000..a702e6487 --- /dev/null +++ b/grub-core/lib/cmdline.c @@ -0,0 +1,105 @@ +/* cmdline.c - linux command line handling */ +/* + * 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 + +static unsigned int check_arg (char *c, int *has_space) +{ + int space = 0; + unsigned int size = 0; + + while (*c) + { + if (*c == '\\' || *c == '\'' || *c == '"') + size++; + else if (*c == ' ') + space = 1; + + size++; + c++; + } + + if (space) + size += 2; + + if (has_space) + *has_space = space; + + return size; +} + +unsigned int grub_loader_cmdline_size (int argc, char *argv[]) +{ + int i; + unsigned int size = 0; + + for (i = 0; i < argc; i++) + { + size += check_arg (argv[i], 0); + size++; /* Separator space or NULL. */ + } + + return size; +} + +int grub_create_loader_cmdline (int argc, char *argv[], char *buf, + grub_size_t size) +{ + int i, space; + unsigned int arg_size; + char *c; + + for (i = 0; i < argc; i++) + { + c = argv[i]; + arg_size = check_arg(argv[i], &space); + arg_size++; /* Separator space or NULL. */ + + if (size < arg_size) + break; + + size -= arg_size; + + if (space) + *buf++ = '"'; + + while (*c) + { + if (*c == '\\' || *c == '\'' || *c == '"') + *buf++ = '\\'; + + *buf++ = *c; + c++; + } + + if (space) + *buf++ = '"'; + + *buf++ = ' '; + } + + /* Replace last space with null. */ + if (i) + buf--; + + *buf = 0; + + return i; +} diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index ca88c7403..80f583cef 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef GRUB_MACHINE_PCBIOS #include @@ -575,7 +576,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_size_t real_size, prot_size; grub_ssize_t len; int i; - char *dest; grub_dl_ref (my_mod); @@ -836,22 +836,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), params->loadflags |= GRUB_LINUX_FLAG_QUIET; } - - /* Specify the boot file. */ - dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET, - "BOOT_IMAGE="); - dest = grub_stpcpy (dest, argv[0]); - - /* Copy kernel parameters. */ - for (i = 1; - i < argc - && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem - + GRUB_LINUX_CL_END_OFFSET); - i++) - { - *dest++ = ' '; - dest = grub_stpcpy (dest, argv[i]); - } + /* Create kernel command line. */ + grub_memcpy ((char *)real_mode_mem + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE, + sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, + (char *)real_mode_mem + GRUB_LINUX_CL_OFFSET + + sizeof (LINUX_IMAGE) - 1, + GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET + - (sizeof (LINUX_IMAGE) - 1)); len = prot_size; if (grub_file_read (file, prot_mode_mem, len) != len) diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index 90de70f66..96d00f927 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -34,6 +34,7 @@ #include #include #include +#include #define GRUB_LINUX_CL_OFFSET 0x9000 #define GRUB_LINUX_CL_END_OFFSET 0x90FF @@ -86,7 +87,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_size_t real_size; grub_ssize_t len; int i; - char *dest; char *grub_linux_prot_chunk; int grub_linux_is_bzimage; grub_addr_t grub_linux_prot_target; @@ -286,21 +286,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1) << GRUB_DISK_SECTOR_BITS)); - /* Specify the boot file. */ - dest = grub_stpcpy (grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET, - "BOOT_IMAGE="); - dest = grub_stpcpy (dest, argv[0]); - - /* Copy kernel parameters. */ - for (i = 1; - i < argc - && dest + grub_strlen (argv[i]) + 1 < (grub_linux_real_chunk - + GRUB_LINUX_CL_END_OFFSET); - i++) - { - *dest++ = ' '; - dest = grub_stpcpy (dest, argv[i]); - } + /* Create kernel command line. */ + grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET, + LINUX_IMAGE, sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, + (char *)grub_linux_real_chunk + + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1, + GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET + - (sizeof (LINUX_IMAGE) - 1)); if (grub_linux_is_bzimage) grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR; diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c index 231aec1d3..a99310cfd 100644 --- a/grub-core/loader/powerpc/ieee1275/linux.c +++ b/grub-core/loader/powerpc/ieee1275/linux.c @@ -27,6 +27,7 @@ #include #include #include +#include #define ELF32_LOADMASK (0xc0000000UL) #define ELF64_LOADMASK (0xc000000000000000ULL) @@ -238,9 +239,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_elf_t elf = 0; - int i; int size; - char *dest; grub_dl_ref (my_mod); @@ -275,23 +274,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto out; } - size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); - for (i = 0; i < argc; i++) - size += grub_strlen (argv[i]) + 1; - - linux_args = grub_malloc (size); + size = grub_loader_cmdline_size(argc, argv); + linux_args = grub_malloc (size + sizeof (LINUX_IMAGE)); if (! linux_args) goto out; - /* Specify the boot file. */ - dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); - dest = grub_stpcpy (dest, argv[0]); - - for (i = 1; i < argc; i++) - { - *dest++ = ' '; - dest = grub_stpcpy (dest, argv[i]); - } + /* Create kernel command line. */ + grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, + size); out: diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c index 8ea96f1c9..a262049a7 100644 --- a/grub-core/loader/sparc64/ieee1275/linux.c +++ b/grub-core/loader/sparc64/ieee1275/linux.c @@ -27,6 +27,7 @@ #include #include #include +#include static grub_dl_t my_mod; @@ -295,9 +296,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), { grub_file_t file = 0; grub_elf_t elf = 0; - int i; int size; - char *dest; grub_dl_ref (my_mod); @@ -333,23 +332,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto out; } - size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); - for (i = 0; i < argc; i++) - size += grub_strlen (argv[i]) + 1; + size = grub_loader_cmdline_size(argc, argv); - linux_args = grub_malloc (size); + linux_args = grub_malloc (size + sizeof (LINUX_IMAGE)); if (! linux_args) goto out; - /* Specify the boot file. */ - dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); - dest = grub_stpcpy (dest, argv[0]); - - for (i = 1; i < argc; i++) - { - *dest++ = ' '; - dest = grub_stpcpy (dest, argv[i]); - } + /* Create kernel command line. */ + grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, + size); out: if (elf) diff --git a/include/grub/lib/cmdline.h b/include/grub/lib/cmdline.h new file mode 100644 index 000000000..1fe8d0179 --- /dev/null +++ b/include/grub/lib/cmdline.h @@ -0,0 +1,31 @@ +/* cmdline.h - linux command line handling */ +/* + * 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_CMDLINE_HEADER +#define GRUB_CMDLINE_HEADER 1 + +#include + +#define LINUX_IMAGE "BOOT_IMAGE=" + +unsigned int grub_loader_cmdline_size (int argc, char *argv[]); +int grub_create_loader_cmdline (int argc, char *argv[], char *buf, + grub_size_t size); + +#endif /* ! GRUB_CMDLINE_HEADER */ From 11b970d7c9e820e4d7574d0cb63ddc55cd27176e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 7 Jan 2011 17:24:25 +0000 Subject: [PATCH 0619/1414] Always initialise *relroot in grub_find_root_device_from_mountinfo, otherwise we free an uninitialised pointer if /proc is unmounted. Reported by: Scott Moser. --- grub-core/kern/emu/getroot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 373834127..a4cfaffc9 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -111,13 +111,13 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) size_t len = 0; char *ret = NULL; + if (relroot) + *relroot = NULL; + fp = fopen ("/proc/self/mountinfo", "r"); if (! fp) return NULL; /* fall through to other methods */ - if (relroot) - *relroot = NULL; - while (getline (&buf, &len, fp) > 0) { int mnt_id, parent_mnt_id; From 64d1f0412bbbfafb0bef788ad6fe13b28329e65d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 7 Jan 2011 22:42:02 +0100 Subject: [PATCH 0620/1414] * docs/grub.texi (Support automatic decompression): Update with xz decompression support. --- ChangeLog | 5 +++++ docs/grub.texi | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1ddc8741..d65e97e09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-07 Szymon Janc + + * docs/grub.texi (Support automatic decompression): Update with xz + decompression support. + 2011-01-07 Szymon Janc Improve loaders' kernel command line handling. diff --git a/docs/grub.texi b/docs/grub.texi index 54a2d8791..daf48da13 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -346,9 +346,11 @@ ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{HFS}, @dfn{HFS+}, @dfn{BSD UFS/UFS2}, and @dfn{XFS}. @xref{Filesystem}, for more information. @item Support automatic decompression -Can decompress files which were compressed by @command{gzip}. This -function is both automatic and transparent to the user (i.e. all -functions operate upon the uncompressed contents of the specified +Can decompress files which were compressed by @command{gzip} or +@command{xz}@footnote{Only CRC32 data integrity check is supported (xz default +is CRC64 so one should use --check=crc32 option). LZMA BCJ filters are +supported.}. This function is both automatic and transparent to the user +(i.e. all functions operate upon the uncompressed contents of the specified files). This greatly reduces a file size and loading time, a particularly great benefit for floppies.@footnote{There are a few pathological cases where loading a very badly organized ELF kernel might From 43f1bc8369211247259581d458a0f3aaa9782bbb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 00:27:38 +0100 Subject: [PATCH 0621/1414] * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): Silence spurious warning. Reported and tested by: Alain Greppin. --- ChangeLog | 6 ++++++ grub-core/loader/i386/bsdXX.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d65e97e09..52f59019b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-08 Vladimir Serbinenko + + * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): + Silence spurious warning. + Reported and tested by: Alain Greppin. + 2011-01-07 Szymon Janc * docs/grub.texi (Support automatic decompression): Update with xz diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index 2dd180509..5b9e7689e 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -394,7 +394,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, grub_err_t err; Elf_Ehdr e; Elf_Shdr *s, *symsh, *strsh; - char *shdr; + char *shdr = NULL; unsigned symsize, strsize; void *sym_chunk; grub_uint8_t *curload; From 0fd48e357f73864f7a334be23153e973f2f76f2a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 00:34:23 +0100 Subject: [PATCH 0622/1414] Satisfy some bison versions need for inttypes.h. * grub-core/lib/posix_wrap/inttypes.h: New file. * grub-core/lib/posix_wrap/sys/types.h (int8_t): New type. (int16_t): Likewise. (int32_t): Likewise. (int64_t): Likewise. Reported and tested by: Alain Greppin. --- ChangeLog | 11 +++++++++++ grub-core/lib/posix_wrap/inttypes.h | 1 + grub-core/lib/posix_wrap/sys/types.h | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 grub-core/lib/posix_wrap/inttypes.h diff --git a/ChangeLog b/ChangeLog index 52f59019b..1a297da01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-01-08 Vladimir Serbinenko + + Satisfy some bison versions need for inttypes.h. + + * grub-core/lib/posix_wrap/inttypes.h: New file. + * grub-core/lib/posix_wrap/sys/types.h (int8_t): New type. + (int16_t): Likewise. + (int32_t): Likewise. + (int64_t): Likewise. + Reported and tested by: Alain Greppin. + 2011-01-08 Vladimir Serbinenko * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): diff --git a/grub-core/lib/posix_wrap/inttypes.h b/grub-core/lib/posix_wrap/inttypes.h new file mode 100644 index 000000000..a12c43b15 --- /dev/null +++ b/grub-core/lib/posix_wrap/inttypes.h @@ -0,0 +1 @@ +#include diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h index 4e8331fdd..69e49509e 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h @@ -32,6 +32,11 @@ typedef grub_uint16_t uint16_t; typedef grub_uint32_t uint32_t; typedef grub_uint64_t uint64_t; +typedef grub_int8_t int8_t; +typedef grub_int16_t int16_t; +typedef grub_int32_t int32_t; +typedef grub_int64_t int64_t; + #ifdef GRUB_CPU_WORDS_BIGENDIAN #define WORDS_BIGENDIAN #else From 9462775a2df7842cf4a4c21f19e5dd1d92ef5183 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 00:39:12 +0100 Subject: [PATCH 0623/1414] * grub-core/Makefile.am (rs_decoder.S): Force compilation with -Os. Reported and tested by: Alain Greppin. --- ChangeLog | 5 +++++ grub-core/Makefile.am | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1a297da01..984c3fc5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-08 Vladimir Serbinenko + + * grub-core/Makefile.am (rs_decoder.S): Force compilation with -Os. + Reported and tested by: Alain Greppin. + 2011-01-08 Vladimir Serbinenko Satisfy some bison versions need for inttypes.h. diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 073ce37f6..fcf3fc42d 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -50,7 +50,7 @@ grub_script.yy.h: script/yylex.l grub_script.yy.c: grub_script.yy.h rs_decoder.S: $(srcdir)/lib/reed_solomon.c - $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 kern/i386/pc/startup.S: $(builddir)/rs_decoder.S From ec1dfd634e3c2f09d9e293239529c5ea784ac102 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 00:44:38 +0100 Subject: [PATCH 0624/1414] * configure.ac: Do CPU substitution even if it's specified explicitly. Reported and tested by: Alain Greppin. --- ChangeLog | 5 +++++ configure.ac | 15 ++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 984c3fc5a..5116604f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-08 Vladimir Serbinenko + + * configure.ac: Do CPU substitution even if it's specified explicitly. + Reported and tested by: Alain Greppin. + 2011-01-08 Vladimir Serbinenko * grub-core/Makefile.am (rs_decoder.S): Force compilation with -Os. diff --git a/configure.ac b/configure.ac index c013c9022..8bb585a78 100644 --- a/configure.ac +++ b/configure.ac @@ -103,15 +103,12 @@ else platform="$with_platform" fi -# Adjust CPU unless target was explicitly specified. -if test -z "$target_alias"; then - case "$target_cpu"-"$platform" in - x86_64-efi) ;; - x86_64-emu) ;; - x86_64-*) target_cpu=i386 ;; - powerpc64-ieee1275) target_cpu=powerpc ;; - esac -fi +case "$target_cpu"-"$platform" in + x86_64-efi) ;; + x86_64-emu) ;; + x86_64-*) target_cpu=i386 ;; + powerpc64-ieee1275) target_cpu=powerpc ;; +esac # Check if the platform is supported, make final adjustments. case "$target_cpu"-"$platform" in From f9f376488bc602b6c8f370c6697e0765747ac1c6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 01:45:57 +0100 Subject: [PATCH 0625/1414] =?UTF-8?q?=09*=20grub-core/term/at=5Fkeyboard.c?= =?UTF-8?q?=20(grub=5Fkeyboard=5Fgetkey):=20Silence=20spurious=20=09warnin?= =?UTF-8?q?g.=20=09Reported=20and=20tested=20by:=20Gr=C3=A9goire=20Sutre.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 6 ++++++ grub-core/term/at_keyboard.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5116604f5..4c2fd2a62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-08 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c (grub_keyboard_getkey): Silence spurious + warning. + Reported and tested by: GrĂ©goire Sutre. + 2011-01-08 Vladimir Serbinenko * configure.ac: Do CPU substitution even if it's specified explicitly. diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 5bc3f578c..55cb76483 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -494,7 +494,7 @@ static int grub_keyboard_getkey (void) { int key; - int is_break; + int is_break = 0; key = fetch_key (&is_break); if (key == -1) From fc836af9a520da52a84c74b99d06de8a3fd117b6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 01:50:06 +0100 Subject: [PATCH 0626/1414] =?UTF-8?q?=09*=20grub-core/commands/terminal.c?= =?UTF-8?q?=20(grub=5Fcmd=5Fterminal=5Finput):=20Silence=20=09aliasing=20w?= =?UTF-8?q?arning.=20=09(grub=5Fcmd=5Fterminal=5Foutput):=20Likewise.=20?= =?UTF-8?q?=09Reported=20and=20tested=20by:=20Gr=C3=A9goire=20Sutre.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 7 +++++++ grub-core/commands/terminal.c | 21 +++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c2fd2a62..7545cbef9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-08 Vladimir Serbinenko + + * grub-core/commands/terminal.c (grub_cmd_terminal_input): Silence + aliasing warning. + (grub_cmd_terminal_output): Likewise. + Reported and tested by: GrĂ©goire Sutre. + 2011-01-08 Vladimir Serbinenko * grub-core/term/at_keyboard.c (grub_keyboard_getkey): Silence spurious diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c index c8b1b6315..c2d9550f6 100644 --- a/grub-core/commands/terminal.c +++ b/grub-core/commands/terminal.c @@ -210,11 +210,11 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init); (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini); return handle_command (argc, args, - (struct abstract_terminal **) &grub_term_inputs, - (struct abstract_terminal **) &grub_term_inputs_disabled, - grub_term_input_autoload, - N_ ("Active input terminals:"), - N_ ("Available input terminals:")); + (struct abstract_terminal **) (void *) &grub_term_inputs, + (struct abstract_terminal **) (void *) &grub_term_inputs_disabled, + grub_term_input_autoload, + N_ ("Active input terminals:"), + N_ ("Available input terminals:")); } static grub_err_t @@ -225,11 +225,12 @@ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init); (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini); - return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs, - (struct abstract_terminal **) &grub_term_outputs_disabled, - grub_term_output_autoload, - N_ ("Active output terminals:"), - N_ ("Available output terminals:")); + return handle_command (argc, args, + (struct abstract_terminal **) (void *) &grub_term_outputs, + (struct abstract_terminal **) (void *) &grub_term_outputs_disabled, + grub_term_output_autoload, + N_ ("Active output terminals:"), + N_ ("Available output terminals:")); } static grub_command_t cmd_terminal_input, cmd_terminal_output; From e7121b69329ce5bff182ab85ccaf2f888a07a7b9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 01:56:09 +0100 Subject: [PATCH 0627/1414] * grub-core/fs/zfs/zfs.c (dmu_read): Use void * for some pointers to avoid aliasing. (fzap_lookup): Likewise. (dnode_get): Likewise. (make_mdn): Likewise. (zfs_mount): Likewise. (fzap_iterate): Use temporary pointer to avoid aliasing. (grub_zfs_read): Likewise. * grub-core/loader/i386/xnu.c (grub_xnu_boot): Likewise. * grub-core/loader/xnu.c (grub_cmd_xnu_kernel): Use void * for some pointers to avoid aliasing. (grub_cmd_xnu_kernel64): Likewise. (grub_xnu_load_driver): Likewise. --- ChangeLog | 16 ++++++++++++++ grub-core/fs/zfs/zfs.c | 43 +++++++++++++++++++++---------------- grub-core/loader/i386/xnu.c | 10 +++++---- grub-core/loader/xnu.c | 27 +++++++++++++---------- 4 files changed, 63 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7545cbef9..0f132cb01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-01-08 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (dmu_read): Use void * for some pointers to + avoid aliasing. + (fzap_lookup): Likewise. + (dnode_get): Likewise. + (make_mdn): Likewise. + (zfs_mount): Likewise. + (fzap_iterate): Use temporary pointer to avoid aliasing. + (grub_zfs_read): Likewise. + * grub-core/loader/i386/xnu.c (grub_xnu_boot): Likewise. + * grub-core/loader/xnu.c (grub_cmd_xnu_kernel): Use void * for some + pointers to avoid aliasing. + (grub_cmd_xnu_kernel64): Likewise. + (grub_xnu_load_driver): Likewise. + 2011-01-08 Vladimir Serbinenko * grub-core/commands/terminal.c (grub_cmd_terminal_input): Silence diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8901af76f..5b575f369 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -603,7 +603,8 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, int idx, level; blkptr_t *bp_array = dn->dn.dn_blkptr; int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT; - blkptr_t *bp, *tmpbuf = 0; + blkptr_t *bp; + void *tmpbuf = 0; grub_zfs_endian_t endian; grub_err_t err = GRUB_ERR_NONE; @@ -646,7 +647,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, break; } grub_dprintf ("zfs", "endian = %d\n", endian); - err = zio_read (bp, endian, (void **) &tmpbuf, 0, data); + err = zio_read (bp, endian, &tmpbuf, 0, data); endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; if (err) break; @@ -880,7 +881,7 @@ static grub_err_t fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, char *name, grub_uint64_t * value, struct grub_zfs_data *data) { - zap_leaf_phys_t *l; + void *l; grub_uint64_t hash, idx, blkid; int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << DNODE_SHIFT); @@ -903,7 +904,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, /* Get the leaf block */ if ((1U << blksft) < sizeof (zap_leaf_phys_t)) return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); - err = dmu_read (zap_dnode, blkid, (void **) &l, &leafendian, data); + err = dmu_read (zap_dnode, blkid, &l, &leafendian, data); if (err) return err; @@ -920,6 +921,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, struct grub_zfs_data *data) { zap_leaf_phys_t *l; + void *l_in; grub_uint64_t idx, blkid; grub_uint16_t chunk; int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, @@ -947,7 +949,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, { blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; - err = dmu_read (zap_dnode, blkid, (void **) &l, &endian, data); + err = dmu_read (zap_dnode, blkid, &l_in, &endian, data); + l = l_in; if (err) { grub_errno = GRUB_ERR_NONE; @@ -1108,7 +1111,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, grub_uint64_t blkid, blksz; /* the block id this object dnode is in */ int epbs; /* shift of number of dnodes in a block */ int idx; /* index within a block */ - dnode_phys_t *dnbuf; + void *dnbuf; grub_err_t err; grub_zfs_endian_t endian; @@ -1131,7 +1134,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian, (unsigned long long) blkid); - err = dmu_read (mdn, blkid, (void **) &dnbuf, &endian, data); + err = dmu_read (mdn, blkid, &dnbuf, &endian, data); if (err) return err; grub_dprintf ("zfs", "alive\n"); @@ -1153,7 +1156,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, data->dnode_endian = endian; } - grub_memmove (&(buf->dn), &dnbuf[idx], DNODE_SIZE); + grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE); buf->endian = endian; if (type && buf->dn.dn_type != type) return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); @@ -1465,7 +1468,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, static grub_err_t make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) { - objset_phys_t *osp; + void *osp; blkptr_t *bp; grub_size_t ospsize; grub_err_t err; @@ -1473,7 +1476,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) grub_dprintf ("zfs", "endian = %d\n", mdn->endian); bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp); - err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data); + err = zio_read (bp, mdn->endian, &osp, &ospsize, data); if (err) return err; if (ospsize < OBJSET_PHYS_SIZE_V14) @@ -1483,7 +1486,8 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) } mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1; - grub_memmove ((char *) &(mdn->dn), (char *) &osp->os_meta_dnode, DNODE_SIZE); + grub_memmove ((char *) &(mdn->dn), + (char *) &((objset_phys_t *) osp)->os_meta_dnode, DNODE_SIZE); grub_free (osp); return GRUB_ERR_NONE; } @@ -1960,7 +1964,7 @@ zfs_mount (grub_device_t dev) int label = 0; uberblock_phys_t *ub_array, *ubbest = NULL; vdev_boot_header_t *bh; - objset_phys_t *osp = 0; + void *osp = 0; grub_size_t ospsize; grub_err_t err; int vdevnum; @@ -2038,7 +2042,7 @@ zfs_mount (grub_device_t dev) ? LITTLE_ENDIAN : BIG_ENDIAN); err = zio_read (&ubbest->ubp_uberblock.ub_rootbp, ub_endian, - (void **) &osp, &ospsize, data); + &osp, &ospsize, data); if (err) { grub_dprintf ("zfs", "couldn't zio_read\n"); @@ -2067,7 +2071,8 @@ zfs_mount (grub_device_t dev) continue; #endif /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); + grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode, + DNODE_SIZE); data->mos.endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_rootbp.blk_prop, ub_endian) >> 63) & 1; grub_memmove (&(data->current_uberblock), &ubbest->ubp_uberblock, sizeof (uberblock_t)); @@ -2201,7 +2206,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) */ if (data->dnode.dn.dn_bonustype == DMU_OT_SA) { - sa_hdr_phys_t *sahdrp; + void *sahdrp; int hdrsize; if (data->dnode.dn.dn_bonuslen != 0) @@ -2212,7 +2217,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) { blkptr_t *bp = &data->dnode.dn.dn_spill; - err = zio_read (bp, data->dnode.endian, (void **) &sahdrp, NULL, data); + err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data); if (err) return err; } @@ -2221,7 +2226,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); } - hdrsize = SA_HDR_SIZE (sahdrp); + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET); } else @@ -2280,6 +2285,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) read = 0; while (length) { + void *t; /* * Find requested blkid and the offset within that block. */ @@ -2287,8 +2293,9 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) grub_free (data->file_buf); data->file_buf = 0; - err = dmu_read (&(data->dnode), blkid, (void **) &(data->file_buf), + err = dmu_read (&(data->dnode), blkid, &t, 0, data); + data->file_buf = t; if (err) return -1; diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index a9435eff3..a0df6f4aa 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -951,10 +951,11 @@ grub_err_t grub_xnu_boot (void) { struct grub_xnu_boot_params *bootparams; + void *bp_in; grub_addr_t bootparams_target; grub_err_t err; grub_efi_uintn_t memory_map_size = 0; - grub_efi_memory_descriptor_t *memory_map; + void *memory_map; grub_addr_t memory_map_target; grub_efi_uintn_t map_key = 0; grub_efi_uintn_t descriptor_size = 0; @@ -1006,9 +1007,10 @@ grub_xnu_boot (void) /* Relocate the boot parameters to heap. */ err = grub_xnu_heap_malloc (sizeof (*bootparams), - (void **) &bootparams, &bootparams_target); + &bp_in, &bootparams_target); if (err) return err; + bootparams = bp_in; /* Set video. */ err = grub_xnu_set_video (bootparams); @@ -1035,7 +1037,7 @@ grub_xnu_boot (void) memory map growth. */ memory_map_size += 20 * descriptor_size; err = grub_xnu_heap_malloc (memory_map_size, - (void **) &memory_map, &memory_map_target); + &memory_map, &memory_map_target); if (err) return err; @@ -1109,7 +1111,7 @@ grub_xnu_boot (void) grub_xnu_arg1 = bootparams_target; grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size, - descriptor_version,memory_map); + descriptor_version, memory_map); state.eip = grub_xnu_entry_point; state.eax = grub_xnu_arg1; diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 95857951a..5a84dea1c 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -342,7 +342,8 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), grub_macho_t macho; grub_uint32_t startcode, endcode; int i; - char *ptr, *loadaddr; + char *ptr; + void *loadaddr; grub_addr_t loadaddr_target; if (argc < 1) @@ -375,7 +376,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), if (!grub_xnu_relocator) return grub_errno; grub_xnu_heap_target_start = startcode; - err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr, + err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr, &loadaddr_target); if (err) @@ -386,7 +387,8 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), } /* Load kernel. */ - err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); + err = grub_macho_load32 (macho, (char *) loadaddr - startcode, + GRUB_MACHO_NOBSS); if (err) { grub_macho_close (macho); @@ -450,7 +452,8 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), grub_macho_t macho; grub_uint64_t startcode, endcode; int i; - char *ptr, *loadaddr; + char *ptr; + void *loadaddr; grub_addr_t loadaddr_target; if (argc < 1) @@ -486,7 +489,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), if (!grub_xnu_relocator) return grub_errno; grub_xnu_heap_target_start = startcode; - err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr, + err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr, &loadaddr_target); if (err) @@ -497,7 +500,8 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), } /* Load kernel. */ - err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS); + err = grub_macho_load64 (macho, (char *) loadaddr - startcode, + GRUB_MACHO_NOBSS); if (err) { grub_macho_close (macho); @@ -636,7 +640,8 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) grub_file_t infoplist; struct grub_xnu_extheader *exthead; int neededspace = sizeof (*exthead); - grub_uint8_t *buf, *buf0; + grub_uint8_t *buf; + void *buf0; grub_addr_t buf_target; grub_size_t infoplistsize = 0, machosize = 0; char *name, *nameend; @@ -692,7 +697,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); if (err) return err; - err = grub_xnu_heap_malloc (neededspace, (void **) &buf0, &buf_target); + err = grub_xnu_heap_malloc (neededspace, &buf0, &buf_target); if (err) return err; buf = buf0; @@ -704,7 +709,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) /* Load the binary. */ if (macho) { - exthead->binaryaddr = buf_target + (buf - buf0); + exthead->binaryaddr = buf_target + (buf - (grub_uint8_t *) buf0); exthead->binarysize = machosize; if (grub_xnu_is_64bit) err = grub_macho_readfile64 (macho, buf); @@ -723,7 +728,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) /* Load the plist. */ if (infoplist) { - exthead->infoplistaddr = buf_target + (buf - buf0); + exthead->infoplistaddr = buf_target + (buf - (grub_uint8_t *) buf0); exthead->infoplistsize = infoplistsize + 1; if (grub_file_read (infoplist, buf, infoplistsize) != (grub_ssize_t) (infoplistsize)) @@ -739,7 +744,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) } grub_errno = GRUB_ERR_NONE; - exthead->nameaddr = (buf - buf0) + buf_target; + exthead->nameaddr = (buf - (grub_uint8_t *) buf0) + buf_target; exthead->namesize = namelen + 1; grub_memcpy (buf, name, namelen); buf[namelen] = 0; From 4b0782664739170dc3688a55e667a56146128e78 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 16:33:49 +0100 Subject: [PATCH 0628/1414] 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 53798c4bd1ae9c635740f72207c9db5509505f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 8 Jan 2011 17:01:38 +0100 Subject: [PATCH 0629/1414] Check for libdevmapper header --- ChangeLog | 4 ++++ configure.ac | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0f132cb01..8a832d41d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-08 GrĂ©goire Sutre + + * configure.ac: Check for libdevmapper header. + 2011-01-08 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (dmu_read): Use void * for some pointers to diff --git a/configure.ac b/configure.ac index 8bb585a78..a9ca130b4 100644 --- a/configure.ac +++ b/configure.ac @@ -863,6 +863,12 @@ if test x"$enable_device_mapper" = xno ; then device_mapper_excuse="explicitly disabled" fi +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper header. + AC_CHECK_HEADER([libdevmapper.h], [], + [device_mapper_excuse="need libdevmapper header"]) +fi + if test x"$device_mapper_excuse" = x ; then # Check for device-mapper library. AC_CHECK_LIB([devmapper], [dm_task_create], [], From 92bb078645e55f116ebb253be5292cd10b6ffbb9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 19:51:08 +0100 Subject: [PATCH 0630/1414] grub-fuse --- Makefile.util.def | 15 ++ config.h.in | 4 + configure.ac | 37 ++++ docs/man/grub-fuse.h2m | 2 + util/grub-fuse.c | 455 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 513 insertions(+) create mode 100644 docs/man/grub-fuse.h2m create mode 100644 util/grub-fuse.c diff --git a/Makefile.util.def b/Makefile.util.def index 74984e2e9..369d312f6 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -212,6 +212,21 @@ program = { ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; }; +program = { + name = grub-fuse; + mansection = 1; + common_nodist = grub_fstest_init.c; + common = util/grub-fuse.c; + common = grub-core/kern/emu/hostfs.c; + common = grub-core/disk/host.c; + + ldadd = libgrubmods.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)' '-lfuse'; + condition = COND_GRUB_FUSE; +}; + program = { name = grub-mkfont; mansection = 1; diff --git a/config.h.in b/config.h.in index 6d7d95dec..3974ad7d5 100644 --- a/config.h.in +++ b/config.h.in @@ -1,3 +1,7 @@ +#undef _LARGEFILE_SOURCE +#undef _FILE_OFFSET_BITS +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) #include #define NESTED_FUNC_ATTR diff --git a/configure.ac b/configure.ac index 8bb585a78..e9e31e7fb 100644 --- a/configure.ac +++ b/configure.ac @@ -856,6 +856,37 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) +AC_ARG_ENABLE([grub-mkfont], + [AS_HELP_STRING([--enable-grub-mkfont], + [build and install the `grub-mkfont' utility (default=guessed)])]) +if test x"$enable_grub_mkfont" = xno ; then + grub_mkfont_excuse="explicitly disabled" +fi + +if test x"$grub_fuse_excuse" = x ; then + AC_CHECK_LIB([fuse], [fuse_main_real], [], + [grub_fuse_excuse="need FUSE library"]) +fi + +if test x"$grub_fuse_excuse" = x ; then + # Check for fuse headers. + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" + AC_CHECK_HEADERS([fuse/fuse.h], [], + [grub_fuse_excuse=["need FUSE headers"]]) + CPPFLAGS="$SAVED_CPPFLAGS" +fi + +if test x"$enable_grub_fuse" = xyes && test x"$grub_fuse_excuse" != x ; then + AC_MSG_ERROR([grub-fuse was explicitly requested but can't be compiled]) +fi +if test x"$grub_fuse_excuse" = x ; then +enable_grub_fuse=yes +else +enable_grub_fuse=no +fi +AC_SUBST([enable_grub_fuse]) + AC_ARG_ENABLE([device-mapper], [AS_HELP_STRING([--enable-device-mapper], [enable Linux device-mapper support (default=guessed)])]) @@ -952,6 +983,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) +AM_CONDITIONAL([COND_GRUB_FUSE], [test x$enable_grub_fuse = xyes]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) @@ -1027,5 +1059,10 @@ echo grub-mkfont: Yes else echo grub-mkfont: No "($grub_mkfont_excuse)" fi +if [ x"$grub_fuse_excuse" = x ]; then +echo grub-fuse: Yes +else +echo grub-fuse: No "($grub_fuse_excuse)" +fi echo "*******************************************************" ] diff --git a/docs/man/grub-fuse.h2m b/docs/man/grub-fuse.h2m new file mode 100644 index 000000000..0e234ddc1 --- /dev/null +++ b/docs/man/grub-fuse.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-fuse \- export GRUB filesystem with FUSE. diff --git a/util/grub-fuse.c b/util/grub-fuse.c new file mode 100644 index 000000000..7f0ad0d0f --- /dev/null +++ b/util/grub-fuse.c @@ -0,0 +1,455 @@ +/* grub-fstest.c - debug tool for filesystem driver */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 FUSE_USE_VERSION 26 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "progname.h" +#include "argp.h" + +static char *root = NULL; +static char **images = NULL; +static char *debug_str = NULL; +static char **fuse_args = NULL; +static int fuse_argc = 0; +static int num_disks = 0; + +static grub_err_t +execute_command (char *name, int n, char **args) +{ + grub_command_t cmd; + + cmd = grub_command_find (name); + if (! cmd) + grub_util_error (_("can\'t find command %s"), name); + + return (cmd->func) (cmd, n, args); +} + +static int +fuse_getattr (const char *path, struct stat *st) +{ + char *filename, *pathname, *path2; + const char *pathname_t; + grub_fs_t fs; + grub_device_t dev; + struct grub_dirhook_info file_info; + int file_exists = 0; + + /* A hook for iterating directories. */ + auto int find_file (const char *cur_filename, + const struct grub_dirhook_info *info); + int find_file (const char *cur_filename, + const struct grub_dirhook_info *info) + { + if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename) + : grub_strcmp (cur_filename, filename)) == 0) + { + file_info = *info; + file_exists = 1; + return 1; + } + return 0; + } + + if (path[0] == '/' && path[1] == 0) + { + st->st_dev = 0; + st->st_ino = 0; + st->st_mode = 0555 | S_IFDIR; + st->st_uid = 0; + st->st_gid = 0; + st->st_rdev = 0; + st->st_size = 0; + st->st_blksize = 512; + st->st_blocks = (st->st_blksize + 511) >> 9; + st->st_atime = st->st_mtime = st->st_ctime = 0; + return 0; + } + + file_exists = 0; + dev = grub_device_open (0); + if (! dev) + return -1; + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_device_close (dev); + return -1; + } + + pathname_t = grub_strchr (path, ')'); + if (! pathname_t) + pathname_t = path; + else + pathname_t++; + pathname = xstrdup (pathname_t); + + /* Remove trailing '/'. */ + while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') + pathname[grub_strlen (pathname) - 1] = 0; + + /* Split into path and filename. */ + filename = grub_strrchr (pathname, '/'); + if (! filename) + { + path2 = grub_strdup ("/"); + filename = pathname; + } + else + { + filename++; + path2 = grub_strdup (pathname); + path2[filename - pathname] = 0; + } + + /* It's the whole device. */ + (fs->dir) (dev, path2, find_file); + + grub_device_close (dev); + grub_free (path2); + if (!file_exists) + return -1; + st->st_dev = 0; + st->st_ino = 0; + st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); + st->st_uid = 0; + st->st_gid = 0; + st->st_rdev = 0; + if (!file_info.dir) + { + grub_file_t file; + file = grub_file_open (path); + if (! file) + { + grub_print_error (); + return -1; + } + st->st_size = file->size; + grub_file_close (file); + } + else + st->st_size = 0; + st->st_blksize = 512; + st->st_blocks = (st->st_size + 511) >> 9; + st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset + ? file_info.mtime : 0; + return 0; +} + +static int +fuse_opendir (const char *path, struct fuse_file_info *fi) +{ + return 0; +} + +/* FIXME */ +static grub_file_t files[65536]; +static int first_fd = 1; + +static int +fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused))) +{ + grub_file_t file; + file = grub_file_open (path); + if (! file) + { + grub_print_error (); + return -1; + } + files[first_fd++] = file; + fi->fh = first_fd; + files[first_fd++] = file; + return 0; +} + +static int +fuse_read (const char *path, char *buf, size_t sz, off_t off, + struct fuse_file_info *fi) +{ + grub_file_t file = files[fi->fh]; + + if (off > file->size) + return -1; + + file->offset = off; + + return grub_file_read (file, buf, sz); +} + +static int +fuse_release (const char *path, struct fuse_file_info *fi) +{ + grub_file_close (files[fi->fh]); + files[fi->fh] = NULL; + return 0; +} + +static int +fuse_readdir (const char *path, void *buf, + fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) +{ + char *pathname; + grub_fs_t fs; + grub_device_t dev; + + auto int call_fill (const char *filename, + const struct grub_dirhook_info *info); + int call_fill (const char *filename, const struct grub_dirhook_info *info) + { + fill (buf, filename, NULL, 0); + return 0; + } + + dev = grub_device_open (0); + if (! dev) + { + return 1; + } + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_device_close (dev); + return 1; + } + + pathname = xstrdup (path); + + /* Remove trailing '/'. */ + while (pathname [0] && pathname[1] + && pathname[grub_strlen (pathname) - 1] == '/') + pathname[grub_strlen (pathname) - 1] = 0; + + (fs->dir) (dev, pathname, call_fill); + grub_device_close (dev); + free (pathname); + return 0; +} + +struct fuse_operations grub_opers = { + .getattr = fuse_getattr, + .open = fuse_open, + .release = fuse_release, + .opendir = fuse_opendir, + .readdir = fuse_readdir, + .read = fuse_read +}; + +static void +fuse_init (void) +{ + int i; + + for (i = 0; i < num_disks; i++) + { + char *argv[2]; + char *host_file; + char *loop_name; + loop_name = grub_xasprintf ("loop%d", i); + if (!loop_name) + grub_util_error (grub_errmsg); + + host_file = grub_xasprintf ("(host)%s", images[i]); + if (!host_file) + grub_util_error (grub_errmsg); + + argv[0] = loop_name; + argv[1] = host_file; + + if (execute_command ("loopback", 2, argv)) + grub_util_error (_("loopback command fails")); + + grub_free (loop_name); + grub_free (host_file); + } + + grub_lvm_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); + grub_raid_fini (); + grub_raid_init (); + grub_mdraid09_init (); + grub_mdraid1x_init (); + grub_lvm_init (); + + fuse_main (fuse_argc, fuse_args, &grub_opers, NULL); + + for (i = 0; i < num_disks; i++) + { + char *argv[2]; + char *loop_name; + + loop_name = grub_xasprintf ("loop%d", i); + if (!loop_name) + grub_util_error (grub_errmsg); + + argv[0] = "-d"; + argv[1] = loop_name; + + execute_command ("loopback", 2, argv); + + grub_free (loop_name); + } +} + +static struct argp_option options[] = { + {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, + {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, + {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, + {0, 0, 0, 0, 0, 0} +}; + +/* Print the version information. */ +static void +print_version (FILE *stream, struct argp_state *state) +{ + fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); +} +void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; + +error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + char *p; + + switch (key) + { + case 'r': + root = arg; + return 0; + + case 'd': + debug_str = arg; + return 0; + + case 'v': + verbosity++; + return 0; + + case ARGP_KEY_ARG: + if (arg[0] != '-') + break; + + default: + if (!arg) + return 0; + + fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0])); + fuse_args[fuse_argc] = xstrdup (arg); + fuse_argc++; + return 0; + } + + if (arg[0] != '/') + { + fprintf (stderr, "%s", _("Must use absolute path.\n")); + argp_usage (state); + } + images = xrealloc (images, (num_disks + 1) * sizeof (images[0])); + images[num_disks] = xstrdup (arg); + num_disks++; + + return 0; +} + +struct argp argp = { + options, argp_parser, N_("IMAGE1 [IMAGE2 ...] MOUNTPOINT"), + N_("Debug tool for filesystem driver."), + NULL, NULL, NULL +}; + +int +main (int argc, char *argv[]) +{ + char *default_root, *alloc_root; + + set_program_name (argv[0]); + + grub_util_init_nls (); + + fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0])); + fuse_args[fuse_argc] = xstrdup (argv[0]); + fuse_argc++; + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (num_disks < 2) + grub_util_error ("need an image and mountpoint"); + fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); + fuse_args[fuse_argc] = images[num_disks - 1]; + fuse_argc++; + num_disks--; + fuse_args[fuse_argc] = NULL; + + /* Initialize all modules. */ + grub_init_all (); + + if (debug_str) + grub_env_set ("debug", debug_str); + + default_root = (num_disks == 1) ? "loop0" : "md0"; + alloc_root = 0; + if (root) + { + if ((*root >= '0') && (*root <= '9')) + { + alloc_root = xmalloc (strlen (default_root) + strlen (root) + 2); + + sprintf (alloc_root, "%s,%s", default_root, root); + root = alloc_root; + } + } + else + root = default_root; + + grub_env_set ("root", root); + + if (alloc_root) + free (alloc_root); + + /* Do it. */ + fuse_init (); + + /* Free resources. */ + grub_fini_all (); + + return 0; +} From c88172fa92efe15950247491db154c01a58df074 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 8 Jan 2011 20:22:32 +0100 Subject: [PATCH 0631/1414] * config.h.in (_LARGEFILE_SOURCE): Add missing define. (_FILE_OFFSET_BITS): Likewise. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ config.h.in | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8a832d41d..30dd4798f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-08 Vladimir Serbinenko + + * config.h.in (_LARGEFILE_SOURCE): Add missing define. + (_FILE_OFFSET_BITS): Likewise. + Reported by: Seth Goldberg. + 2011-01-08 GrĂ©goire Sutre * configure.ac: Check for libdevmapper header. diff --git a/config.h.in b/config.h.in index 6d7d95dec..3974ad7d5 100644 --- a/config.h.in +++ b/config.h.in @@ -1,3 +1,7 @@ +#undef _LARGEFILE_SOURCE +#undef _FILE_OFFSET_BITS +#define _LARGEFILE_SOURCE +#define _FILE_OFFSET_BITS 64 #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) #include #define NESTED_FUNC_ATTR From a21e5672fd8edd1f7ab17204396fb436dba0c2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sun, 9 Jan 2011 23:23:25 +0100 Subject: [PATCH 0632/1414] Handle openbsd and netbsd types being in part_bsd module. --- ChangeLog | 5 +++++ util/grub-mkconfig_lib.in | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 30dd4798f..723df8522 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-09 GrĂ©goire Sutre + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Handle + openbsd and netbsd types being in part_bsd module. + 2011-01-08 Vladimir Serbinenko * config.h.in (_LARGEFILE_SOURCE): Add missing define. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index ec4084698..2a48fb260 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -107,7 +107,12 @@ prepare_grub_to_access_device () partmap="`${grub_probe} --device ${device} --target=partmap`" for module in ${partmap} ; do - echo "insmod part_${module}" + case "${module}" in + netbsd | openbsd) + echo "insmod part_bsd";; + *) + echo "insmod part_${module}";; + esac done fs="`${grub_probe} --device ${device} --target=fs`" From 1f060f399a5eebbb50f0e3aa41e734de09380aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 10 Jan 2011 01:08:40 +0100 Subject: [PATCH 0633/1414] Teach grub-mkconfig to load fs modules for NetBSD. --- ChangeLog | 5 ++++ util/grub.d/10_netbsd.in | 62 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 723df8522..e215db3bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-09 GrĂ©goire Sutre + + * util/grub.d/10_netbsd.in (netbsd_load_fs_module): New function. + (netbsd_entry): Use netbsd_load_fs_module() to load filesystem module. + 2011-01-09 GrĂ©goire Sutre * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Handle diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index 13f9d923a..ffd31ad93 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -27,11 +27,65 @@ export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then - OS=NetBSD + OS="NetBSD" else OS="${GRUB_DISTRIBUTOR} NetBSD" fi +netbsd_load_fs_module () +{ + loader="$1" # "knetbsd" or "multiboot" + kernel="$2" # absolute path to the kernel file + + case $(zcat -f "${kernel}" | file -bL - | cut -d , -f 2 | tr -d ' ') in + Intel80386) + karch="i386" + ;; + x86-64) + karch="amd64" + ;; + *) + return + ;; + esac + + case $(${grub_probe} --target=fs -d ${GRUB_DEVICE}) in + ext2) + kmod="ext2fs" + ;; + fat) + kmod="msdosfs" + ;; + ntfs) + kmod="ntfs" + ;; + ufs*) + kmod="ffs" + ;; + *) + return + ;; + esac + + kversion=$(zcat -f "${kernel}" | strings | sed -n -e '/^@(#)NetBSD/ { s/^@(#)NetBSD \([0-9\.]*\) .*$/\1/g ; p ; q ; }') + kmodule="/stand/${karch}/${kversion}/modules/${kmod}/${kmod}.kmod" + + if test -z "$karch" -o -z "$kversion" -o ! -f "${kmodule}"; then + return + fi + + kmodule_rel=$(make_system_path_relative_to_its_root "$kmodule") || return + prepare_grub_to_access_device $(${grub_probe} -t device "${kmodule}") | sed -e 's,^, ,' + case "${loader}" in + knetbsd) + printf "\tknetbsd_module_elf %s\n" "${kmodule_rel}" + ;; + multiboot) + printf "\tmodule %s\n" "${kmodule_rel}" + ;; + esac +} + netbsd_entry () { loader="$1" # "knetbsd" or "multiboot" @@ -59,6 +113,9 @@ netbsd_entry () "${kernel}" "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" ;; esac + + netbsd_load_fs_module "${loader}" "${kernel}" + printf "}\n" } @@ -72,8 +129,7 @@ for k in $(ls -t /netbsd*) ; do if ! grub_file_is_not_garbage "$k" ; then continue fi - if ! ((file -bL "$k" | grep -q "${pattern}") || - (zcat "$k" | file -bL - | grep -q "${pattern}")) 2>/dev/null ; then + if ! (zcat -f "$k" | file -bL - | grep -q "${pattern}") 2>/dev/null ; then continue fi From cf0eaf13a102d71b8f7d56af8b1d00a623903d0e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 17:28:29 +0100 Subject: [PATCH 0634/1414] * grub-core/disk/raid.c (insert_array): Display RAID name in duplicate members errors. --- ChangeLog | 5 +++++ grub-core/disk/raid.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e215db3bd..85495e8ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-10 Vladimir Serbinenko + + * grub-core/disk/raid.c (insert_array): Display RAID name in duplicate + members errors. + 2011-01-09 GrĂ©goire Sutre * util/grub.d/10_netbsd.in (netbsd_load_fs_module): New function. diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index edc2b195d..c789fea50 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -530,8 +530,8 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, /* We found multiple devices with the same number. Again, this shouldn't happen. */ return grub_error (GRUB_ERR_BAD_DEVICE, - "found two disks with the number %d", - new_array->number); + "found two disks with the index %d for RAID %s", + new_array->index, array->name); if (new_array->disk_size < array->disk_size) array->disk_size = new_array->disk_size; From b1969b304927c0fcd7ad812d97e564ddf3216476 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 17:35:32 +0100 Subject: [PATCH 0635/1414] * grub-core/fs/btrfs.c (grub_btrfs_mount): Transform out of range into badfs. Reported by: TiCPU. --- ChangeLog | 6 ++++++ grub-core/fs/btrfs.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 85495e8ad..12927d0f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-10 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_mount): Transform out of range into + badfs. + Reported by: TiCPU. + 2011-01-10 Vladimir Serbinenko * grub-core/disk/raid.c (insert_array): Display RAID name in duplicate diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index a2ee485b4..179891da8 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -60,6 +60,9 @@ grub_btrfs_mount (grub_disk_t disk) return data; fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); + grub_free (data); return NULL; } From c49849cc63560d02e042eda337135dbcf72a92fa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 17:51:06 +0100 Subject: [PATCH 0636/1414] * grub-core/kern/i386/pc/mmap.c (grub_get_conv_memsize): New function. (grub_machine_mmap_iterate): Take low memory into account --- ChangeLog | 5 +++++ grub-core/kern/i386/pc/mmap.c | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 12927d0f2..34703b81d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-10 Vladimir Serbinenko + + * grub-core/kern/i386/pc/mmap.c (grub_get_conv_memsize): New function. + (grub_machine_mmap_iterate): Take low memory into account + 2011-01-10 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_mount): Transform out of range into diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c index a305d4511..480ffa949 100644 --- a/grub-core/kern/i386/pc/mmap.c +++ b/grub-core/kern/i386/pc/mmap.c @@ -36,6 +36,22 @@ struct grub_machine_mmap_entry } __attribute__((packed)); +/* + * + * grub_get_conv_memsize(i) : return the conventional memory size in KB. + * BIOS call "INT 12H" to get conventional memory size + * The return value in AX. + */ +static inline grub_uint16_t +grub_get_conv_memsize (void) +{ + struct grub_bios_int_registers regs; + + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x12, ®s); + return regs.eax & 0xffff; +} + /* * grub_get_ext_memsize() : return the extended memory size in KB. * BIOS call "INT 15H, AH=88H" to get extended memory size @@ -155,6 +171,10 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) { grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); + if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10, + GRUB_MEMORY_AVAILABLE)) + return 0; + if (eisa_mmap) { if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, @@ -162,7 +182,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE); } else - hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MEMORY_AVAILABLE); + hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10, + GRUB_MEMORY_AVAILABLE); } return 0; From db87be2aeab310b4740c0a6c556f667d43dd342e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 17:54:21 +0100 Subject: [PATCH 0637/1414] * grub-core/kern/i386/pc/init.c (grub_get_conv_memsize): Removed. (grub_machine_init): Don't check amount of low memory as reportedly INT 12h can be broken and if low memory is too low we wouldn't have gotten into grub_machine_init anyway. --- ChangeLog | 7 +++++++ grub-core/kern/i386/pc/init.c | 23 +++++++---------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34703b81d..a1d948151 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-10 Vladimir Serbinenko + + * grub-core/kern/i386/pc/init.c (grub_get_conv_memsize): Removed. + (grub_machine_init): Don't check amount of low memory as reportedly + INT 12h can be broken and if low memory is too low we wouldn't have + gotten into grub_machine_init anyway. + 2011-01-10 Vladimir Serbinenko * grub-core/kern/i386/pc/mmap.c (grub_get_conv_memsize): New function. diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 122c2c556..d8c337bde 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -140,36 +140,27 @@ compact_mem_regions (void) } } -/* - * - * grub_get_conv_memsize(i) : return the conventional memory size in KB. - * BIOS call "INT 12H" to get conventional memory size - * The return value in AX. - */ -static inline grub_uint16_t -grub_get_conv_memsize (void) -{ - struct grub_bios_int_registers regs; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x12, ®s); - return regs.eax & 0xffff; -} - void grub_machine_init (void) { int i; +#if 0 int grub_lower_mem; +#endif /* Initialize the console as early as possible. */ grub_console_init (); + /* This sanity check is useless since top of GRUB_MEMORY_MACHINE_RESERVED_END + is used for stack and if it's unavailable we wouldn't have gotten so far. + */ +#if 0 grub_lower_mem = grub_get_conv_memsize () << 10; /* Sanity check. */ if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END) grub_fatal ("too small memory"); +#endif /* FIXME: This prevents loader/i386/linux.c from using low memory. When our heap implements support for requesting a chunk in low memory, this should From ce6bb3ee31b651a09cd513cf8af5fb3b142bb82c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 19:20:50 +0100 Subject: [PATCH 0638/1414] * util/grub-menulst2cfg.c (main): Trim the line. --- ChangeLog | 4 ++++ util/grub-menulst2cfg.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a1d948151..64f9a5be9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-10 Vladimir Serbinenko + + * util/grub-menulst2cfg.c (main): Trim the line. + 2011-01-10 Vladimir Serbinenko * grub-core/kern/i386/pc/init.c (grub_get_conv_memsize): Removed. diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index e29c6b17c..da1c289a8 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -78,9 +78,12 @@ main (int argc, char **argv) { char *oldname = NULL; char *newsuffix; + char *ptr; + + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname, &newsuffix); + parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); if (newsuffix) { suffixlen += strlen (newsuffix); From 47a77af5e8f03eed1edb60f81ab7764d54ab515a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 19:25:00 +0100 Subject: [PATCH 0639/1414] * grub-core/commands/legacycfg.c (legacy_file): Trim the line. --- ChangeLog | 4 ++++ grub-core/commands/legacycfg.c | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 64f9a5be9..6461f79f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-10 Vladimir Serbinenko + + * grub-core/commands/legacycfg.c (legacy_file): Trim the line. + 2011-01-10 Vladimir Serbinenko * util/grub-menulst2cfg.c (main): Trim the line. diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index de392ac81..71ac5c620 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -83,9 +83,13 @@ legacy_file (const char *filename) { char *oldname = NULL; char *newsuffix; + char *ptr; + + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); oldname = entryname; - parsed = grub_legacy_parse (buf, &entryname, &newsuffix); + parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); + grub_free (buf); buf = NULL; if (newsuffix) { From 6fef99b4e4121ccd3bf9208c13faa6433a51453f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 19:52:12 +0100 Subject: [PATCH 0640/1414] * util/grub-mklayout.c (usage): Update help text. --- ChangeLog | 4 ++++ util/grub-mklayout.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6461f79f4..d856bbff2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-10 Vladimir Serbinenko + + * util/grub-mklayout.c (usage): Update help text. + 2011-01-10 Vladimir Serbinenko * grub-core/commands/legacycfg.c (legacy_file): Trim the line. diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index e90d955ff..36f6e04fc 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -259,8 +259,9 @@ usage (int status) fprintf (stderr, "Try `%s --help' for more information.\n", program_name); else printf ("\ -Usage: %s [OPTIONS] LAYOUT\n\ - -o, --output set output base name file. Default is LAYOUT.gkb\n\ +Usage: %s [OPTIONS]\n\ + -i, --input set input filename. Default is STDIN\n\ + -o, --output set output filename. Default is STDOUT\n\ -h, --help display this message and exit.\n\ -V, --version print version information and exit.\n\ -v, --verbose print verbose messages.\n\ From dcb883b1623c730190357ad8803f88e592b6d364 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 23:27:58 +0100 Subject: [PATCH 0641/1414] Submenu default support. * grub-core/normal/menu.c (grub_menu_execute_entry): New parameter auto_boot. All users updated. Declared static. Handle chosen and default with submenus. (grub_menu_execute_with_fallback): Declared static. Don't notify failure if autobooted. Upper level does it. (menuentry_eq): New function. (get_entry_number): Use menuentry_eq. (show_menu): New parameter "autobooted". All users updated. (grub_show_menu): Likewise. * include/grub/normal.h (grub_show_menu): Likewise. * include/grub/menu.h (grub_menu_execute_entry): Removed. (grub_menu_execute_with_fallback): Likewise. --- ChangeLog | 18 +++++ grub-core/commands/legacycfg.c | 2 +- grub-core/normal/main.c | 2 +- grub-core/normal/menu.c | 130 +++++++++++++++++++++++++++++---- grub-core/normal/menu_entry.c | 2 +- include/grub/menu.h | 5 -- include/grub/normal.h | 2 +- 7 files changed, 137 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index d856bbff2..976c2cf5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2011-01-10 Vladimir Serbinenko + + Submenu default support. + + * grub-core/normal/menu.c (grub_menu_execute_entry): New parameter + auto_boot. All users updated. + Declared static. + Handle chosen and default with submenus. + (grub_menu_execute_with_fallback): Declared static. + Don't notify failure if autobooted. Upper level does it. + (menuentry_eq): New function. + (get_entry_number): Use menuentry_eq. + (show_menu): New parameter "autobooted". All users updated. + (grub_show_menu): Likewise. + * include/grub/normal.h (grub_show_menu): Likewise. + * include/grub/menu.h (grub_menu_execute_entry): Removed. + (grub_menu_execute_with_fallback): Likewise. + 2011-01-10 Vladimir Serbinenko * util/grub-mklayout.c (usage): Update help text. diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 71ac5c620..23c1c1908 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -213,7 +213,7 @@ grub_cmd_legacy_source (struct grub_command *cmd, grub_menu_t menu; menu = grub_env_get_menu (); if (menu && menu->size) - grub_show_menu (menu, 1); + grub_show_menu (menu, 1, 0); if (!extractor) grub_env_context_close (); } diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 3bfbbeb72..69bf5e6b5 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -287,7 +287,7 @@ grub_normal_execute (const char *config, int nested, int batch) { if (menu && menu->size) { - grub_show_menu (menu, nested); + grub_show_menu (menu, nested, 0); if (nested) grub_normal_free_menu (menu); } diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 807ad51e0..6a123a6de 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -154,12 +154,15 @@ get_and_remove_first_entry_number (const char *name) } /* Run a menu entry. */ -void -grub_menu_execute_entry(grub_menu_entry_t entry) +static void +grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) { grub_err_t err = GRUB_ERR_NONE; int errs_before; grub_menu_t menu; + char *optr, *buf, *oldchosen = NULL, *olddefault = NULL; + const char *ptr, *chosen, *def; + grub_size_t sz = 0; if (entry->restricted) err = grub_auth_check_authentication (entry->users); @@ -173,6 +176,9 @@ grub_menu_execute_entry(grub_menu_entry_t entry) errs_before = grub_err_printed_errors; + chosen = grub_env_get ("chosen"); + def = grub_env_get ("default"); + if (entry->submenu) { grub_env_context_open (); @@ -180,9 +186,64 @@ grub_menu_execute_entry(grub_menu_entry_t entry) if (! menu) return; grub_env_set_menu (menu); + if (auto_boot) + grub_env_set ("timeout", "0"); } - grub_env_set ("chosen", entry->title); + for (ptr = entry->title; *ptr; ptr++) + sz += (*ptr == '>') ? 2 : 1; + if (chosen) + { + oldchosen = grub_strdup (chosen); + if (!oldchosen) + grub_print_error (); + } + if (def) + { + olddefault = grub_strdup (def); + if (!olddefault) + grub_print_error (); + } + sz++; + if (chosen) + sz += grub_strlen (chosen); + sz++; + buf = grub_malloc (sz); + if (!buf) + grub_print_error (); + else + { + optr = buf; + if (chosen) + { + optr = grub_stpcpy (optr, chosen); + *optr++ = '>'; + } + for (ptr = entry->title; *ptr; ptr++) + { + if (*ptr == '>') + *optr++ = '>'; + *optr++ = *ptr; + } + *optr = 0; + grub_env_set ("chosen", buf); + grub_env_export ("chosen"); + grub_free (buf); + } + for (ptr = def; *ptr; ptr++) + { + if (ptr[0] == '>' && ptr[1] == '>') + { + ptr++; + continue; + } + if (ptr[0] == '>') + break; + } + if (ptr[0] && ptr[1]) + grub_env_set ("default", ptr + 1); + else + grub_env_unset ("default"); grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args); if (errs_before != grub_err_printed_errors) @@ -196,20 +257,30 @@ grub_menu_execute_entry(grub_menu_entry_t entry) { if (menu && menu->size) { - grub_show_menu (menu, 1); + grub_show_menu (menu, 1, auto_boot); grub_normal_free_menu (menu); } grub_env_context_close (); } + if (oldchosen) + grub_env_set ("chosen", oldchosen); + else + grub_env_unset ("chosen"); + if (olddefault) + grub_env_set ("default", olddefault); + else + grub_env_unset ("default"); + grub_env_unset ("timeout"); } /* Execute ENTRY from the menu MENU, falling back to entries specified in the environment variable "fallback" if it fails. CALLBACK is a pointer to a struct of function pointers which are used to allow the caller provide feedback to the user. */ -void +static void grub_menu_execute_with_fallback (grub_menu_t menu, grub_menu_entry_t entry, + int autobooted, grub_menu_execute_callback_t callback, void *callback_data) { @@ -217,7 +288,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu, callback->notify_booting (entry, callback_data); - grub_menu_execute_entry (entry); + grub_menu_execute_entry (entry, 1); /* Deal with fallback entries. */ while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) @@ -228,14 +299,15 @@ grub_menu_execute_with_fallback (grub_menu_t menu, entry = grub_menu_get_entry (menu, fallback_entry); callback->notify_fallback (entry, callback_data); - grub_menu_execute_entry (entry); + grub_menu_execute_entry (entry, 1); /* If the function call to execute the entry returns at all, then this is taken to indicate a boot failure. For menu entries that do something other than actually boot an operating system, this could assume incorrectly that something failed. */ } - callback->notify_failure (callback_data); + if (!autobooted) + callback->notify_failure (callback_data); } static struct grub_menu_viewer *viewers; @@ -309,11 +381,35 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer) viewers = viewer; } +static int +menuentry_eq (const char *title, const char *spec) +{ + const char *ptr1, *ptr2; + ptr1 = title; + ptr2 = spec; + while (1) + { + if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) + return 1; + if (*ptr2 == '>' && ptr2[1] != '>') + return 0; + if (*ptr2 == '>') + ptr2++; + if (*ptr1 != *ptr2) + return 0; + if (*ptr1 == 0) + return 1; + ptr1++; + ptr2++; + } +} + + /* Get the entry number from the variable NAME. */ static int get_entry_number (grub_menu_t menu, const char *name) { - char *val; + const char *val; int entry; val = grub_env_get (name); @@ -334,7 +430,7 @@ get_entry_number (grub_menu_t menu, const char *name) for (i = 0; e; i++) { - if (grub_strcmp (e->title, val) == 0) + if (menuentry_eq (e->title, val)) { entry = i; break; @@ -590,7 +686,7 @@ static struct grub_menu_execute_callback execution_callback = }; static grub_err_t -show_menu (grub_menu_t menu, int nested) +show_menu (grub_menu_t menu, int nested, int autobooted) { while (1) { @@ -609,22 +705,26 @@ show_menu (grub_menu_t menu, int nested) grub_cls (); if (auto_boot) - grub_menu_execute_with_fallback (menu, e, &execution_callback, 0); + grub_menu_execute_with_fallback (menu, e, autobooted, + &execution_callback, 0); else - grub_menu_execute_entry (e); + grub_menu_execute_entry (e, 0); + if (autobooted) + break; } return GRUB_ERR_NONE; } grub_err_t -grub_show_menu (grub_menu_t menu, int nested) +grub_show_menu (grub_menu_t menu, int nested, int autoboot) { grub_err_t err1, err2; while (1) { - err1 = show_menu (menu, nested); + err1 = show_menu (menu, nested, autoboot); + autoboot = 0; grub_print_error (); if (grub_normal_exit_level) diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 4db4a45c1..e744d8d69 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1227,7 +1227,7 @@ run (struct screen *screen) { if (menu && menu->size) { - grub_show_menu (menu, 1); + grub_show_menu (menu, 1, 0); grub_normal_free_menu (menu); } grub_env_context_close (); diff --git a/include/grub/menu.h b/include/grub/menu.h index 5ff356beb..1f23a2363 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -94,11 +94,6 @@ typedef struct grub_menu_execute_callback grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no); int grub_menu_get_timeout (void); void grub_menu_set_timeout (int timeout); -void grub_menu_execute_entry (grub_menu_entry_t entry); -void grub_menu_execute_with_fallback (grub_menu_t menu, - grub_menu_entry_t entry, - grub_menu_execute_callback_t callback, - void *callback_data); void grub_menu_entry_run (grub_menu_entry_t entry); int grub_menu_get_default_entry_index (grub_menu_t menu); diff --git a/include/grub/normal.h b/include/grub/normal.h index 187567797..3b99e073a 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -89,7 +89,7 @@ void grub_print_message_indented (const char *msg, int margin_left, void grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested); grub_err_t -grub_show_menu (grub_menu_t menu, int nested); +grub_show_menu (grub_menu_t menu, int nested, int autobooted); /* Defined in `handler.c'. */ void read_handler_list (void); From a508e7764271aa8abcb4c93a799eec64326806e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 23:31:27 +0100 Subject: [PATCH 0642/1414] * util/grub-kbdcomp.in: Add missing transform and bindir variables. Reported by: nebuchadnezzar. --- ChangeLog | 5 +++++ util/grub-kbdcomp.in | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 976c2cf5b..eff9002cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-10 Vladimir Serbinenko + + * util/grub-kbdcomp.in: Add missing transform and bindir variables. + Reported by: nebuchadnezzar. + 2011-01-10 Vladimir Serbinenko Submenu default support. diff --git a/util/grub-kbdcomp.in b/util/grub-kbdcomp.in index 87b24bcdf..b7e706c24 100644 --- a/util/grub-kbdcomp.in +++ b/util/grub-kbdcomp.in @@ -1,5 +1,9 @@ #!/bin/sh +transform="@program_transform_name@" + +bindir="@bindir@" + grub_mklayout=${bindir}/`echo grub-mklayout | sed ${transform}` ckbcomp "$@" | $grub_mklayout -o "$1".gkb From d570097a04f3249274d1d588d51b1fffa8aa6513 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 23:41:58 +0100 Subject: [PATCH 0643/1414] * util/grub-kbdcomp.in: Add missing prefix and exec_prefix variables. Reported by: nebuchadnezzar. --- ChangeLog | 5 +++++ util/grub-kbdcomp.in | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index eff9002cf..5ef4b1c95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-10 Vladimir Serbinenko + + * util/grub-kbdcomp.in: Add missing prefix and exec_prefix variables. + Reported by: nebuchadnezzar. + 2011-01-10 Vladimir Serbinenko * util/grub-kbdcomp.in: Add missing transform and bindir variables. diff --git a/util/grub-kbdcomp.in b/util/grub-kbdcomp.in index b7e706c24..05e516d23 100644 --- a/util/grub-kbdcomp.in +++ b/util/grub-kbdcomp.in @@ -2,6 +2,8 @@ transform="@program_transform_name@" +prefix="@prefix@" +exec_prefix="@exec_prefix@" bindir="@bindir@" grub_mklayout=${bindir}/`echo grub-mklayout | sed ${transform}` From ae67942e7819481499fbc9710781b5eacaf445b3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 23:51:10 +0100 Subject: [PATCH 0644/1414] Don't use post-4G memory on EFI even if 64-bit since some non-compliant implementations bug on them. * grub-core/kern/efi/mm.c (grub_efi_allocate_pages): Skip post-4G memory. (filter_memory_map): Likewise. --- ChangeLog | 9 +++++++++ grub-core/kern/efi/mm.c | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ef4b1c95..0b9b9b6aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-01-10 Vladimir Serbinenko + + Don't use post-4G memory on EFI even if 64-bit since some non-compliant + implementations bug on them. + + * grub-core/kern/efi/mm.c (grub_efi_allocate_pages): Skip post-4G + memory. + (filter_memory_map): Likewise. + 2011-01-10 Vladimir Serbinenko * util/grub-kbdcomp.in: Add missing prefix and exec_prefix variables. diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index a715da076..8b9e6ec25 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -52,13 +52,13 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address, grub_efi_status_t status; grub_efi_boot_services_t *b; -#if GRUB_TARGET_SIZEOF_VOID_P < 8 +#if 1 /* Limit the memory access to less than 4GB for 32-bit platforms. */ if (address > 0xffffffff) return 0; #endif -#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) +#if 1 if (address == 0) { type = GRUB_EFI_ALLOCATE_MAX_ADDRESS; @@ -251,7 +251,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY -#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) +#if 1 && desc->physical_start <= 0xffffffff #endif && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 @@ -267,7 +267,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, desc->physical_start = 0x100000; } -#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL) +#if 1 if (BYTES_TO_PAGES (filtered_desc->physical_start) + filtered_desc->num_pages > BYTES_TO_PAGES (0x100000000LL)) From b3ff6ff0565a4f774763eb71f70979b126029dce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 23:56:11 +0100 Subject: [PATCH 0645/1414] * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Use comma as separator and pass bootpath/devid even if only one of them is available. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ grub-core/fs/zfs/zfsinfo.c | 23 ++++++++--------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b9b9b6aa..4433ffa5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-10 Vladimir Serbinenko + + * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Use comma as + separator and pass bootpath/devid even if only one of them is available. + Reported by: Seth Goldberg. + 2011-01-10 Vladimir Serbinenko Don't use post-4G memory on EFI even if 64-bit since some non-compliant diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 33065892a..5a7b5ec44 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -364,21 +364,14 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, grub_free (nv); grub_free (nvlist); - if (bootpath && devid) - { - bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu bootpath=%s diskdevid=%s", - poolname, (unsigned long long) mdnobj, - bootpath, devid); - if (!bootfs) - return grub_errno; - } - else - { - bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu", - poolname, (unsigned long long) mdnobj); - if (!bootfs) - return grub_errno; - } + bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s", + poolname, (unsigned long long) mdnobj, + bootpath ? ",bootpath=" : "", + bootpath ? : "", + devid ? ",diskdevid=" : "", + devid ? : ""); + if (!bootfs) + return grub_errno; if (argc >= 2) grub_env_set (args[1], bootfs); else From c2fa6cbb42dd3e2a17e7074a2eec421c31f4b4fa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 Jan 2011 23:57:49 +0100 Subject: [PATCH 0646/1414] * util/grub-menulst2cfg.c: Add missing include of misc.h. --- ChangeLog | 4 ++++ util/grub-menulst2cfg.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4433ffa5e..63a0ee46c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-10 Vladimir Serbinenko + + * util/grub-menulst2cfg.c: Add missing include of misc.h. + 2011-01-10 Vladimir Serbinenko * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Use comma as diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index da1c289a8..513af47c1 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -23,6 +23,7 @@ #include #include #include +#include int main (int argc, char **argv) From 3395fe5230ef31f838692b88dc0c7ebc62599151 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 11 Jan 2011 00:02:01 +0100 Subject: [PATCH 0647/1414] Pass more appropriate video id to Linux. * grub-core/loader/i386/linux.c (grub_linux_setup_video): Use grub_video_get_driver_id and variable gfxpayloadforcelfb to fill have_vga. (grub_linux_boot): Rely on grub_linux_setup_video to fill have_vga and shift params->lfb_size. * include/grub/i386/linux.h: Make an enume out of have_vga values. --- BUGS | 2 ++ ChangeLog | 11 ++++++++ grub-core/loader/i386/linux.c | 51 +++++++++++++++++++++++++---------- include/grub/i386/linux.h | 10 ++++--- 4 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 BUGS diff --git a/BUGS b/BUGS new file mode 100644 index 000000000..0faebcdcc --- /dev/null +++ b/BUGS @@ -0,0 +1,2 @@ +Currently search and assembling multidevice abstractions scans all the devices which can be slow. +Cache isn't used correctly for video which results in slowness. diff --git a/ChangeLog b/ChangeLog index 63a0ee46c..1a6a71bc5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-01-10 Vladimir Serbinenko + + Pass more appropriate video id to Linux. + + * grub-core/loader/i386/linux.c (grub_linux_setup_video): Use + grub_video_get_driver_id and variable gfxpayloadforcelfb to + fill have_vga. + (grub_linux_boot): Rely on grub_linux_setup_video to fill have_vga and + shift params->lfb_size. + * include/grub/i386/linux.h: Make an enume out of have_vga values. + 2011-01-10 Vladimir Serbinenko * util/grub-menulst2cfg.c: Add missing include of misc.h. diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 80f583cef..80960570b 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -313,6 +313,13 @@ grub_linux_setup_video (struct linux_kernel_params *params) struct grub_video_mode_info mode_info; void *framebuffer; grub_err_t err; + grub_video_driver_id_t driver_id; + char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); + + driver_id = grub_video_get_driver_id (); + + if (driver_id == GRUB_VIDEO_DRIVER_NONE) + return 1; err = grub_video_get_info_and_fini (&mode_info, &framebuffer); @@ -339,12 +346,40 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->reserved_mask_size = mode_info.reserved_mask_size; params->reserved_field_pos = mode_info.reserved_field_pos; + if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y')) + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + else + { + switch (driver_id) + { + case GRUB_VIDEO_DRIVER_VBE: + params->lfb_size >>= 16; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + break; + + case GRUB_VIDEO_DRIVER_EFI_UGA: + case GRUB_VIDEO_DRIVER_EFI_GOP: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; + break; + + /* FIXME: check if better id is available. */ + case GRUB_VIDEO_DRIVER_SM712: + case GRUB_VIDEO_DRIVER_VGA: + case GRUB_VIDEO_DRIVER_CIRRUS: + case GRUB_VIDEO_DRIVER_BOCHS: + /* Make gcc happy. */ + case GRUB_VIDEO_DRIVER_SDL: + case GRUB_VIDEO_DRIVER_NONE: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + break; + } + } #ifdef GRUB_MACHINE_PCBIOS /* VESA packed modes may come with zeroed mask sizes, which need to be set here according to DAC Palette width. If we don't, this results in Linux displaying a black screen. */ - if (mode_info.bpp <= 8) + if (driver_id == GRUB_VIDEO_DRIVER_VBE && mode_info.bpp <= 8) { struct grub_vbe_info_block controller_info; int status; @@ -457,15 +492,7 @@ grub_linux_boot (void) grub_errno = GRUB_ERR_NONE; } - if (! grub_linux_setup_video (params)) - { - /* Use generic framebuffer unless VESA is known to be supported. */ - if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA) - params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; - else - params->lfb_size >>= 16; - } - else + if (grub_linux_setup_video (params)) { #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; @@ -771,10 +798,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), break; } - /* We can't detect VESA, but user is implicitly telling us that it - is built-in because `vga=' parameter was used. */ - params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; - linux_mode = &grub_vesa_mode_table[vid_mode - GRUB_VESA_MODE_TABLE_START]; diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index 9ba83eee2..fed58a630 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -79,9 +79,13 @@ struct grub_e820_mmap grub_uint32_t type; } __attribute__((packed)); -#define GRUB_VIDEO_LINUX_TYPE_TEXT 0x01 -#define GRUB_VIDEO_LINUX_TYPE_VESA 0x23 /* VESA VGA in graphic mode. */ -#define GRUB_VIDEO_LINUX_TYPE_SIMPLE 0x70 /* Linear framebuffer without any additional functions. */ +enum + { + GRUB_VIDEO_LINUX_TYPE_TEXT = 0x01, + GRUB_VIDEO_LINUX_TYPE_VESA = 0x23, /* VESA VGA in graphic mode. */ + GRUB_VIDEO_LINUX_TYPE_EFIFB = 0x70, /* EFI Framebuffer. */ + GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70 /* Linear framebuffer without any additional functions. */ + }; /* For the Linux/i386 boot protocol version 2.03. */ struct linux_kernel_header From f093110b52d6d2b3b97fd1c07388f441863e0f5f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 11 Jan 2011 00:06:01 +0100 Subject: [PATCH 0648/1414] * BUGS: New file. --- BUGS | 9 +++++++-- ChangeLog | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/BUGS b/BUGS index 0faebcdcc..46faa6452 100644 --- a/BUGS +++ b/BUGS @@ -1,2 +1,7 @@ -Currently search and assembling multidevice abstractions scans all the devices which can be slow. -Cache isn't used correctly for video which results in slowness. +GRUB team is aware of following problems: + - Currently search and assembling multidevice abstractions scans + all the devices which can be slow. + - Cache isn't used correctly for video which results in slowness. + +While these are bugs their solution has a potential of breaking more and more +seriously. So it was decided for 1.99 that they aren't fixed. diff --git a/ChangeLog b/ChangeLog index 1a6a71bc5..894f886b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-11 Vladimir Serbinenko + + * BUGS: New file. + 2011-01-10 Vladimir Serbinenko Pass more appropriate video id to Linux. From 45146057263bc0d47cefe2f46ee6157f92fd3af4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 11 Jan 2011 00:44:56 +0100 Subject: [PATCH 0649/1414] =?UTF-8?q?=09*=20grub-core/loader/i386/multiboo?= =?UTF-8?q?t=5Fmbi.c=20(grub=5Fmultiboot=5Fmake=5Fmbi):=20=09Take=20into?= =?UTF-8?q?=20account=20space=20used=20by=20ELF=20sections=20and=20multibo?= =?UTF-8?q?ot=20palette.=20=09Reported=20by:=20Gr=C3=A9goire=20Sutre.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 6 ++++++ grub-core/loader/i386/multiboot_mbi.c | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index 894f886b4..73571a549 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-11 Vladimir Serbinenko + + * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): + Take into account space used by ELF sections and multiboot palette. + Reported by: GrĂ©goire Sutre. + 2011-01-11 Vladimir Serbinenko * BUGS: New file. diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index eade78e93..b98bda223 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -539,6 +539,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target) mbi->u.elf_sec.shndx = elf_sec_shstrndx; mbi->flags |= MULTIBOOT_INFO_ELF_SHDR; + + ptrorig += elf_sec_entsize * elf_sec_num; + ptrdest += elf_sec_entsize * elf_sec_num; } err = retrieve_video_parameters (mbi, ptrorig, ptrdest); @@ -547,6 +550,16 @@ grub_multiboot_make_mbi (grub_uint32_t *target) grub_print_error (); grub_errno = GRUB_ERR_NONE; } + + if ((mbi->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) + && mbi->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED) + { + ptrorig += mbi->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + ptrdest += mbi->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + } + #if GRUB_MACHINE_HAS_VBE ptrorig += sizeof (struct grub_vbe_info_block); ptrdest += sizeof (struct grub_vbe_info_block); From 4531a206a1c112d405ef9ea00f2e06037ef0c01a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 11 Jan 2011 11:51:05 +0100 Subject: [PATCH 0650/1414] * grub-core/fs/i386/pc/pxe.c (set_mac_env): Export variable. (set_env_limn_ro): Likewise. (GRUB_MOD_INIT): Likewise. * grub-core/hook/datehook.c (GRUB_MOD_INIT): Likewise. Change to ARRAY_SIZE while on it. (GRUB_MOD_FINI): Change to ARRAY_SIZE. * grub-core/normal/context.c (grub_env_export): Move from here ... * grub-core/kern/env.c (grub_env_export): ... here. * grub-core/normal/context.c (grub_cmd_export): Skip exporting root and prefix. * grub-core/kern/main.c (grub_main): Export root and prefix. * include/grub/env.h (grub_env_export): Export. Reported by: Seth Goldberg. --- ChangeLog | 16 ++++++++++++++++ grub-core/fs/i386/pc/pxe.c | 9 +++++++++ grub-core/hook/datehook.c | 15 +++++++++------ grub-core/kern/env.c | 20 ++++++++++++++++++++ grub-core/kern/main.c | 2 ++ grub-core/normal/context.c | 23 ----------------------- include/grub/env.h | 2 +- 7 files changed, 57 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73571a549..a4f7122fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-01-11 Vladimir Serbinenko + + * grub-core/fs/i386/pc/pxe.c (set_mac_env): Export variable. + (set_env_limn_ro): Likewise. + (GRUB_MOD_INIT): Likewise. + * grub-core/hook/datehook.c (GRUB_MOD_INIT): Likewise. Change to + ARRAY_SIZE while on it. + (GRUB_MOD_FINI): Change to ARRAY_SIZE. + * grub-core/normal/context.c (grub_env_export): Move from here ... + * grub-core/kern/env.c (grub_env_export): ... here. + * grub-core/normal/context.c (grub_cmd_export): Skip exporting root and + prefix. + * grub-core/kern/main.c (grub_main): Export root and prefix. + * include/grub/env.h (grub_env_export): Export. + Reported by: Seth Goldberg. + 2011-01-11 Vladimir Serbinenko * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index cbb3c7d87..e2b53d637 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -420,6 +420,7 @@ set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len) grub_env_set ("net_pxe_mac", buf); /* XXX: Is it possible to change MAC in PXE? */ grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly); + grub_env_export ("net_pxe_mac"); } static void @@ -431,6 +432,7 @@ set_env_limn_ro (const char *varname, char *value, grub_size_t len) grub_env_set (varname, value); value[len] = c; grub_register_variable_hook (varname, 0, grub_env_write_readonly); + grub_env_export (varname); } static void @@ -624,12 +626,19 @@ GRUB_MOD_INIT(pxe) grub_env_write_pxe_default_server); grub_register_variable_hook ("pxe_default_gateway", 0, grub_env_write_pxe_default_gateway); + /* XXX: Is it possible to change IP in PXE? */ grub_register_variable_hook ("net_pxe_ip", 0, grub_env_write_readonly); grub_register_variable_hook ("pxe_blksize", 0, grub_env_write_pxe_blocksize); + + grub_env_export ("pxe_default_server"); + grub_env_export ("pxe_default_gateway"); + grub_env_export ("net_pxe_ip"); + grub_env_export ("pxe_blksize"); + grub_disk_dev_register (&grub_pxe_dev); grub_fs_register (&grub_pxefs_fs); } diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c index 9b5b54bf3..d855311d3 100644 --- a/grub-core/hook/datehook.c +++ b/grub-core/hook/datehook.c @@ -86,18 +86,21 @@ grub_read_hook_datetime (struct grub_env_var *var, GRUB_MOD_INIT(datehook) { - int i; + unsigned i; - for (i = 0; i < 7; i++) - grub_register_variable_hook (grub_datetime_names[i], - grub_read_hook_datetime, 0); + for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++) + { + grub_register_variable_hook (grub_datetime_names[i], + grub_read_hook_datetime, 0); + grub_env_export (grub_datetime_names[i]); + } } GRUB_MOD_FINI(datehook) { - int i; + unsigned i; - for (i = 0; i < 7; i++) + for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++) { grub_register_variable_hook (grub_datetime_names[i], 0, 0); grub_env_unset (grub_datetime_names[i]); diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c index 84b3a001d..8f843a872 100644 --- a/grub-core/kern/env.c +++ b/grub-core/kern/env.c @@ -240,3 +240,23 @@ grub_register_variable_hook (const char *name, return GRUB_ERR_NONE; } + +grub_err_t +grub_env_export (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (! var) + { + grub_err_t err; + + err = grub_env_set (name, ""); + if (err) + return err; + var = grub_env_find (name); + } + var->global = 1; + + return GRUB_ERR_NONE; +} diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 8b6c8a180..da7123234 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -189,6 +189,8 @@ grub_main (void) for convenience. */ grub_machine_set_prefix (); grub_set_root_dev (); + grub_env_export ("root"); + grub_env_export ("prefix"); grub_register_core_commands (); diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index 75beeefda..b73161d0b 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -175,26 +175,6 @@ grub_env_extractor_close (int source) return err; } -grub_err_t -grub_env_export (const char *name) -{ - struct grub_env_var *var; - - var = grub_env_find (name); - if (! var) - { - grub_err_t err; - - err = grub_env_set (name, ""); - if (err) - return err; - var = grub_env_find (name); - } - var->global = 1; - - return GRUB_ERR_NONE; -} - static grub_command_t export_cmd; static grub_err_t @@ -216,9 +196,6 @@ grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)), void grub_context_init (void) { - grub_env_export ("root"); - grub_env_export ("prefix"); - export_cmd = grub_register_command ("export", grub_cmd_export, N_("ENVVAR [ENVVAR] ..."), N_("Export variables.")); diff --git a/include/grub/env.h b/include/grub/env.h index 6d1f0de6e..c0107f16a 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -53,7 +53,7 @@ grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, grub_err_t grub_env_context_open (void); grub_err_t grub_env_context_close (void); -grub_err_t grub_env_export (const char *name); +grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); void grub_env_unset_menu (void); grub_menu_t grub_env_get_menu (void); From 86205c94c3f85579f56b005896c4ad3cf0c69d00 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 11 Jan 2011 09:08:57 -0600 Subject: [PATCH 0651/1414] * util/grub-mklayout.c (console_grub_equivalences_shift): Terminate with NULL. (console_grub_equivalences_unshift): Likewise. Reported by: Daniel Dehennin. --- ChangeLog | 7 +++++++ util/grub-mklayout.c | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index a4f7122fb..56a8db213 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-11 Colin Watson + + * util/grub-mklayout.c (console_grub_equivalences_shift): Terminate + with NULL. + (console_grub_equivalences_unshift): Likewise. + Reported by: Daniel Dehennin. + 2011-01-11 Vladimir Serbinenko * grub-core/fs/i386/pc/pxe.c (set_mac_env): Export variable. diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 36f6e04fc..04501cb40 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -60,6 +60,8 @@ static struct console_grub_equivalence console_grub_equivalences_shift[] = { {"KP_8", '8'}, {"KP_9", '9'}, {"KP_Period", '.'}, + + {NULL, '\0'} }; static struct console_grub_equivalence console_grub_equivalences_unshift[] = { @@ -74,6 +76,8 @@ static struct console_grub_equivalence console_grub_equivalences_unshift[] = { {"KP_8", GRUB_TERM_KEY_UP}, {"KP_9", GRUB_TERM_KEY_PPAGE}, {"KP_Period", GRUB_TERM_KEY_DC}, + + {NULL, '\0'} }; static struct console_grub_equivalence console_grub_equivalences_common[] = { From 89644ef113f00c03b18d075243debf5417e00549 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 11 Jan 2011 21:20:54 +0100 Subject: [PATCH 0652/1414] Rename grub-fuse to grub-mount (with Vladimir's blessing) --- Makefile.util.def | 4 ++-- configure.ac | 6 +++--- docs/man/grub-fuse.h2m | 2 -- docs/man/grub-mount.h2m | 2 ++ util/{grub-fuse.c => grub-mount.c} | 0 5 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 docs/man/grub-fuse.h2m create mode 100644 docs/man/grub-mount.h2m rename util/{grub-fuse.c => grub-mount.c} (100%) diff --git a/Makefile.util.def b/Makefile.util.def index 369d312f6..3009ff76a 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -213,10 +213,10 @@ program = { }; program = { - name = grub-fuse; + name = grub-mount; mansection = 1; common_nodist = grub_fstest_init.c; - common = util/grub-fuse.c; + common = util/grub-mount.c; common = grub-core/kern/emu/hostfs.c; common = grub-core/disk/host.c; diff --git a/configure.ac b/configure.ac index e9e31e7fb..b71aea910 100644 --- a/configure.ac +++ b/configure.ac @@ -878,7 +878,7 @@ if test x"$grub_fuse_excuse" = x ; then fi if test x"$enable_grub_fuse" = xyes && test x"$grub_fuse_excuse" != x ; then - AC_MSG_ERROR([grub-fuse was explicitly requested but can't be compiled]) + AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled]) fi if test x"$grub_fuse_excuse" = x ; then enable_grub_fuse=yes @@ -1060,9 +1060,9 @@ else echo grub-mkfont: No "($grub_mkfont_excuse)" fi if [ x"$grub_fuse_excuse" = x ]; then -echo grub-fuse: Yes +echo grub-mount: Yes else -echo grub-fuse: No "($grub_fuse_excuse)" +echo grub-mount: No "($grub_fuse_excuse)" fi echo "*******************************************************" ] diff --git a/docs/man/grub-fuse.h2m b/docs/man/grub-fuse.h2m deleted file mode 100644 index 0e234ddc1..000000000 --- a/docs/man/grub-fuse.h2m +++ /dev/null @@ -1,2 +0,0 @@ -[NAME] -grub-fuse \- export GRUB filesystem with FUSE. diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m new file mode 100644 index 000000000..73e7246a3 --- /dev/null +++ b/docs/man/grub-mount.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mount \- export GRUB filesystem with FUSE. diff --git a/util/grub-fuse.c b/util/grub-mount.c similarity index 100% rename from util/grub-fuse.c rename to util/grub-mount.c From 9da068a5dc3b507276552980fc9c6459aef0a02d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 11 Jan 2011 23:01:07 +0100 Subject: [PATCH 0653/1414] * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32): Apply loadmask before doing any calculations. Use correct type for offset. (grub_linux_load64): Likewise. --- ChangeLog | 6 ++++++ grub-core/loader/powerpc/ieee1275/linux.c | 16 +++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56a8db213..05e2ec8c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-11 Vladimir Serbinenko + + * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32): Apply + loadmask before doing any calculations. Use correct type for offset. + (grub_linux_load64): Likewise. + 2011-01-11 Colin Watson * util/grub-mklayout.c (console_grub_equivalences_shift): Terminate diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c index a99310cfd..0cf0eb825 100644 --- a/grub-core/loader/powerpc/ieee1275/linux.c +++ b/grub-core/loader/powerpc/ieee1275/linux.c @@ -152,7 +152,8 @@ grub_linux_load32 (grub_elf_t elf) Elf32_Addr base_addr; grub_addr_t seg_addr; grub_uint32_t align; - int offset; + grub_uint32_t offset; + Elf32_Addr entry; linux_size = grub_elf32_size (elf, &base_addr, &align); if (linux_size == 0) @@ -160,9 +161,12 @@ grub_linux_load32 (grub_elf_t elf) /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; - offset = elf->ehdr.ehdr32.e_entry - base_addr; + /* Linux's entry point incorrectly contains a virtual address. */ + entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK; + /* Linux's incorrectly contains a virtual address. */ base_addr &= ~ELF32_LOADMASK; + offset = entry - base_addr; /* On some systems, firmware occupies the memory we're trying to use. * Happily, Linux can be loaded anywhere (it relocates itself). Iterate @@ -196,7 +200,8 @@ grub_linux_load64 (grub_elf_t elf) Elf64_Addr base_addr; grub_addr_t seg_addr; grub_uint64_t align; - int offset; + grub_uint64_t offset; + Elf64_Addr entry; linux_size = grub_elf64_size (elf, &base_addr, &align); if (linux_size == 0) @@ -204,9 +209,10 @@ grub_linux_load64 (grub_elf_t elf) /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; - offset = elf->ehdr.ehdr64.e_entry - base_addr; - /* Linux's incorrectly contains a virtual address. */ base_addr &= ~ELF64_LOADMASK; + entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK; + offset = entry - base_addr; + /* Linux's incorrectly contains a virtual address. */ /* On some systems, firmware occupies the memory we're trying to use. * Happily, Linux can be loaded anywhere (it relocates itself). Iterate From 51fa856c58720eeb6b018a2181716a5458e5fbae Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 11 Jan 2011 17:49:27 -0600 Subject: [PATCH 0654/1414] * configure.ac: Fall back to `true' if `makeinfo' does not exist. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 05e2ec8c7..e14a33968 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-11 Colin Watson + + * configure.ac: Fall back to `true' if `makeinfo' does not exist. + 2011-01-11 Vladimir Serbinenko * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32): Apply diff --git a/configure.ac b/configure.ac index a9ca130b4..055c65e67 100644 --- a/configure.ac +++ b/configure.ac @@ -246,7 +246,7 @@ else fi # These are not a "must". -AC_PATH_PROG(MAKEINFO, makeinfo) +AC_PATH_PROGS(MAKEINFO, makeinfo true) # # Checks for host programs. From b44a558c9a133f398364bc953ba540e1909c1f31 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 Jan 2011 11:26:28 +0100 Subject: [PATCH 0655/1414] Use alias->path rather than buggy "canon". * grub-core/disk/ieee1275/ofdisk.c (ofdisk_hash_add_real): New function. (ofdisk_hash_add): New argument curcan. All users updated. --- ChangeLog | 7 +++++++ grub-core/disk/ieee1275/ofdisk.c | 34 ++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index e14a33968..958850421 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-12 Vladimir Serbinenko + + Use alias->path rather than buggy "canon". + + * grub-core/disk/ieee1275/ofdisk.c (ofdisk_hash_add_real): New function. + (ofdisk_hash_add): New argument curcan. All users updated. + 2011-01-11 Colin Watson * configure.ac: Fall back to `true' if `makeinfo' does not exist. diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 85c34609e..0a935d5c2 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -62,11 +62,10 @@ ofdisk_hash_find (const char *devpath) } static struct ofdisk_hash_ent * -ofdisk_hash_add (char *devpath) +ofdisk_hash_add_real (char *devpath) { + struct ofdisk_hash_ent *p; struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; - struct ofdisk_hash_ent *p, *pcan; - char *curcan; p = grub_malloc(sizeof (*p)); if (!p) @@ -76,17 +75,27 @@ ofdisk_hash_add (char *devpath) p->next = *head; p->shortest = 0; *head = p; + return p; +} + +static struct ofdisk_hash_ent * +ofdisk_hash_add (char *devpath, char *curcan) +{ + struct ofdisk_hash_ent *p, *pcan; + + p = ofdisk_hash_add_real (devpath); + + grub_dprintf ("disk", "devpath = %s, canonical = %s\n", devpath, curcan); - curcan = grub_ieee1275_canonicalise_devname (devpath); if (!curcan) { - grub_errno = GRUB_ERR_NONE; + p->shortest = devpath; return p; } pcan = ofdisk_hash_find (curcan); if (!pcan) - pcan = ofdisk_hash_add (curcan); + pcan = ofdisk_hash_add_real (curcan); else grub_free (curcan); @@ -118,17 +127,22 @@ scan (void) return 0; grub_dprintf ("disk", "disk name = %s\n", alias->name); + grub_dprintf ("disk", "disk name = %s, path = %s\n", alias->name, + alias->path); - op = ofdisk_hash_find (alias->path); + op = ofdisk_hash_find (alias->name); if (!op) { char *name = grub_strdup (alias->name); - if (!name) + char *can = grub_strdup (alias->path); + if (!name || !can) { grub_errno = GRUB_ERR_NONE; + grub_free (name); + grub_free (can); return 0; } - op = ofdisk_hash_add (name); + op = ofdisk_hash_add (name, can); } return 0; } @@ -247,7 +261,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) struct ofdisk_hash_ent *op; op = ofdisk_hash_find (devpath); if (!op) - op = ofdisk_hash_add (devpath); + op = ofdisk_hash_add (devpath, NULL); else grub_free (devpath); if (!op) From b8494fbe5c6b816dc7386eb7dc60a3922b86fdb7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 Jan 2011 11:52:51 +0100 Subject: [PATCH 0656/1414] * grub-core/normal/context.c (grub_env_context_close): Silence spurious warning. * grub-core/normal/menu.c (grub_menu_execute_entry): Likewise. * grub-core/partmap/msdos.c (pc_partition_map_embed): Use unsigned counter. --- ChangeLog | 8 ++++++++ grub-core/normal/context.c | 3 ++- grub-core/normal/menu.c | 2 +- grub-core/partmap/msdos.c | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 958850421..6efb466bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-01-12 Vladimir Serbinenko + + * grub-core/normal/context.c (grub_env_context_close): Silence spurious + warning. + * grub-core/normal/menu.c (grub_menu_execute_entry): Likewise. + * grub-core/partmap/msdos.c (pc_partition_map_embed): Use unsigned + counter. + 2011-01-12 Vladimir Serbinenko Use alias->path rather than buggy "canon". diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index b73161d0b..108679913 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -148,7 +148,7 @@ grub_env_context_close (void) grub_err_t grub_env_extractor_close (int source) { - grub_menu_t menu, menu2; + grub_menu_t menu = NULL; grub_menu_entry_t *last; grub_err_t err; @@ -161,6 +161,7 @@ grub_env_extractor_close (int source) if (source) { + grub_menu_t menu2; menu2 = grub_env_get_menu (); last = &menu2->entry_list; diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 6a123a6de..e62482122 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -159,7 +159,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) { grub_err_t err = GRUB_ERR_NONE; int errs_before; - grub_menu_t menu; + grub_menu_t menu = NULL; char *optr, *buf, *oldchosen = NULL, *olddefault = NULL; const char *ptr, *chosen, *def; grub_size_t sz = 0; diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index f99e27a6e..d411c4405 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -234,7 +234,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (end >= *nsectors + 1) { - int i; + unsigned i; *nsectors = end - 1; *sectors = grub_malloc (*nsectors * sizeof (**sectors)); if (!*sectors) From 8fc0a24576669f28e98f9ccc1b40b8e742f95aad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 Jan 2011 11:55:52 +0100 Subject: [PATCH 0657/1414] * grub-core/Makefile.core.def (ieee1275_fb): Disable on sparc. It doesn't work well there. --- ChangeLog | 5 +++++ grub-core/Makefile.core.def | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6efb466bb..915fd2619 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-12 Vladimir Serbinenko + + * grub-core/Makefile.core.def (ieee1275_fb): Disable on sparc. + It doesn't work well there. + 2011-01-12 Vladimir Serbinenko * grub-core/normal/context.c (grub_env_context_close): Silence spurious diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 094bbc835..2cca4fa95 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1463,7 +1463,6 @@ module = { name = ieee1275_fb; ieee1275 = video/ieee1275.c; enable = powerpc; - enable = sparc64; }; module = { From f8f479dbbbd908551f2c691b3b7d35997f3a1a7b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 Jan 2011 12:49:16 +0100 Subject: [PATCH 0658/1414] * util/grub-mkfont.c (write_font_pf2): Use appropriate type for data variable. Fixes problem on big endian platforms. --- ChangeLog | 5 +++++ util/grub-mkfont.c | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 915fd2619..254fc2c6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-12 Vladimir Serbinenko + + * util/grub-mkfont.c (write_font_pf2): Use appropriate type for data + variable. Fixes problem on big endian platforms. + 2011-01-12 Vladimir Serbinenko * grub-core/Makefile.core.def (ieee1275_fb): Disable on sparc. diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 983ac7065..3108d4694 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -859,7 +859,7 @@ void write_font_pf2 (struct grub_font_info *font_info, char *output_file) { FILE *file; - grub_uint32_t leng, data; + grub_uint32_t leng; char style_name[20], *font_name; int offset; struct grub_glyph_info *cur; @@ -959,12 +959,14 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) for (cur = font_info->glyphs_sorted; cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++) { - data = grub_cpu_to_be32 (cur->char_code); - grub_util_write_image ((char *) &data, 4, file); - data = 0; - grub_util_write_image ((char *) &data, 1, file); - data = grub_cpu_to_be32 (offset); - grub_util_write_image ((char *) &data, 4, file); + grub_uint32_t data32; + grub_uint8_t data8; + data32 = grub_cpu_to_be32 (cur->char_code); + grub_util_write_image ((char *) &data32, 4, file); + data8 = 0; + grub_util_write_image ((char *) &data8, 1, file); + data32 = grub_cpu_to_be32 (offset); + grub_util_write_image ((char *) &data32, 4, file); offset += 10 + cur->bitmap_size; } @@ -976,6 +978,7 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) for (cur = font_info->glyphs_sorted; cur < font_info->glyphs_sorted + font_info->num_glyphs; cur++) { + grub_uint16_t data; data = grub_cpu_to_be16 (cur->width); grub_util_write_image ((char *) &data, 2, file); data = grub_cpu_to_be16 (cur->height); From 173b71e9fea74cb2edfab96418f92bc589a17dc4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 12 Jan 2011 19:51:19 +0100 Subject: [PATCH 0659/1414] * util/grub.d/00_header.in (load_video): Handle the case when no video drivers available. Thanks to: Axel Beckert. --- ChangeLog | 6 ++++++ util/grub.d/00_header.in | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 254fc2c6f..74c6affff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-12 Vladimir Serbinenko + + * util/grub.d/00_header.in (load_video): Handle the case when no video + drivers available. + Thanks to: Axel Beckert. + 2011-01-12 Vladimir Serbinenko * util/grub-mkfont.c (write_font_pf2): Use appropriate type for data diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index a596e9c4a..420b3f32c 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -84,11 +84,16 @@ if [ -n "${GRUB_VIDEO_BACKEND}" ]; then EOF else # Insert all available backends; GRUB will use the most appropriate. + have_video=0; for backend in $(cat "${GRUB_PREFIX}/video.lst"); do + have_video=1; cat < Date: Wed, 12 Jan 2011 19:58:32 +0100 Subject: [PATCH 0660/1414] * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Use the realpath'ed device string. Handle floppy (somewhat). Issue error in unknown case rather than garbage. Reported by: Axel Beckert. --- ChangeLog | 8 ++++++++ util/ieee1275/ofpath.c | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74c6affff..7a3f3f63a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-01-12 Vladimir Serbinenko + + * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Use the + realpath'ed device string. + Handle floppy (somewhat). + Issue error in unknown case rather than garbage. + Reported by: Axel Beckert. + 2011-01-12 Vladimir Serbinenko * util/grub.d/00_header.in (load_video): Handle the case when no video diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index fa0d48cf9..1a433345d 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -377,8 +377,8 @@ grub_util_devname_to_ofpath (const char *devname) if (! name_buf) grub_util_error ("cannot get the real path of `%s'", devname); - device = get_basename (devname); - devnode = strip_trailing_digits (devname); + device = get_basename (name_buf); + devnode = strip_trailing_digits (name_buf); devicenode = strip_trailing_digits (device); ofpath = xmalloc (OF_PATH_MAX); @@ -391,6 +391,13 @@ grub_util_devname_to_ofpath (const char *devname) else if (device[0] == 'v' && device[1] == 'd' && device[2] == 'i' && device[3] == 's' && device[4] == 'k') of_path_of_vdisk(ofpath, name_buf, device, devnode, devicenode); + else if (device[0] == 'f' && device[1] == 'd' + && device[2] == '0' && device[3] == '\0') + /* All the models I've seen have a devalias "floppy". + New models have no floppy at all. */ + strcpy (ofpath, "floppy"); + else + grub_util_error ("unknown device type %s\n", device); free (devnode); free (devicenode); From bd1a4147141708625214564959684257a6614935 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 12 Jan 2011 17:27:52 -0600 Subject: [PATCH 0661/1414] Resolve the device returned by grub_find_root_device_from_mountinfo or find_root_device_from_libzfs using grub_find_device. Reported by: Roderich Schupp. --- grub-core/kern/emu/getroot.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index df3a4d765..92ff971e5 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -467,7 +467,7 @@ grub_find_device (const char *path, dev_t dev) char * grub_guess_root_device (const char *dir) { - char *os_dev; + char *os_dev = NULL; #ifdef __GNU__ file_t file; mach_port_t *ports; @@ -526,30 +526,42 @@ grub_guess_root_device (const char *dir) mach_port_deallocate (mach_task_self (), file); #else /* !__GNU__ */ struct stat st; + dev_t dev; #ifdef __linux__ - os_dev = grub_find_root_device_from_mountinfo (dir, NULL); - if (os_dev) - return os_dev; + if (!os_dev) + os_dev = grub_find_root_device_from_mountinfo (dir, NULL); #endif /* __linux__ */ #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - os_dev = find_root_device_from_libzfs (dir); - if (os_dev) - return os_dev; + if (!os_dev) + os_dev = find_root_device_from_libzfs (dir); #endif - if (stat (dir, &st) < 0) - grub_util_error ("cannot stat `%s'", 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); + } #ifdef __CYGWIN__ /* Cygwin specific function. */ - os_dev = grub_find_device (dir, st.st_dev); + os_dev = grub_find_device (dir, dev); #else /* This might be truly slow, but is there any better way? */ - os_dev = grub_find_device ("/dev", st.st_dev); + os_dev = grub_find_device ("/dev", dev); #endif #endif /* !__GNU__ */ From f1632d4dd050baee3d2a41730c45ab21f741c62f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 13 Jan 2011 22:23:49 +0100 Subject: [PATCH 0662/1414] Fix compilation on cygwin. * conf/Makefile.common (STRIPFLAGS_KERNEL): Add -F elf32-i386 and -R .drectve on cygwin. * conf/i386-pc-cygwin-img-ld.sc: Merge rdata and pdata into data. * configure.ac: Use $(top_builddir) in TARGET_OBJ2ELF. (COND_CYGWIN): New condition. * grub-core/Makefile.am (%.mod): Set TARGET_OBJ2ELF. * grub-core/genmod.sh.in: Use ${TARGET_OBJ2ELF} and not @TARGET_OBJ2ELF@. * util/grub-pe2elf.c (write_symbol_table): Use pe_symtab->type and not type to determine whether aux is to be used. --- ChangeLog | 15 +++++++++++++++ conf/Makefile.common | 4 ++++ conf/i386-pc-cygwin-img-ld.sc | 6 ------ configure.ac | 3 ++- grub-core/Makefile.am | 2 +- grub-core/genmod.sh.in | 4 ++-- util/grub-pe2elf.c | 2 +- 7 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7a3f3f63a..696da1215 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-01-13 Vladimir Serbinenko + + Fix compilation on cygwin. + + * conf/Makefile.common (STRIPFLAGS_KERNEL): Add -F elf32-i386 and + -R .drectve on cygwin. + * conf/i386-pc-cygwin-img-ld.sc: Merge rdata and pdata into data. + * configure.ac: Use $(top_builddir) in TARGET_OBJ2ELF. + (COND_CYGWIN): New condition. + * grub-core/Makefile.am (%.mod): Set TARGET_OBJ2ELF. + * grub-core/genmod.sh.in: Use ${TARGET_OBJ2ELF} and + not @TARGET_OBJ2ELF@. + * util/grub-pe2elf.c (write_symbol_table): Use pe_symtab->type and not + type to determine whether aux is to be used. + 2011-01-12 Vladimir Serbinenko * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Use the diff --git a/conf/Makefile.common b/conf/Makefile.common index 2df8465c0..32ca76d08 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -67,7 +67,11 @@ CFLAGS_KERNEL = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding LDFLAGS_KERNEL = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N -static-libgcc CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) +if COND_CYGWIN +STRIPFLAGS_KERNEL = -F elf32-i386 -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve +else STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment +endif CFLAGS_MODULE = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding LDFLAGS_MODULE = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N,-r,-d diff --git a/conf/i386-pc-cygwin-img-ld.sc b/conf/i386-pc-cygwin-img-ld.sc index a41cac75e..3b579d344 100644 --- a/conf/i386-pc-cygwin-img-ld.sc +++ b/conf/i386-pc-cygwin-img-ld.sc @@ -13,15 +13,9 @@ SECTIONS __data_start__ = . ; *(.data) __data_end__ = . ; - } - .rdata : - { __rdata_start__ = . ; *(.rdata) __rdata_end__ = . ; - } - .pdata : - { *(.pdata) edata = . ; } diff --git a/configure.ac b/configure.ac index 055c65e67..0b9207ea2 100644 --- a/configure.ac +++ b/configure.ac @@ -454,7 +454,7 @@ fi # For platforms where ELF is not the default link format. AC_MSG_CHECKING([for command to convert module to ELF format]) case "${host_os}" in - cygwin) TARGET_OBJ2ELF='$(grub_utildir)/grub-pe2elf'; + cygwin) TARGET_OBJ2ELF='$(top_builddir)/grub-pe2elf'; # FIXME: put proper test here NEED_REGISTER_FRAME_INFO=1 ;; @@ -964,6 +964,7 @@ AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) +AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin]) # Output files. grub_CHECK_LINK_DIR diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index fcf3fc42d..94f7f3ffe 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -303,7 +303,7 @@ platform_DATA += moddep.lst CLEANFILES += config.log syminfo.lst moddep.lst $(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) - sh $^ $@ + TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ platform_DATA += $(MOD_FILES) CLEANFILES += $(MOD_FILES) diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in index b97f3e1c7..023cd1062 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -52,8 +52,8 @@ fi rm -f $t1 $t2 if test x@TARGET_APPLE_CC@ != x1; then - if ! test -z "@TARGET_OBJ2ELF@"; then - ./@TARGET_OBJ2ELF@ $tmpfile || exit 1 + if ! test -z "${TARGET_OBJ2ELF}"; then + ./${TARGET_OBJ2ELF} $tmpfile || exit 1 fi if test x@platform@ != xemu; then @STRIP@ --strip-unneeded \ diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index f370bbfa8..cf690841f 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -337,7 +337,7 @@ write_symbol_table (FILE* fp, char *image, else bind = STB_LOCAL; - if ((type != STT_FUNC) && (pe_symtab->num_aux)) + if ((pe_symtab->type != GRUB_PE32_DT_FUNCTION) && (pe_symtab->num_aux)) { if (! pe_symtab->value) type = STT_SECTION; From 4fbf185232d53acc65599720b6d304acb012e968 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 13 Jan 2011 22:25:56 +0100 Subject: [PATCH 0663/1414] * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Quote bootpath and diskdevid. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfsinfo.c | 12 +++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 696da1215..b57c6f229 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-13 Vladimir Serbinenko + + * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Quote bootpath and + diskdevid. + 2011-01-13 Vladimir Serbinenko Fix compilation on cygwin. diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 5a7b5ec44..224a97792 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -364,12 +364,14 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, grub_free (nv); grub_free (nvlist); - bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s", + bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s%s%s", poolname, (unsigned long long) mdnobj, - bootpath ? ",bootpath=" : "", - bootpath ? : "", - devid ? ",diskdevid=" : "", - devid ? : ""); + bootpath ? ",bootpath=\"" : "", + bootpath ? : "", + bootpath ? "\"" : "", + devid ? ",diskdevid=\"" : "", + devid ? : "", + devid ? "\"" : ""); if (!bootfs) return grub_errno; if (argc >= 2) From f440c33fd2669b06a0c84cbbe1912054d5d39314 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Jan 2011 17:37:11 +0100 Subject: [PATCH 0664/1414] 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 1d955d0098b02d77ccec93cd425568a7fa95c913 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Jan 2011 19:21:06 +0100 Subject: [PATCH 0665/1414] * grub-core/Makefile.core.def (fwstart): Add lost LDFLAGS. --- ChangeLog | 4 ++++ grub-core/Makefile.core.def | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index b57c6f229..4822910dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-13 Vladimir Serbinenko + + * grub-core/Makefile.core.def (fwstart): Add lost LDFLAGS. + 2011-01-13 Vladimir Serbinenko * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Quote bootpath and diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2cca4fa95..ce7d0b0c2 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -324,6 +324,7 @@ image = { name = fwstart; mips_yeeloong = boot/mips/yeeloong/fwstart.S; objcopyflags = '-O binary'; + ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; enable = mips_yeeloong; }; From 46c9db88cda310ec22344fcf4cfb055c1a317a28 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Jan 2011 19:23:34 +0100 Subject: [PATCH 0666/1414] * grub-core/kern/mips/yeeloong/init.c (grub_machine_init): Init boot module. --- ChangeLog | 7 ++++++- grub-core/kern/mips/yeeloong/init.c | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4822910dd..69534abe2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2011-01-13 Vladimir Serbinenko +2011-01-14 Vladimir Serbinenko + + * grub-core/kern/mips/yeeloong/init.c (grub_machine_init): Init boot + module. + +2011-01-14 Vladimir Serbinenko * grub-core/Makefile.core.def (fwstart): Add lost LDFLAGS. diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c index cadb10773..7a48d69f5 100644 --- a/grub-core/kern/mips/yeeloong/init.c +++ b/grub-core/kern/mips/yeeloong/init.c @@ -41,6 +41,7 @@ extern void grub_at_keyboard_init (void); extern void grub_serial_init (void); 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 @@ -210,6 +211,8 @@ grub_machine_init (void) grub_terminfo_init (); grub_serial_init (); + + grub_boot_init (); } void From 13fc463f17281442f13c5ed3dc586f22efaaa2af Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 15 Jan 2011 14:18:16 -0600 Subject: [PATCH 0667/1414] Make new grub_vbe_bios_* functions static. --- ChangeLog.vbe-autodetect | 5 +---- grub-core/video/i386/pc/vbe.c | 6 +++--- include/grub/i386/pc/vbe.h | 9 --------- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect index d8034b885..46aacef7b 100644 --- a/ChangeLog.vbe-autodetect +++ b/ChangeLog.vbe-autodetect @@ -1,4 +1,4 @@ -2010-12-14 Colin Watson +2011-01-15 Colin Watson Preferred resolution detection for VBE. @@ -25,9 +25,6 @@ (grub_video_edid_preferred_mode): Likewise. * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New structure. - (grub_vbe_bios_get_flat_panel_info): Add prototype. - (grub_vbe_bios_get_ddc_capabilities): Likewise. - (grub_vbe_bios_read_edid): Likewise. * grub-core/commands/videoinfo.c (print_edid): New function. (grub_cmd_videoinfo): Print EDID if available. diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index c6bb733a9..29b67beeb 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -274,7 +274,7 @@ grub_vbe_bios_get_pm_interface (grub_uint16_t *segment, grub_uint16_t *offset, } /* Call VESA BIOS 0x4f11 to get flat panel information, return status. */ -grub_vbe_status_t +static grub_vbe_status_t grub_vbe_bios_get_flat_panel_info (struct grub_vbe_flat_panel_info *flat_panel_info) { struct grub_bios_int_registers regs; @@ -289,7 +289,7 @@ grub_vbe_bios_get_flat_panel_info (struct grub_vbe_flat_panel_info *flat_panel_i } /* Call VESA BIOS 0x4f15 to get DDC availability, return status. */ -grub_vbe_status_t +static grub_vbe_status_t grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level) { struct grub_bios_int_registers regs; @@ -307,7 +307,7 @@ grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level) } /* Call VESA BIOS 0x4f15 to read EDID information, return status. */ -grub_vbe_status_t +static grub_vbe_status_t grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_info) { struct grub_bios_int_registers regs; diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index 0422558db..09ad7eb64 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -214,15 +214,6 @@ grub_vbe_bios_get_scanline_length (grub_uint32_t *length); grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x, grub_uint32_t *y); -/* Call VESA BIOS 0x4f11 to get flat panel information, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_flat_panel_info (struct grub_vbe_flat_panel_info *flat_panel_info); -/* Call VESA BIOS 0x4f15 to get DDC availability, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level); -/* Call VESA BIOS 0x4f15 to read EDID information, return status. */ -grub_vbe_status_t -grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_data); grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width); From 043603376e933098adea34156b0898814221c734 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 15 Jan 2011 21:58:21 +0100 Subject: [PATCH 0668/1414] * util/grub-mkimage.c (generate_image): Check fwstart.img checksum for safety. --- ChangeLog | 5 +++++ util/grub-mkimage.c | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/ChangeLog b/ChangeLog index 69534abe2..d275fd9b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-15 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Check fwstart.img checksum + for safety. + 2011-01-14 Vladimir Serbinenko * grub-core/kern/mips/yeeloong/init.c (grub_machine_init): Init boot diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 53e867602..0375d3ed5 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -1167,11 +1168,34 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t rom_size; 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 + 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"); boot_size = grub_util_get_image_size (boot_path); boot_img = grub_util_read_image (boot_path); + grub_memset (context, 0, sizeof (context)); + GRUB_MD_SHA512->init (context); + GRUB_MD_SHA512->write (context, boot_img, boot_size); + GRUB_MD_SHA512->final (context); + if (grub_memcmp (GRUB_MD_SHA512->read (context), fwstart_good_hash, + GRUB_MD_SHA512->mdlen) != 0) + grub_util_warn ("fwstart.img doesn't match the known good version. " + "Proceed at your own risk"); + rom_size = ALIGN_UP (core_size + boot_size, 512 * 1024); rom_img = xmalloc (rom_size); From 646ada34d11f26484ffe33e0cc80bcd06219ec8c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Jan 2011 12:54:03 +0100 Subject: [PATCH 0669/1414] * configure.ac: Bump version to 1.99~rc1. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d275fd9b6..8c39f7ba5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-16 Vladimir Serbinenko + + * configure.ac: Bump version to 1.99~rc1. + 2011-01-15 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Check fwstart.img checksum diff --git a/configure.ac b/configure.ac index 0b9207ea2..c660ac41e 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~beta0],[bug-grub@gnu.org]) +AC_INIT([GRUB],[1.99~rc1],[bug-grub@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) From 4f8ba1461b82f886557293c26da82fe590d556cd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 17 Jan 2011 11:56:36 +0000 Subject: [PATCH 0670/1414] Use low memory scratch area for EDID and FP calls. --- grub-core/video/i386/pc/vbe.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 29b67beeb..ea60c6074 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -383,7 +383,12 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) grub_vbe_status_t status; grub_uint8_t ddc_level; struct grub_video_edid_info edid_info; - struct grub_vbe_flat_panel_info flat_panel_info; + struct grub_vbe_flat_panel_info *flat_panel_info; + + /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ + flat_panel_info = (struct grub_vbe_flat_panel_info *) + (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + sizeof (struct grub_video_edid_info)); + grub_memset (flat_panel_info, 0, sizeof (*flat_panel_info)); if (controller_info.version >= 0x200 && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff) @@ -397,7 +402,7 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) grub_errno = GRUB_ERR_NONE; } - status = grub_vbe_bios_get_flat_panel_info (&flat_panel_info); + status = grub_vbe_bios_get_flat_panel_info (flat_panel_info); if (status == GRUB_VBE_STATUS_OK) { *width = flat_panel_info.horizontal_size; @@ -967,9 +972,18 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, static grub_err_t grub_video_vbe_get_edid (struct grub_video_edid_info *edid_info) { - if (grub_vbe_bios_read_edid (edid_info) != GRUB_VBE_STATUS_OK) + struct grub_video_edid_info *edid_info_lowmem; + + /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ + edid_info_lowmem = + (struct grub_video_edid_info *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (edid_info_lowmem, 0, sizeof (*edid_info_lowmem)); + + if (grub_vbe_bios_read_edid (edid_info_lowmem) != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "EDID information not available"); + grub_memcpy (edid_info, edid_info_lowmem, sizeof (*edid_info)); + return GRUB_ERR_NONE; } From cb918eddf4fd5c2d2d07ac5da6fa8074604b3e5f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 17 Jan 2011 12:05:12 +0000 Subject: [PATCH 0671/1414] fix FP info handling --- grub-core/video/i386/pc/vbe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index ea60c6074..c2b35a851 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -405,8 +405,8 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) status = grub_vbe_bios_get_flat_panel_info (flat_panel_info); if (status == GRUB_VBE_STATUS_OK) { - *width = flat_panel_info.horizontal_size; - *height = flat_panel_info.vertical_size; + *width = flat_panel_info->horizontal_size; + *height = flat_panel_info->vertical_size; return GRUB_ERR_NONE; } From 9b300caf8455dd0b8c3910330b063ff5777f0a36 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 17 Jan 2011 12:07:47 +0000 Subject: [PATCH 0672/1414] grub_video_get_edid is not usable from grub_vbe_get_preferred_mode, as a video adapter has not necessarily yet been set. Use grub_video_vbe_get_edid and grub_video_edid_checksum directly instead. Remove grub_video_get_edid as it now has no users. Reported by: Marjo Mercado. --- ChangeLog.vbe-autodetect | 4 +--- grub-core/video/i386/pc/vbe.c | 39 ++++++++++++++++++----------------- grub-core/video/video.c | 18 ---------------- include/grub/video.h | 1 - 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect index 46aacef7b..3341e8cc3 100644 --- a/ChangeLog.vbe-autodetect +++ b/ChangeLog.vbe-autodetect @@ -1,9 +1,8 @@ -2011-01-15 Colin Watson +2011-01-17 Colin Watson Preferred resolution detection for VBE. * grub-core/video/video.c (grub_video_edid_checksum): New function. - (grub_video_get_edid): Likewise. (grub_video_edid_preferred_mode): Likewise. Try EDID followed by the Flat Panel extension, in line with the X.org VESA driver. * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info): @@ -21,7 +20,6 @@ * include/grub/video.h (struct grub_vbe_edid_info): New structure. (struct grub_video_adapter): Add get_edid. (grub_video_edid_checksum): Add prototype. - (grub_video_get_edid): Likewise. (grub_video_edid_preferred_mode): Likewise. * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New structure. diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index c2b35a851..f94b06060 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -377,6 +377,24 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block) return GRUB_ERR_NONE; } +static grub_err_t +grub_video_vbe_get_edid (struct grub_video_edid_info *edid_info) +{ + struct grub_video_edid_info *edid_info_lowmem; + + /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ + edid_info_lowmem = + (struct grub_video_edid_info *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (edid_info_lowmem, 0, sizeof (*edid_info_lowmem)); + + if (grub_vbe_bios_read_edid (edid_info_lowmem) != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_BAD_DEVICE, "EDID information not available"); + + grub_memcpy (edid_info, edid_info_lowmem, sizeof (*edid_info)); + + return GRUB_ERR_NONE; +} + static grub_err_t grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) { @@ -394,7 +412,8 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff) == GRUB_VBE_STATUS_OK) { - if (grub_video_get_edid (&edid_info) == GRUB_ERR_NONE + if (grub_video_vbe_get_edid (&edid_info) == GRUB_ERR_NONE + && grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE && grub_video_edid_preferred_mode (&edid_info, width, height) == GRUB_ERR_NONE) return GRUB_ERR_NONE; @@ -969,24 +988,6 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, return grub_video_fb_get_info_and_fini (mode_info, framebuf); } -static grub_err_t -grub_video_vbe_get_edid (struct grub_video_edid_info *edid_info) -{ - struct grub_video_edid_info *edid_info_lowmem; - - /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ - edid_info_lowmem = - (struct grub_video_edid_info *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - grub_memset (edid_info_lowmem, 0, sizeof (*edid_info_lowmem)); - - if (grub_vbe_bios_read_edid (edid_info_lowmem) != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_BAD_DEVICE, "EDID information not available"); - - grub_memcpy (edid_info, edid_info_lowmem, sizeof (*edid_info)); - - return GRUB_ERR_NONE; -} - static void grub_video_vbe_print_adapter_specific_info (void) { diff --git a/grub-core/video/video.c b/grub-core/video/video.c index 84e98bb67..01bdd1ff3 100644 --- a/grub-core/video/video.c +++ b/grub-core/video/video.c @@ -393,24 +393,6 @@ grub_video_edid_checksum (struct grub_video_edid_info *edid_info) return grub_errno; } -grub_err_t -grub_video_get_edid (struct grub_video_edid_info *edid_info) -{ - if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); - - if (! grub_video_adapter_active->get_edid) - return grub_error (GRUB_ERR_BAD_DEVICE, - "EDID information unavailable for this video mode"); - - if (grub_video_adapter_active->get_edid (edid_info) != GRUB_ERR_NONE) - return grub_errno; - if (grub_video_edid_checksum (edid_info) != GRUB_ERR_NONE) - return grub_errno; - - return GRUB_ERR_NONE; -} - grub_err_t grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info, unsigned int *width, unsigned int *height) diff --git a/include/grub/video.h b/include/grub/video.h index 2251ed5f4..f42730a7d 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -486,7 +486,6 @@ grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_ grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); grub_err_t grub_video_edid_checksum (struct grub_video_edid_info *edid_info); -grub_err_t grub_video_get_edid (struct grub_video_edid_info *edid_info); grub_err_t grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info, unsigned int *width, unsigned int *height); From 5e79d66a547bd1e616defefef4cc5ab44d198a1e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 17 Jan 2011 12:48:07 +0000 Subject: [PATCH 0673/1414] * .bzrignore: Remove nonexistent grub-pbkdf2. --- .bzrignore | 1 - ChangeLog | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index 0cbb3f17f..a3e6f9dd2 100644 --- a/.bzrignore +++ b/.bzrignore @@ -44,7 +44,6 @@ grub-kbdcomp grub-macho2img grub-menulst2cfg grub-mk* -grub-pbkdf2 grub-pe2elf grub-probe grub_probe_init.c diff --git a/ChangeLog b/ChangeLog index 8c39f7ba5..a2d11d828 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-17 Colin Watson + + * .bzrignore: Remove nonexistent grub-pbkdf2. + 2011-01-16 Vladimir Serbinenko * configure.ac: Bump version to 1.99~rc1. From 01b08a0f15e12a1bcbea49b092a960645c9880fb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Jan 2011 13:44:16 +0100 Subject: [PATCH 0674/1414] 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 0675/1414] 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 0676/1414] 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 0677/1414] 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 0678/1414] 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 0679/1414] 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 81431e2b020371b57f747e2b3decdfbb00ed183e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 22 Jan 2011 01:11:56 +0000 Subject: [PATCH 0680/1414] * docs/grub.texi (Simple configuration): Document GRUB_PRELOAD_MODULES. --- ChangeLog | 5 +++++ docs/grub.texi | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index a2d11d828..75c713b9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-22 Colin Watson + + * docs/grub.texi (Simple configuration): Document + GRUB_PRELOAD_MODULES. + 2011-01-17 Colin Watson * .bzrignore: Remove nonexistent grub-pbkdf2. diff --git a/docs/grub.texi b/docs/grub.texi index daf48da13..a47389f1e 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1181,6 +1181,11 @@ directly to @ref{play}. If this option is set, GRUB will issue a @ref{badram} command to filter out specified regions of RAM. +@item GRUB_PRELOAD_MODULES +This option may be set to a list of GRUB module names separated by spaces. +Each module will be loaded as early as possible, at the start of +@file{grub.cfg}. + @end table For more detailed customisation of @command{grub-mkconfig}'s output, you may From 96e0a6ea9795fd2068d8f8e308d398fd3cb0e314 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 22 Jan 2011 01:26:49 +0000 Subject: [PATCH 0681/1414] * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Consider a path unreadable if `grub-probe -t abstraction' fails, for example if memberlist fails on an LVM volume group. Reported by: Darius Jahandarie. --- ChangeLog | 7 +++++++ util/grub-mkconfig_lib.in | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 75c713b9d..062f3c5a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-22 Colin Watson + + * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Consider a + path unreadable if `grub-probe -t abstraction' fails, for example if + memberlist fails on an LVM volume group. + Reported by: Darius Jahandarie. + 2011-01-22 Colin Watson * docs/grub.texi (Simple configuration): Document diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 2a48fb260..628ea34d4 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -61,6 +61,12 @@ is_path_readable_by_grub () return 1 fi + # ... or if we can't figure out the abstraction module, for example if + # memberlist fails on an LVM volume group. + if ${grub_probe} -t abstraction $path > /dev/null 2>&1 ; then : ; else + return 1 + fi + return 0 } From e489601ad0594bde0dc17257802beb7076976849 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 13:18:05 +0100 Subject: [PATCH 0682/1414] * grub-core/disk/raid.c (insert_array): Ensure uniqueness of p->number even if some elements have a name. Reported by: Alexander GQ Gerasiov. --- ChangeLog | 6 ++++++ grub-core/disk/raid.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 062f3c5a8..cb499bb01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-22 Vladimir Serbinenko + + * grub-core/disk/raid.c (insert_array): Ensure uniqueness of p->number + even if some elements have a name. + Reported by: Alexander GQ Gerasiov. + 2011-01-22 Colin Watson * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Consider a diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index c789fea50..3972e1632 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -570,7 +570,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, { for (p = array_list; p != NULL; p = p->next) { - if (! p->name && p->number == array->number) + if (p->number == array->number) break; } } From 5d4f4dd51b159de457a989c731c0012d0bbbac98 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 13:22:46 +0100 Subject: [PATCH 0683/1414] * grub-core/disk/scsi.c (grub_scsi_read): Fix binary and check and make logical expression more readable. --- ChangeLog | 5 +++++ grub-core/disk/scsi.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cb499bb01..16be610ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-22 Vladimir Serbinenko + + * grub-core/disk/scsi.c (grub_scsi_read): Fix binary and check and make + logical expression more readable. + 2011-01-22 Vladimir Serbinenko * grub-core/disk/raid.c (insert_array): Ensure uniqueness of p->number diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 902ab12c3..a40de278f 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -506,7 +506,7 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE) { unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS; - if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0)) + if (spb == 0 || (scsi->blocksize & (GRUB_DISK_SECTOR_SIZE - 1)) != 0) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported SCSI block size"); From 80f23be71fa11304d11e3dc549f1a20d0a492673 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 14:11:19 +0100 Subject: [PATCH 0684/1414] * grub-core/script/argv.c (round_up_exp): unsigned is 32-bit on all supported platforms. Put a compile time assert for this rather than generate a warning with 32-bit shift. --- ChangeLog | 6 ++++++ grub-core/script/argv.c | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 16be610ea..9e4ea21dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-22 Vladimir Serbinenko + + * grub-core/script/argv.c (round_up_exp): unsigned is 32-bit on all + supported platforms. Put a compile time assert for this rather than + generate a warning with 32-bit shift. + 2011-01-22 Vladimir Serbinenko * grub-core/disk/scsi.c (grub_scsi_read): Fix binary and check and make diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c index 50f810fcf..856828d7b 100644 --- a/grub-core/script/argv.c +++ b/grub-core/script/argv.c @@ -25,6 +25,8 @@ static unsigned round_up_exp (unsigned v) { + COMPILE_TIME_ASSERT (sizeof (v) == 4); + v--; v |= v >> 1; v |= v >> 2; @@ -32,9 +34,6 @@ round_up_exp (unsigned v) v |= v >> 8; v |= v >> 16; - if (sizeof (v) > 4) - v |= v >> 32; - v++; v += (v == 0); From ffc8f4d8bce3586d4dcd714c84eea558c902c8a8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 14:15:17 +0100 Subject: [PATCH 0685/1414] * grub-core/partmap/bsdlabel.c: Include grub/emu/misc.h and not grub/util/misc.h. (iterate_real): Don't rely on partition being non-NULL. --- ChangeLog | 5 +++++ grub-core/partmap/bsdlabel.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e4ea21dd..6593c4891 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-22 Vladimir Serbinenko + + * grub-core/partmap/bsdlabel.c: Include grub/emu/misc.h and not grub/util/misc.h. + (iterate_real): Don't rely on partition being non-NULL. + 2011-01-22 Vladimir Serbinenko * grub-core/script/argv.c (round_up_exp): unsigned is 32-bit on all diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 09ecd935a..4dec3851c 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -26,7 +26,7 @@ #include #ifdef GRUB_UTIL -#include +#include #endif static struct grub_partition_map grub_bsdlabel_partition_map; @@ -101,7 +101,8 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, #ifdef GRUB_UTIL char *partname; /* disk->partition != NULL as 0 < delta */ - partname = grub_partition_get_name (disk->partition); + partname = disk->partition ? grub_partition_get_name (disk->partition) + : ""; grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", disk->name, partname, p.partmap->name, p.number + 1); grub_free (partname); From 03a4ccb5134770375d5b8ed95e11ef6bfc296730 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 14:26:18 +0100 Subject: [PATCH 0686/1414] * grub-core/bus/bonito.c (write_bases): Fix direction of the shift. --- ChangeLog | 4 ++++ grub-core/bus/bonito.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6593c4891..f44a91c6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-22 Vladimir Serbinenko + + * grub-core/bus/bonito.c (write_bases): Fix direction of the shift. + 2011-01-22 Vladimir Serbinenko * grub-core/partmap/bsdlabel.c: Include grub/emu/misc.h and not grub/util/misc.h. diff --git a/grub-core/bus/bonito.c b/grub-core/bus/bonito.c index 3f794c45a..c2e0cd6ff 100644 --- a/grub-core/bus/bonito.c +++ b/grub-core/bus/bonito.c @@ -38,7 +38,7 @@ write_bases (void) for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT) & GRUB_MACHINE_PCI_WIN_MASK) - >> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE)); + << (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE)); GRUB_MACHINE_PCI_IO_CTRL_REG = reg; } From 37f4f60828307e35cac458e5b832d4a36aaa0471 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 15:10:29 +0100 Subject: [PATCH 0687/1414] * util/grub-install.in: Ignore install device on platforms where it doesn't make sense. Always use UUIDs except on pc, efi and sparc64. Reported by: Daniel Kahn Gillmor. --- ChangeLog | 7 +++++++ util/grub-install.in | 26 ++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index f44a91c6b..ce6b6f7cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-01-22 Vladimir Serbinenko + + * util/grub-install.in: Ignore install device on platforms + where it doesn't make sense. Always use UUIDs except on pc, efi and + sparc64. + Reported by: Daniel Kahn Gillmor. + 2011-01-22 Vladimir Serbinenko * grub-core/bus/bonito.c (write_bases): Fix direction of the shift. diff --git a/util/grub-install.in b/util/grub-install.in index 90360c279..1ae00b2fd 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -270,6 +270,11 @@ if test "x$install_device" = x && ([ "${target_cpu}-${platform}" = "i386-pc" ] \ exit 1 fi +if ! ([ "${target_cpu}-${platform}" = "i386-pc" ] \ + || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ]); then + install_device= +fi + # If the debugging feature is enabled, print commands. setup_verbose= if test x"$debug" = xyes; then @@ -516,27 +521,24 @@ if [ "x${devabstraction_module}" = "x" ] ; then # Strip partition number grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`" grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`" - if [ "$disk_module" = ata ] ; then + if [ "$disk_module" = ata ] || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]) ; then # generic method (used on coreboot and ata mod) uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" if [ "x${uuid}" = "x" ] ; then - echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]; then + echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + elif [ "$disk_module" = ata ]; then + echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + else + echo "UUID needed with cross-disk installs, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + fi + exit 1 fi echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg" echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" - elif [ "x${grub_drive}" != "x${install_drive}" ] ; then - uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" - if [ "x${uuid}" = "x" ] ; then - echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 - exit 1 - fi - echo "search.fs_uuid ${uuid} root " >> ${grubdir}/load.cfg - echo 'set prefix=($root)'"${relative_grubdir}" >> ${grubdir}/load.cfg - config_opt="-c ${grubdir}/load.cfg " - modules="$modules search_fs_uuid" elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ]; then # we need to hardcode the partition number in the core image's prefix. if [ x"$grub_partition" = x ]; then From 5d4c5f891446f913ced217af1712a8d903449fe0 Mon Sep 17 00:00:00 2001 From: Anthony DeRobertis Date: Sat, 22 Jan 2011 15:20:08 +0100 Subject: [PATCH 0688/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Check super_offset field. --- grub-core/disk/mdraid1x_linux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index 155210df3..f2e7555cb 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -143,7 +143,8 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, &sb)) return grub_errno; - if (grub_le_to_cpu32 (sb.magic) != SB_MAGIC) + if (grub_le_to_cpu32 (sb.magic) != SB_MAGIC + || grub_le_to_cpu64 (sb.super_offset) != sector) continue; { From 73ae4f4ff55b39739352daf133ac4e9562e7f98e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 15:30:48 +0100 Subject: [PATCH 0689/1414] Add missing ChangeLog entry --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index ce6b6f7cf..ba611afad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-22 Anthony DeRobertis + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Check + super_offset field. + 2011-01-22 Vladimir Serbinenko * util/grub-install.in: Ignore install device on platforms From 3533413cd5efc9630436511b57d77f24c6afd0a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 22 Jan 2011 15:37:05 +0100 Subject: [PATCH 0690/1414] * grub-core/kern/emu/getroot.c: Include config-util.h explicitly. --- ChangeLog | 4 ++++ grub-core/kern/emu/getroot.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index ba611afad..edb7d46f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-01-22 Vladimir Serbinenko + + * grub-core/kern/emu/getroot.c: Include config-util.h explicitly. + 2011-01-22 Anthony DeRobertis * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Check diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index aedef9e0e..110e58b14 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -17,7 +17,9 @@ * along with GRUB. If not, see . */ +#include #include + #include #include #include From ea9e017dc5064da8a8f8d336785bd1937d1b6737 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Jan 2011 21:50:09 +0100 Subject: [PATCH 0691/1414] 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 0692/1414] 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 0693/1414] 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 0694/1414] 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 0695/1414] 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 0696/1414] 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 0697/1414] 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 0698/1414] 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 0699/1414] 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 0700/1414] 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 0701/1414] 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 3281d3d6d43ac50dab55cbed9b337ac4d8e17dac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Jan 2011 02:44:27 +0100 Subject: [PATCH 0702/1414] * util/grub-mkimage.c (generate_image): Refuse to create the images bigger than the actual flash (512K) in Loongson machines. 512K is also the biggest chip supported by them. --- ChangeLog | 6 ++++++ util/grub-mkimage.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index edb7d46f7..514ce4ef8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-24 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Refuse to create the images + bigger than the actual flash (512K) in Loongson machines. 512K is also + the biggest chip supported by them. + 2011-01-22 Vladimir Serbinenko * grub-core/kern/emu/getroot.c: Include config-util.h explicitly. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 0375d3ed5..876e9c9b2 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1196,7 +1196,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_warn ("fwstart.img doesn't match the known good version. " "Proceed at your own risk"); - rom_size = ALIGN_UP (core_size + boot_size, 512 * 1024); + if (core_size + boot_size > 512 * 1024) + grub_util_error ("firmware image is too big"); + rom_size = 512 * 1024; rom_img = xmalloc (rom_size); memset (rom_img, 0, rom_size); From 307ed0b484330ed600cb01e33f45f6a974aae7c1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 25 Jan 2011 12:28:11 +0000 Subject: [PATCH 0703/1414] 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 0704/1414] 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 800f188183cf4d45bbd13eb94e1c2419888b76b2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 Jan 2011 17:01:28 +0000 Subject: [PATCH 0705/1414] * docs/grub.texi (Making a GRUB bootable CD-ROM): Update to describe grub-mkrescue. --- ChangeLog | 5 +++++ docs/grub.texi | 48 +++++++++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 514ce4ef8..019a6746c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-28 Colin Watson + + * docs/grub.texi (Making a GRUB bootable CD-ROM): Update to describe + grub-mkrescue. + 2011-01-24 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Refuse to create the images diff --git a/docs/grub.texi b/docs/grub.texi index a47389f1e..c815bcbbe 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -651,15 +651,22 @@ using BIOS functions.}. This means that you can use the whole CD-ROM from GRUB and you don't have to make a floppy or hard disk image file, which can cause compatibility problems. -For booting from a CD-ROM, GRUB uses a special Stage 2 called -@file{stage2_eltorito}. The only GRUB files you need to have in your -bootable CD-ROM are this @file{stage2_eltorito} and optionally a config file -@file{grub.cfg}. You don't need to use @file{stage1} or @file{stage2}, -because El Torito is quite different from the standard boot process. +For booting from a CD-ROM, GRUB uses a special image called +@file{cdboot.img}, which is concatenated with @file{core.img}. The +@file{core.img} used for this should be built with at least the +@samp{iso9660} and @samp{biosdisk} modules. Your bootable CD-ROM will +usually also need to include a configuration file @file{grub.cfg} and some +other GRUB modules. -Here is an example of procedures to make a bootable CD-ROM -image. First, make a top directory for the bootable image, say, -@samp{iso}: +To make a simple generic GRUB rescue CD, you can use the +@command{grub-mkrescue} program: + +@example +$ @kbd{grub-mkrescue -o grub.iso} +@end example + +You will often need to include other files in your image. To do this, first +make a top directory for the bootable image, say, @samp{iso}: @example $ @kbd{mkdir iso} @@ -671,33 +678,24 @@ Make a directory for GRUB: $ @kbd{mkdir -p iso/boot/grub} @end example -Copy the file @file{stage2_eltorito}: - -@example -$ @kbd{cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub} -@end example - If desired, make the config file @file{grub.cfg} under @file{iso/boot/grub} (@pxref{Configuration}), and copy any files and directories for the disc to the directory @file{iso/}. -Finally, make a ISO9660 image file like this: +Finally, make the image: @example -$ @kbd{mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot \ - -boot-load-size 4 -boot-info-table -o grub.iso iso} +$ @kbd{grub-mkrescue -o grub.iso iso} @end example This produces a file named @file{grub.iso}, which then can be burned -into a CD (or a DVD). @kbd{mkisofs} has already set up the disc to boot -from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to -setup GRUB on the disc. (Note that the @kbd{-boot-load-size 4} bit is -required for compatibility with the BIOS on many older machines.) +into a CD (or a DVD), or written to a USB mass storage device. -You can use the device @samp{(cd)} to access a CD-ROM in your -config file. This is not required; GRUB automatically sets the root device -to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to -@samp{(cd)} if you want to access other drives as well. +The root device will be set up appropriately on entering your +@file{grub.cfg} configuration file, so you can refer to file names on the CD +without needing to use an explicit device name. This makes it easier to +produce rescue images that will work on both optical drives and USB mass +storage devices. @node Device map From 8c2c4ff2f533cf37c2025655497f3dfc8cfd5eef Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Feb 2011 13:33:16 +0000 Subject: [PATCH 0706/1414] Handle empty dir passed to grub_find_root_device_from_mountinfo; fixes grub-mkrelpath on btrfs subvolumes. --- grub-core/kern/emu/getroot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 92ff971e5..c1ed35b2d 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -111,6 +111,8 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) size_t len = 0; char *ret = NULL; + if (! *dir) + dir = "/"; if (relroot) *relroot = NULL; From 5870a4a06f11059defad9ff546b7b2811a838873 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Feb 2011 16:35:07 +0000 Subject: [PATCH 0707/1414] typo --- grub-core/fs/btrfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index b7c59065c..ac90c055a 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -729,7 +729,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t paddr; stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); - /* Right now the redundancy handlind is easy. + /* Right now the redundancy handling is easy. With RAID5-like it will be more difficult. */ stripe += stripen + i; From 7e735e4349c2c408dd5420882ed206d8d34d78ce Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Feb 2011 13:21:13 +0000 Subject: [PATCH 0708/1414] * include/grub/file.h (not_easly_seekable): Rename to ... (not_easily_seekable): ... this. Update all users. --- ChangeLog | 5 +++++ grub-core/fs/i386/pc/pxe.c | 2 +- grub-core/io/bufio.c | 2 +- grub-core/io/gzio.c | 2 +- grub-core/io/xzio.c | 2 +- include/grub/file.h | 6 +++--- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 019a6746c..d3325ac6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-02-08 Colin Watson + + * include/grub/file.h (not_easly_seekable): Rename to ... + (not_easily_seekable): ... this. Update all users. + 2011-01-28 Colin Watson * docs/grub.texi (Making a GRUB bootable CD-ROM): Update to describe diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index e2b53d637..a3b055f3d 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -281,7 +281,7 @@ grub_pxefs_open (struct grub_file *file, const char *name) } file->data = data; - file->not_easly_seekable = 1; + file->not_easily_seekable = 1; grub_memcpy (file_int, file, sizeof (struct grub_file)); curr_file = file_int; diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c index 8a72ecd79..891fb78e9 100644 --- a/grub-core/io/bufio.c +++ b/grub-core/io/bufio.c @@ -74,7 +74,7 @@ grub_bufio_open (grub_file_t io, int size) file->data = bufio; file->read_hook = 0; file->fs = &grub_bufio_fs; - file->not_easly_seekable = io->not_easly_seekable; + file->not_easily_seekable = io->not_easily_seekable; return file; } diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index f563d7b92..47df23833 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -1136,7 +1136,7 @@ grub_gzio_open (grub_file_t io) file->data = gzio; file->read_hook = 0; file->fs = &grub_gzio_fs; - file->not_easly_seekable = 1; + file->not_easily_seekable = 1; if (! test_header (file)) { diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index 37be1790f..3daf6a3fe 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -200,7 +200,7 @@ grub_xzio_open (grub_file_t io) file->read_hook = 0; file->fs = &grub_xzio_fs; file->size = GRUB_FILE_SIZE_UNKNOWN; - file->not_easly_seekable = 1; + file->not_easily_seekable = 1; if (grub_file_tell (xzio->file) != 0) grub_file_seek (xzio->file, 0); diff --git a/include/grub/file.h b/include/grub/file.h index 72cd45468..3adb1706f 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -39,8 +39,8 @@ struct grub_file /* The file size. */ grub_off_t size; - /* If file is not easly seekable. Should be set by underlying layer. */ - int not_easly_seekable; + /* If file is not easily seekable. Should be set by underlying layer. */ + int not_easily_seekable; /* Filesystem-specific data. */ void *data; @@ -123,7 +123,7 @@ grub_file_tell (const grub_file_t file) static inline int grub_file_seekable (const grub_file_t file) { - return !file->not_easly_seekable; + return !file->not_easily_seekable; } #endif /* ! GRUB_FILE_HEADER */ From 22b28eb3fe78a38e1be478d70bd8da1a75f784de Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 9 Feb 2011 11:23:11 +0000 Subject: [PATCH 0709/1414] * util/grub-install.in: Remove unnecessary brackets from tr arguments. * util/grub.d/10_hurd.in: Likewise. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. * util/grub.d/20_linux_xen.in: Likewise. Reported by: Jamie Heilman. Fixes Debian bug #612564. --- ChangeLog | 10 ++++++++++ util/grub-install.in | 2 +- util/grub.d/10_hurd.in | 2 +- util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- util/grub.d/20_linux_xen.in | 2 +- 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3325ac6b..6517450ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-02-09 Colin Watson + + * util/grub-install.in: Remove unnecessary brackets from tr + arguments. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + Reported by: Jamie Heilman. Fixes Debian bug #612564. + 2011-02-08 Colin Watson * include/grub/file.h (not_easly_seekable): Rename to ... diff --git a/util/grub-install.in b/util/grub-install.in index 1ae00b2fd..af3034e03 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -64,7 +64,7 @@ if test -f "${sysconfdir}/default/grub" ; then . "${sysconfdir}/default/grub" fi -bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut -d' ' -f1)" +bootloader_id="$(echo "$GRUB_DISTRIBUTOR" | tr 'A-Z' 'a-z' | cut -d' ' -f1)" if test -z "$bootloader_id"; then bootloader_id=grub fi diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index eeb441aa4..8c54eab97 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -28,7 +28,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU else OS="${GRUB_DISTRIBUTOR} GNU/Hurd" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" fi at_least_one=false diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index b026812a7..dce5e945c 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -31,7 +31,7 @@ CLASS="--class os" case "${GRUB_DISTRIBUTOR}" in Debian) OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) --class gnu-kfreebsd --class gnu ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) --class gnu-kfreebsd --class gnu ${CLASS}" ;; *) OS="FreeBSD" diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index a09c3e687..491d2b5ce 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -32,7 +32,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux else OS="${GRUB_DISTRIBUTOR} GNU/Linux" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" fi # loop-AES arranges things so that /dev/loop/X can be our root device, but diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index ee49cd903..356219e1d 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -32,7 +32,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux else OS="${GRUB_DISTRIBUTOR} GNU/Linux" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" fi # loop-AES arranges things so that /dev/loop/X can be our root device, but From 97286eb54770ce840063ee0740c4a4923aaa28de Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 9 Feb 2011 12:14:10 +0000 Subject: [PATCH 0710/1414] * docs/grub.texi (Kernel): Add reference to grub-mkrescue. (Making a GRUB bootable CD-ROM): Likewise. (Invoking grub-mkrescue): New section. Reported by: Yann Dirson. Fixes Debian bug #612585. --- ChangeLog | 7 ++++++ docs/grub.texi | 62 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6517450ce..56498af1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-02-09 Colin Watson + + * docs/grub.texi (Kernel): Add reference to grub-mkrescue. + (Making a GRUB bootable CD-ROM): Likewise. + (Invoking grub-mkrescue): New section. + Reported by: Yann Dirson. Fixes Debian bug #612585. + 2011-02-09 Colin Watson * util/grub-install.in: Remove unnecessary brackets from tr diff --git a/docs/grub.texi b/docs/grub.texi index c815bcbbe..590e6afb7 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -36,6 +36,7 @@ Invariant Sections. * grub-install: (grub)Invoking grub-install. Install GRUB on your drive * grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration * grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. +* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image @end direntry @setchapternewpage odd @@ -94,6 +95,7 @@ This edition documents version @value{VERSION}. * Invoking grub-mkconfig:: Generate a GRUB configuration file * Invoking grub-mkpasswd-pbkdf2:: Generate GRUB password hashes +* Invoking grub-mkrescue:: Make a GRUB rescue image * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -659,7 +661,7 @@ usually also need to include a configuration file @file{grub.cfg} and some other GRUB modules. To make a simple generic GRUB rescue CD, you can use the -@command{grub-mkrescue} program: +@command{grub-mkrescue} program (@pxref{Invoking grub-mkrescue}): @example $ @kbd{grub-mkrescue -o grub.iso} @@ -3609,6 +3611,64 @@ Length of the salt. Defaults to 64. @end table +@node Invoking grub-mkrescue +@chapter Invoking grub-mkrescue + +The program @command{grub-mkrescue} generates a bootable GRUB rescue image +(@pxref{Making a GRUB bootable CD-ROM}). + +@example +grub-mkrescue -o grub.iso +@end example + +All arguments not explicitly listed as @command{grub-mkrescue} options are +passed on directly to @command{xorriso} in @command{mkisofs} emulation mode. +Options passed to @command{xorriso} will normally be interpreted as +@command{mkisofs} options; if the option @samp{--} is used, then anything +after that will be interpreted as native @command{xorriso} options. + +Non-option arguments specify additional source directories. This is +commonly used to add extra files to the image: + +@example +mkdir -p disk/boot/grub +@r{(add extra files to @file{disk/boot/grub})} +grub-mkrescue -o grub.iso disk +@end example + +@command{grub-mkrescue} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version number of GRUB and exit. + +@item -o @var{file} +@itemx --output=@var{file} +Save output in @var{file}. This "option" is required. + +@item --modules=@var{modules} +Pre-load the named GRUB modules in the image. Multiple entries in +@var{modules} should be separated by whitespace (so you will probably need +to quote this for your shell). + +@item --rom-directory=@var{dir} +If generating images for the QEMU or Coreboot platforms, copy the resulting +@file{qemu.img} or @file{coreboot.elf} files respectively to the @var{dir} +directory as well as including them in the image. + +@item --xorriso=@var{file} +Use @var{file} as the @command{xorriso} program, rather than the built-in +default. + +@item --grub-mkimage=@var{file} +Use @var{file} as the @command{grub-mkimage} program, rather than the +built-in default. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB From fee7cdd4e1bdc0618e01307477e5c115ee76a6dc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Feb 2011 13:00:54 +0000 Subject: [PATCH 0711/1414] * util/grub.d/20_linux_xen.in: Bail out early if linux_list is empty, since in that case we can only generate either nothing or a syntactically invalid configuration file. Reported by: Michal Suchanek. Fixes Debian bug #612898. --- ChangeLog | 7 +++++++ util/grub.d/20_linux_xen.in | 3 +++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 56498af1b..6e9ab5758 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-02-11 Colin Watson + + * util/grub.d/20_linux_xen.in: Bail out early if linux_list is + empty, since in that case we can only generate either nothing or a + syntactically invalid configuration file. + Reported by: Michal Suchanek. Fixes Debian bug #612898. + 2011-02-09 Colin Watson * docs/grub.texi (Kernel): Add reference to grub-mkrescue. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 356219e1d..e71fc1458 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -98,6 +98,9 @@ linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") if grub_file_is_not_garbage "$i" && grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null ; then echo -n "$i " ; fi done` +if [ "x${linux_list}" = "x" ] ; then + exit 0 +fi xen_list=`for i in /boot/xen*; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` From d998657dcf8be2a6d4e93f004519e63b66af22cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Feb 2011 09:59:04 +0300 Subject: [PATCH 0712/1414] * grub-core/partmap/msdos.c (pc_partition_map_embed): Fix off by one error. --- ChangeLog | 5 +++++ grub-core/partmap/msdos.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e9ab5758..3a695b25a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-02-12 Vladimir Serbinenko + + * grub-core/partmap/msdos.c (pc_partition_map_embed): Fix off by one + error. + 2011-02-11 Colin Watson * util/grub.d/20_linux_xen.in: Bail out early if linux_list is diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index d411c4405..31a0a0707 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -232,10 +232,10 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, break; } - if (end >= *nsectors + 1) + if (end >= *nsectors + 2) { unsigned i; - *nsectors = end - 1; + *nsectors = end - 2; *sectors = grub_malloc (*nsectors * sizeof (**sectors)); if (!*sectors) return grub_errno; From 028501a0e06877f14e2445f73a8969bced63c10f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Feb 2011 10:22:55 +0300 Subject: [PATCH 0713/1414] Workaround yet another IEEE1275 bug. * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS. * grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate): Ignore adress_cells and size:cells if GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS is set. * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS on powermacs. --- ChangeLog | 12 ++++++++++++ grub-core/kern/ieee1275/cmain.c | 3 +++ grub-core/kern/ieee1275/mmap.c | 6 ++++++ include/grub/ieee1275/ieee1275.h | 6 ++++++ 4 files changed, 27 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3a695b25a..72d718b08 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-02-12 Vladimir Serbinenko + + Workaround yet another IEEE1275 bug. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value + GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS. + * grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate): Ignore + adress_cells and size:cells if GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS + is set. + * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS on powermacs. + 2011-02-12 Vladimir Serbinenko * grub-core/partmap/msdos.c (pc_partition_map_embed): Fix off by one diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c index 30eacbbdd..2fbe809b2 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c @@ -84,6 +84,9 @@ grub_ieee1275_find_options (void) if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC")) is_qemu = 1; + if (grub_strncmp (tmp, "PowerMac", sizeof ("PowerMac") - 1) == 0) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS); + if (is_smartfirmware) { /* Broken in all versions */ diff --git a/grub-core/kern/ieee1275/mmap.c b/grub-core/kern/ieee1275/mmap.c index 942e5a354..2e4e085bb 100644 --- a/grub-core/kern/ieee1275/mmap.c +++ b/grub-core/kern/ieee1275/mmap.c @@ -50,6 +50,12 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't examine /memory/available property"); + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS)) + { + address_cells = 1; + size_cells = 1; + } + /* Decode each entry and call `hook'. */ i = 0; available_size /= sizeof (grub_uint32_t); diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 2592dd348..4c56cc20f 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -106,6 +106,12 @@ enum grub_ieee1275_flag /* OLPC / XO firmware has the cursor ON/OFF routines. */ GRUB_IEEE1275_FLAG_HAS_CURSORONOFF, + + /* Some PowerMacs claim to use 2 address cells but in fact use only 1. + Other PowerMacs claim to use only 1 and really do so. Always assume + 1 address cell is used on PowerMacs. + */ + GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); From 54da1febceee8e07edf6b58f31952648897ba689 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 19 Feb 2011 13:18:05 +0100 Subject: [PATCH 0714/1414] 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 57d75699d6eff414d65bd0cc704c2b86be518c94 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Mar 2011 22:23:06 +0100 Subject: [PATCH 0715/1414] 2011-03-07 Szymon Janc * grub-core/fs/zfs/zfs.c (zap_leaf_lookup): Set-but-not-used variable removed. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 72d718b08..d8a8d1fc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-07 Szymon Janc + + * grub-core/fs/zfs/zfs.c (zap_leaf_lookup): + Set-but-not-used variable removed. + 2011-02-12 Vladimir Serbinenko Workaround yet another IEEE1275 bug. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 5b575f369..3a94d8874 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -837,14 +837,12 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, name)) { struct zap_leaf_array *la; - grub_uint8_t *ip; if (le->le_int_size != 8 || le->le_value_length != 1) return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); /* get the uint64_t property value */ la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array; - ip = la->la_array; *value = grub_be_to_cpu64 (la->la_array64); From 83a3c48d3749b64eda1708f2d76efd18f2d6e487 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 9 Mar 2011 17:35:16 +0000 Subject: [PATCH 0716/1414] * docs/grub.texi (Simple configuration): Tidy up formatting. --- ChangeLog | 4 ++++ docs/grub.texi | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8a8d1fc2..103706af0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-09 Colin Watson + + * docs/grub.texi (Simple configuration): Tidy up formatting. + 2011-03-07 Szymon Janc * grub-core/fs/zfs/zfs.c (zap_leaf_lookup): diff --git a/docs/grub.texi b/docs/grub.texi index 590e6afb7..83bd80023 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1036,8 +1036,8 @@ it as a new default entry for use by future runs of GRUB. This is only useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because @samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with @command{grub-set-default} or @command{grub-reboot}. Unset by default. -The remarks of @pxref{Changes from GRUB Legacy} on the availability -of @samp{save_env} apply. +@samp{save_env} may not be available in all situations +(@pxref{Changes from GRUB Legacy}). @item GRUB_TIMEOUT Boot the default entry this many seconds after the menu is displayed, unless From be1a7ce0cfdd3ada7298abae16168a16bc551e96 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 9 Mar 2011 17:38:31 +0000 Subject: [PATCH 0717/1414] * grub-core/loader/i386/linux.c (find_efi_mmap_size): Page-align cached mmap_size, so that this works correctly when called multiple times. Reported by: Daniel Kahn Gillmor. Should fix Debian bug #616638. --- ChangeLog | 7 +++++++ grub-core/loader/i386/linux.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 103706af0..0406cf91f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-03-09 Colin Watson + + * grub-core/loader/i386/linux.c (find_efi_mmap_size): Page-align + cached mmap_size, so that this works correctly when called multiple + times. + Reported by: Daniel Kahn Gillmor. Should fix Debian bug #616638. + 2011-03-09 Colin Watson * docs/grub.texi (Simple configuration): Tidy up formatting. diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 80960570b..0178e2fd4 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -136,7 +136,8 @@ find_efi_mmap_size (void) later, and EFI itself may allocate more. */ mmap_size += (1 << 12); - return page_align (mmap_size); + mmap_size = page_align (mmap_size); + return mmap_size; } #endif From 9b43bf396a61b60a0ee4b8a1591634b1120b8906 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Mar 2011 11:51:10 +0000 Subject: [PATCH 0718/1414] * grub-core/boot/i386/pc/lnxboot.S (real_code_2): Ensure that the initial chunk read from the kernel always includes GRUB's multiboot header, which is now outside the first sector. --- ChangeLog | 6 ++++++ grub-core/boot/i386/pc/lnxboot.S | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0406cf91f..08b937dcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-11 Colin Watson + + * grub-core/boot/i386/pc/lnxboot.S (real_code_2): Ensure that the + initial chunk read from the kernel always includes GRUB's multiboot + header, which is now outside the first sector. + 2011-03-09 Colin Watson * grub-core/loader/i386/linux.c (find_efi_mmap_size): Page-align diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index 9a599c261..2c7596026 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -178,8 +178,13 @@ real_code_2: pushw %es popw %ds +#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200 movl $0x200, %ecx addl %ecx, %esi +#else + movl $(GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4), %ecx + addl $0x200, %esi +#endif movl $DATA_ADDR, %edi call LOCAL(move_memory) @@ -196,7 +201,11 @@ real_code_2: 1: movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx +#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200 addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx +#else + addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx +#endif 2: call LOCAL(move_memory) From 2da48d28d998f8d85868fae5debd238d2b3994d4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 11:52:04 +0100 Subject: [PATCH 0719/1414] * util/grub-install.in: Correct the x86-64 name as x86_64. --- ChangeLog | 4 ++++ util/grub-install.in | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08b937dcb..6218e9f12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-23 Vladimir Serbinenko + + * util/grub-install.in: Correct the x86-64 name as x86_64. + 2011-03-11 Colin Watson * grub-core/boot/i386/pc/lnxboot.S (real_code_2): Ensure that the diff --git a/util/grub-install.in b/util/grub-install.in index af3034e03..b4a4b3f26 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -367,7 +367,7 @@ if [ x"$platform" = xefi ]; then case "$target_cpu" in i386) efi_file=BOOTIA32.EFI ;; - x86-64) + x86_64) efi_file=BOOTX64.EFI ;; # GRUB does not yet support these architectures, but they're defined # by the specification so we include them here to ease future @@ -381,7 +381,7 @@ if [ x"$platform" = xefi ]; then case "$target_cpu" in i386) efi_file=grubia32.efi ;; - x86-64) + x86_64) efi_file=grubx64.efi ;; # GRUB does not yet support these architectures, but they're defined # by the specification so we include them here to ease future From 40fc46599d1421ed892d9eb2cd0277850791ef35 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 11:54:58 +0100 Subject: [PATCH 0720/1414] * grub-core/video/bochs.c (grub_video_bochs_setup): Use grub_video_mode_type_t. * grub-core/video/cirrus.c (grub_video_cirrus_setup): Likewise. * grub-core/video/i386/pc/vbe.c (grub_video_vbe_setup): Likewise. * grub-core/video/i386/pc/vga.c (grub_video_vga_setup): Likewise. --- ChangeLog | 8 ++++++++ grub-core/video/bochs.c | 3 ++- grub-core/video/cirrus.c | 3 ++- grub-core/video/i386/pc/vbe.c | 3 ++- grub-core/video/i386/pc/vga.c | 3 ++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6218e9f12..20fdfc86c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/video/bochs.c (grub_video_bochs_setup): Use + grub_video_mode_type_t. + * grub-core/video/cirrus.c (grub_video_cirrus_setup): Likewise. + * grub-core/video/i386/pc/vbe.c (grub_video_vbe_setup): Likewise. + * grub-core/video/i386/pc/vga.c (grub_video_vga_setup): Likewise. + 2011-03-23 Vladimir Serbinenko * util/grub-install.in: Correct the x86-64 name as x86_64. diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c index 5def0985b..832cd9903 100644 --- a/grub-core/video/bochs.c +++ b/grub-core/video/bochs.c @@ -199,7 +199,8 @@ grub_video_bochs_set_palette (unsigned int start, unsigned int count, static grub_err_t grub_video_bochs_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask) + grub_video_mode_type_t mode_type, + grub_video_mode_type_t mode_mask) { int depth; grub_err_t err; diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c index b8b0142ad..a964c85cd 100644 --- a/grub-core/video/cirrus.c +++ b/grub-core/video/cirrus.c @@ -235,7 +235,8 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count, static grub_err_t grub_video_cirrus_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask) + grub_video_mode_type_t mode_type, + grub_video_mode_type_t mode_mask) { int depth; grub_err_t err; diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 2ddb4ca80..08bf124b6 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -688,7 +688,8 @@ grub_video_vbe_iterate (int (*hook) (const struct grub_video_mode_info *info)) static grub_err_t grub_video_vbe_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask) + grub_video_mode_type_t mode_type, + grub_video_mode_type_t mode_mask) { grub_uint16_t *p; struct grub_vbe_mode_info_block vbe_mode_info; diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c index 41b8d3eb1..19770ce0a 100644 --- a/grub-core/video/i386/pc/vga.c +++ b/grub-core/video/i386/pc/vga.c @@ -116,7 +116,8 @@ grub_video_vga_init (void) static grub_err_t grub_video_vga_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask) + grub_video_mode_type_t mode_type, + grub_video_mode_type_t mode_mask) { grub_err_t err; From 7d4e39d65a7102579e219ba52dccbb3830617ede Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:05:13 +0100 Subject: [PATCH 0721/1414] * grub-core/bus/usb/usb.c (attach_hooks): Make static. * grub-core/bus/usb/usbhub.c (hubs): Likewise. * grub-core/commands/hashsum.c (aliases): Likewise. * grub-core/commands/setpci.c (pci_registers): Likewise. * grub-core/disk/usbms.c (attach_hook): Likewise. * grub-core/fs/zfs/zfs.c (decomp_table): Likewise. (zio_checksum_table): Likewise. * grub-core/gettext/gettext.c (grub_gettext_msg_list): Likewise. * grub-core/gfxmenu/gfxmenu.c (cached_view): Likewise. * grub-core/lib/legacy_parse.c (legacy_commands): Likewise. * grub-core/lib/relocator.c (leftovers): Likewise. (extra_blocks): Likewise. * grub-core/loader/i386/bsd.c (relocator): Likewise. * grub-core/loader/i386/multiboot_mbi.c (modules): Likewise. (modules_last): Likewise. * grub-core/loader/i386/xnu.c (table_aliases): Likewise. (devices): Likewise. * grub-core/loader/multiboot_mbi2.c (modules): Likewise. (modules_last): Likewise. * grub-core/normal/auth.c (users): Likewise. * grub-core/normal/context.c (initial_menu): Likewise. (current_menu): Likewise. * grub-core/normal/crypto.c (crypto_specs): Likewise. * grub-core/term/serial.c (grub_serial_ports): Likewise. (grub_serial_terminfo_input_template): Likewise. (grub_serial_terminfo_output_template): Likewise. (grub_serial_terminfo_input): Likewise. (grub_serial_terminfo_output): Likewise. (registered): Likewise. * grub-core/term/usb_keyboard.c (attach_hook): Likewise. --- ChangeLog | 33 +++++++++++++++++++++++++++ grub-core/bus/usb/usb.c | 2 +- grub-core/bus/usb/usbhub.c | 2 +- grub-core/commands/hashsum.c | 2 +- grub-core/commands/setpci.c | 2 +- grub-core/disk/usbms.c | 2 +- grub-core/fs/zfs/zfs.c | 4 ++-- grub-core/gettext/gettext.c | 2 +- grub-core/gfxmenu/gfxmenu.c | 2 +- grub-core/lib/legacy_parse.c | 2 +- grub-core/lib/relocator.c | 4 ++-- grub-core/loader/i386/bsd.c | 2 +- grub-core/loader/i386/multiboot_mbi.c | 2 +- grub-core/loader/i386/xnu.c | 4 ++-- grub-core/loader/multiboot_mbi2.c | 2 +- grub-core/normal/auth.c | 2 +- grub-core/normal/context.c | 4 ++-- grub-core/normal/crypto.c | 2 +- grub-core/term/serial.c | 12 +++++----- grub-core/term/usb_keyboard.c | 2 +- 20 files changed, 61 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 20fdfc86c..9527a6e8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/bus/usb/usb.c (attach_hooks): Make static. + * grub-core/bus/usb/usbhub.c (hubs): Likewise. + * grub-core/commands/hashsum.c (aliases): Likewise. + * grub-core/commands/setpci.c (pci_registers): Likewise. + * grub-core/disk/usbms.c (attach_hook): Likewise. + * grub-core/fs/zfs/zfs.c (decomp_table): Likewise. + (zio_checksum_table): Likewise. + * grub-core/gettext/gettext.c (grub_gettext_msg_list): Likewise. + * grub-core/gfxmenu/gfxmenu.c (cached_view): Likewise. + * grub-core/lib/legacy_parse.c (legacy_commands): Likewise. + * grub-core/lib/relocator.c (leftovers): Likewise. + (extra_blocks): Likewise. + * grub-core/loader/i386/bsd.c (relocator): Likewise. + * grub-core/loader/i386/multiboot_mbi.c (modules): Likewise. + (modules_last): Likewise. + * grub-core/loader/i386/xnu.c (table_aliases): Likewise. + (devices): Likewise. + * grub-core/loader/multiboot_mbi2.c (modules): Likewise. + (modules_last): Likewise. + * grub-core/normal/auth.c (users): Likewise. + * grub-core/normal/context.c (initial_menu): Likewise. + (current_menu): Likewise. + * grub-core/normal/crypto.c (crypto_specs): Likewise. + * grub-core/term/serial.c (grub_serial_ports): Likewise. + (grub_serial_terminfo_input_template): Likewise. + (grub_serial_terminfo_output_template): Likewise. + (grub_serial_terminfo_input): Likewise. + (grub_serial_terminfo_output): Likewise. + (registered): Likewise. + * grub-core/term/usb_keyboard.c (attach_hook): Likewise. + 2011-03-23 Vladimir Serbinenko * grub-core/video/bochs.c (grub_video_bochs_setup): Use diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c index 2bd805ef2..70173b7ea 100644 --- a/grub-core/bus/usb/usb.c +++ b/grub-core/bus/usb/usb.c @@ -25,7 +25,7 @@ #include static grub_usb_controller_dev_t grub_usb_list; -struct grub_usb_attach_desc *attach_hooks; +static struct grub_usb_attach_desc *attach_hooks; void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index f08910d2b..492be914c 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -39,7 +39,7 @@ struct grub_usb_hub grub_usb_device_t dev; }; -struct grub_usb_hub *hubs; +static struct grub_usb_hub *hubs; /* Add a device that currently has device number 0 and resides on CONTROLLER, the Hub reported that the device speed is SPEED. */ diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index 8b6806e45..664fe9c24 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -36,7 +36,7 @@ static const struct grub_arg_option options[] = { {0, 0, 0, 0, 0, 0} }; -struct { const char *name; const char *hashname; } aliases[] = +static struct { const char *name; const char *hashname; } aliases[] = { {"sha256sum", "sha256"}, {"sha512sum", "sha512"}, diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index 7b194ed17..88dfa4c08 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -32,7 +32,7 @@ struct pci_register unsigned size; }; -struct pci_register pci_registers[] = +static struct pci_register pci_registers[] = { {"VENDOR_ID", GRUB_PCI_REG_VENDOR , 2}, {"DEVICE_ID", GRUB_PCI_REG_DEVICE , 2}, diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c index e63105ccc..2e5d2459a 100644 --- a/grub-core/disk/usbms.c +++ b/grub-core/disk/usbms.c @@ -408,7 +408,7 @@ static struct grub_scsi_dev grub_usbms_dev = .write = grub_usbms_write }; -struct grub_usb_attach_desc attach_hook = +static struct grub_usb_attach_desc attach_hook = { .class = GRUB_USB_CLASS_MASS_STORAGE, .hook = grub_usbms_attach diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3a94d8874..8e83ea0b5 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -161,7 +161,7 @@ struct grub_zfs_data grub_disk_addr_t vdev_phys_sector; }; -decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { +static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ {"off", NULL}, /* ZIO_COMPRESS_OFF */ @@ -201,7 +201,7 @@ zio_checksum_off (const void *buf __attribute__ ((unused)), } /* Checksum Table and Values */ -zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { +static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { {NULL, 0, 0, "inherit"}, {NULL, 0, 0, "on"}, {zio_checksum_off, 0, 0, "off"}, diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 5c7db4408..84937f19b 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -49,7 +49,7 @@ struct grub_gettext_msg const char *translated; }; -struct grub_gettext_msg *grub_gettext_msg_list = NULL; +static struct grub_gettext_msg *grub_gettext_msg_list = NULL; #define GETTEXT_MAGIC_NUMBER 0 #define GETTEXT_FILE_FORMAT 4 diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c index 1acab9ca7..76d83c44b 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/grub-core/gfxmenu/gfxmenu.c @@ -37,7 +37,7 @@ #include #include -grub_gfxmenu_view_t cached_view; +static grub_gfxmenu_view_t cached_view; static void grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index fe421af35..fb1a52bf8 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -58,7 +58,7 @@ struct legacy_command const char *longdesc; }; -struct legacy_command legacy_commands[] = +static struct legacy_command legacy_commands[] = { {"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", "Print the blocklist notation of the file FILE."}, diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index dbd5fe4d0..e1bb7b7ea 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -77,10 +77,10 @@ struct grub_relocator_fw_leftover grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8]; }; -struct grub_relocator_fw_leftover *leftovers; +static struct grub_relocator_fw_leftover *leftovers; #endif -struct grub_relocator_extra_block *extra_blocks; +static struct grub_relocator_extra_block *extra_blocks; void * get_virtual_current_address (grub_relocator_chunk_t in) diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 08cdcda37..ecd5bd5cd 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -65,7 +65,7 @@ static void *kern_chunk_src; static grub_uint32_t bootflags; static int is_elf_kernel, is_64bit; static grub_uint32_t openbsd_root; -struct grub_relocator *relocator = NULL; +static struct grub_relocator *relocator = NULL; static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk; struct bsd_tag diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index b98bda223..14db50bcd 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -46,7 +46,7 @@ struct module int cmdline_size; }; -struct module *modules, *modules_last; +static struct module *modules, *modules_last; static grub_size_t cmdline_size; static grub_size_t total_modcmd; static unsigned modcnt; diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index a0df6f4aa..b877b0ea5 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -49,7 +49,7 @@ struct tbl_alias char *name; }; -struct tbl_alias table_aliases[] = +static struct tbl_alias table_aliases[] = { {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"}, {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"}, @@ -219,7 +219,7 @@ struct property_descriptor void *data; }; -struct grub_xnu_devprop_device_descriptor *devices = 0; +static struct grub_xnu_devprop_device_descriptor *devices = 0; grub_err_t grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev, diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index 3141f0028..05f581bb6 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -54,7 +54,7 @@ struct module int cmdline_size; }; -struct module *modules, *modules_last; +static struct module *modules, *modules_last; static grub_size_t cmdline_size; static grub_size_t total_modcmd; static unsigned modcnt; diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c index e5d187f0e..8e19568e2 100644 --- a/grub-core/normal/auth.c +++ b/grub-core/normal/auth.c @@ -34,7 +34,7 @@ struct grub_auth_user int authenticated; }; -struct grub_auth_user *users = NULL; +static struct grub_auth_user *users = NULL; grub_err_t grub_auth_register_authentication (const char *user, diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index 108679913..581316603 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -31,8 +31,8 @@ struct menu_pointer struct menu_pointer *prev; }; -struct menu_pointer initial_menu; -struct menu_pointer *current_menu = &initial_menu; +static struct menu_pointer initial_menu; +static struct menu_pointer *current_menu = &initial_menu; void grub_env_unset_menu (void) diff --git a/grub-core/normal/crypto.c b/grub-core/normal/crypto.c index 465c9f81d..19dafd8a7 100644 --- a/grub-core/normal/crypto.c +++ b/grub-core/normal/crypto.c @@ -31,7 +31,7 @@ struct load_spec char *modname; }; -struct load_spec *crypto_specs = NULL; +static struct load_spec *crypto_specs = NULL; static void grub_crypto_autoload (const char *name) diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index e672a89d6..32628dbae 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -41,7 +41,7 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -struct grub_serial_port *grub_serial_ports; +static struct grub_serial_port *grub_serial_ports; struct grub_serial_output_state { @@ -69,7 +69,7 @@ serial_fetch (grub_term_input_t term) return data->port->driver->fetch (data->port); } -const struct grub_serial_input_state grub_serial_terminfo_input_template = +static const struct grub_serial_input_state grub_serial_terminfo_input_template = { .tinfo = { @@ -77,7 +77,7 @@ const struct grub_serial_input_state grub_serial_terminfo_input_template = } }; -const struct grub_serial_output_state grub_serial_terminfo_output_template = +static const struct grub_serial_output_state grub_serial_terminfo_output_template = { .tinfo = { @@ -87,11 +87,11 @@ const struct grub_serial_output_state grub_serial_terminfo_output_template = } }; -struct grub_serial_input_state grub_serial_terminfo_input; +static struct grub_serial_input_state grub_serial_terminfo_input; -struct grub_serial_output_state grub_serial_terminfo_output; +static struct grub_serial_output_state grub_serial_terminfo_output; -int registered = 0; +static int registered = 0; static struct grub_term_input grub_serial_term_input = { diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c index 30ed8f9c2..23c0c10ca 100644 --- a/grub-core/term/usb_keyboard.c +++ b/grub-core/term/usb_keyboard.c @@ -435,7 +435,7 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term) return interpret_status (termdata->status) | termdata->mods; } -struct grub_usb_attach_desc attach_hook = +static struct grub_usb_attach_desc attach_hook = { .class = GRUB_USB_CLASS_HID, .hook = grub_usb_keyboard_attach From d1611f0163f1915b1de994c2cc1bd5f315b16dae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:08:33 +0100 Subject: [PATCH 0722/1414] * grub-core/efiemu/i386/pc/cfgtables.c (grub_machine_efiemu_init_tables): Make declaration a prototype. * grub-core/loader/xnu.c (grub_xnu_lock): Likewise. (grub_xnu_unlock): Likewise. * grub-core/normal/cmdline.c (grub_cmdline_get/cl_set_pos_all): Likewise. --- ChangeLog | 8 ++++++++ grub-core/efiemu/i386/pc/cfgtables.c | 2 +- grub-core/loader/xnu.c | 4 ++-- grub-core/normal/cmdline.c | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9527a6e8e..1f7de420e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/efiemu/i386/pc/cfgtables.c + (grub_machine_efiemu_init_tables): Make declaration a prototype. + * grub-core/loader/xnu.c (grub_xnu_lock): Likewise. + (grub_xnu_unlock): Likewise. + * grub-core/normal/cmdline.c (grub_cmdline_get/cl_set_pos_all): Likewise. + 2011-03-23 Vladimir Serbinenko * grub-core/bus/usb/usb.c (attach_hooks): Make static. diff --git a/grub-core/efiemu/i386/pc/cfgtables.c b/grub-core/efiemu/i386/pc/cfgtables.c index 9287d3a94..7b6a40c87 100644 --- a/grub-core/efiemu/i386/pc/cfgtables.c +++ b/grub-core/efiemu/i386/pc/cfgtables.c @@ -24,7 +24,7 @@ #include grub_err_t -grub_machine_efiemu_init_tables () +grub_machine_efiemu_init_tables (void) { grub_uint8_t *ptr; void *table; diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 5a84dea1c..73158fd10 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -1429,7 +1429,7 @@ grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)), #endif void -grub_xnu_lock () +grub_xnu_lock (void) { if (!locked) grub_dl_ref (my_mod); @@ -1437,7 +1437,7 @@ grub_xnu_lock () } void -grub_xnu_unlock () +grub_xnu_unlock (void) { if (locked) grub_dl_unref (my_mod); diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index b8c20d91c..09f2271ea 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -240,7 +240,7 @@ grub_cmdline_get (const char *prompt) grub_term_gotoxy (cl_term->term, cl_term->xpos, cl_term->ypos); } - void cl_set_pos_all () + void cl_set_pos_all (void) { unsigned i; for (i = 0; i < nterms; i++) From ed57e55702eac9ce24a8db0b4b7e5d40794a36a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:13:39 +0100 Subject: [PATCH 0723/1414] * grub-core/bus/usb/uhci.c (grub_uhci_detect_dev): Return GRUB_USB_SPEED_NONE in case of failure and not the error code. --- ChangeLog | 5 +++++ grub-core/bus/usb/uhci.c | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f7de420e..d1d946075 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/bus/usb/uhci.c (grub_uhci_detect_dev): Return + GRUB_USB_SPEED_NONE in case of failure and not the error code. + 2011-03-23 Vladimir Serbinenko * grub-core/efiemu/i386/pc/cfgtables.c diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index d082beac4..71142846b 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -749,8 +749,7 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed) else if (port == 1) reg = GRUB_UHCI_REG_PORTSC2; else - return grub_error (GRUB_ERR_OUT_OF_RANGE, - "UHCI Root Hub port does not exist"); + return GRUB_USB_SPEED_NONE; status = grub_uhci_readreg16 (u, reg); From 2e3e2e09081afd7b50391182401c7c90f8a9e9c7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:17:05 +0100 Subject: [PATCH 0724/1414] * grub-core/bus/usb/usbtrans.c (grub_usb_control_msg): Return usb-style error and not grub_errno. * grub-core/bus/usb/usbhub.c (grub_usb_add_hub): Likewise. --- ChangeLog | 6 ++++++ grub-core/bus/usb/usbtrans.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1d946075..87f78e0bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/bus/usb/usbtrans.c (grub_usb_control_msg): Return usb-style + error and not grub_errno. + * grub-core/bus/usb/usbhub.c (grub_usb_add_hub): Likewise. + 2011-03-23 Vladimir Serbinenko * grub-core/bus/usb/uhci.c (grub_uhci_detect_dev): Return diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c index ebb8a2eb6..167fae5a2 100644 --- a/grub-core/bus/usb/usbtrans.c +++ b/grub-core/bus/usb/usbtrans.c @@ -97,7 +97,7 @@ grub_usb_control_msg (grub_usb_device_t dev, if (! transfer) { grub_dma_free (data_chunk); - return grub_errno; + return GRUB_USB_ERR_INTERNAL; } setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); @@ -105,7 +105,7 @@ grub_usb_control_msg (grub_usb_device_t dev, { grub_free (transfer); grub_dma_free (data_chunk); - return grub_errno; + return GRUB_USB_ERR_INTERNAL; } setupdata = grub_dma_get_virt (setupdata_chunk); @@ -139,7 +139,7 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_free (transfer); grub_dma_free (setupdata_chunk); grub_dma_free (data_chunk); - return grub_errno; + return GRUB_USB_ERR_INTERNAL; } /* Build a Setup packet. XXX: Endianness. */ From e804e7b099ca8cf2feddd92682ba617423159afa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:18:21 +0100 Subject: [PATCH 0725/1414] missing file in last change --- grub-core/bus/usb/usbhub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 492be914c..82bb2da1c 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -110,7 +110,7 @@ static grub_usb_err_t grub_usb_add_hub (grub_usb_device_t dev) { struct grub_usb_usb_hubdesc hubdesc; - grub_err_t err; + grub_usb_err_t err; int i; err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN From b1d2840445c6b471e600f7d6177b6fc56bffc666 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:21:15 +0100 Subject: [PATCH 0726/1414] * grub-core/disk/usbms.c (grub_usbms_reset): Transform USB-style error into GRUB-style one. --- ChangeLog | 5 +++++ grub-core/disk/usbms.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 87f78e0bd..20a83dd84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/disk/usbms.c (grub_usbms_reset): Transform USB-style error + into GRUB-style one. + 2011-03-23 Vladimir Serbinenko * grub-core/bus/usb/usbtrans.c (grub_usb_control_msg): Return usb-style diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c index 2e5d2459a..fcfe9e5d4 100644 --- a/grub-core/disk/usbms.c +++ b/grub-core/disk/usbms.c @@ -70,7 +70,11 @@ static int first_available_slot = 0; static grub_err_t grub_usbms_reset (grub_usb_device_t dev, int interface) { - return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); + grub_usb_err_t u; + u = grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); + if (u) + return grub_error (GRUB_ERR_IO, "USB error %d", u); + return GRUB_ERR_NONE; } static void From fa3e01bfb5710c13daf92e0d107ae9ac39991209 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:23:42 +0100 Subject: [PATCH 0727/1414] * grub-core/lib/i386/pc/biosnum.c: Add missing include. --- ChangeLog | 4 ++++ grub-core/lib/i386/pc/biosnum.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 20a83dd84..ac149aeaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/lib/i386/pc/biosnum.c: Add missing include. + 2011-03-23 Vladimir Serbinenko * grub-core/disk/usbms.c (grub_usbms_reset): Transform USB-style error diff --git a/grub-core/lib/i386/pc/biosnum.c b/grub-core/lib/i386/pc/biosnum.c index 058c9d331..12771085a 100644 --- a/grub-core/lib/i386/pc/biosnum.c +++ b/grub-core/lib/i386/pc/biosnum.c @@ -19,6 +19,7 @@ #include #include #include +#include static int grub_get_root_biosnumber_default (void) From 537dc9bec6da41353c0df219a58cb378f0484091 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 12:40:15 +0100 Subject: [PATCH 0728/1414] * grub-core/normal/main.c (GRUB_MOD_INIT): Export pager variable. --- ChangeLog | 4 ++++ grub-core/normal/main.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index ac149aeaa..a6afeac29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/normal/main.c (GRUB_MOD_INIT): Export pager variable. + 2011-03-23 Vladimir Serbinenko * grub-core/lib/i386/pc/biosnum.c: Add missing include. diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 69bf5e6b5..cefb1cb9b 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -496,6 +496,7 @@ GRUB_MOD_INIT(normal) grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); grub_register_variable_hook ("pager", 0, grub_env_write_pager); + grub_env_export ("pager"); /* Register a command "normal" for the rescue mode. */ grub_register_command ("normal", grub_cmd_normal, From bae7fcc1ed5ac86f54f99f8033fa1980ad8a54dd Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 23 Mar 2011 13:01:42 +0100 Subject: [PATCH 0729/1414] Fix incorrect assert failure reporting. * grub-core/tests/example_functional_test.c (example_test): Add a failure comment. * grub-core/tests/lib/test.c (add_failure): Renamed to ... (failure_start): ...this. Check that malloc succeeded. Don't call xvasprintf. Return failure struct. (failure_append_vtext): New function. (failure_append_text): Likewise. (add_failure): Likewise. (grub_test_assert_helper): Likewise. * include/grub/test.h (grub_test_assert_helper): New declaration. (grub_test_assert): Macro rewritten. --- ChangeLog | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index a6afeac29..99cae9ba5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-03-23 Peter Jones + + Fix incorrect assert failure reporting. + + * grub-core/tests/example_functional_test.c (example_test): Add + a failure comment. + * grub-core/tests/lib/test.c (add_failure): Renamed to ... + (failure_start): ...this. Check that malloc succeeded. + Don't call xvasprintf. Return failure struct. + (failure_append_vtext): New function. + (failure_append_text): Likewise. + (add_failure): Likewise. + (grub_test_assert_helper): Likewise. + * include/grub/test.h (grub_test_assert_helper): New declaration. + (grub_test_assert): Macro rewritten. + 2011-03-23 Vladimir Serbinenko * grub-core/normal/main.c (GRUB_MOD_INIT): Export pager variable. From bd4d051a9517992ddcc291110ba52dd9efe743e8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 13:23:50 +0100 Subject: [PATCH 0730/1414] * grub-core/script/parser.y: Declare "time" as valid argument. --- ChangeLog | 4 ++++ grub-core/script/parser.y | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 99cae9ba5..3330a357b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/script/parser.y: Declare "time" as valid argument. + 2011-03-23 Peter Jones Fix incorrect assert failure reporting. diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y index 88c7fe9e3..683b3ac4b 100644 --- a/grub-core/script/parser.y +++ b/grub-core/script/parser.y @@ -147,6 +147,7 @@ argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); } | "until" { $$ = grub_script_add_arglist (state, 0, $1); } | "while" { $$ = grub_script_add_arglist (state, 0, $1); } | "function" { $$ = grub_script_add_arglist (state, 0, $1); } + | "time" { $$ = grub_script_add_arglist (state, 0, $1); } | word { $$ = $1; } ; From 59e1e5f17ba434d6fbf66de4014471f01c1c00e2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 14:18:56 +0100 Subject: [PATCH 0731/1414] * grub-core/normal/menu_entry.c (init_line): Fix off-by-one error. --- ChangeLog | 4 ++++ grub-core/normal/menu_entry.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3330a357b..c7bc69f58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/normal/menu_entry.c (init_line): Fix off-by-one error. + 2011-03-23 Vladimir Serbinenko * grub-core/script/parser.y: Declare "time" as valid argument. diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index e744d8d69..94f6e7f32 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -87,7 +87,7 @@ init_line (struct line *linep) { linep->len = 0; linep->max_len = 80; /* XXX */ - linep->buf = grub_malloc (linep->max_len); + linep->buf = grub_malloc (linep->max_len + 1); if (! linep->buf) return 0; From ebad0b81be1e6cd148688bcb0c4192b1923a51d0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 23 Mar 2011 14:45:04 +0000 Subject: [PATCH 0732/1414] remove unused variable --- grub-core/kern/emu/getroot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 601ac8b04..71b9a3c50 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -131,7 +131,6 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) size_t enc_path_len; const char *sep; char fstype[PATH_MAX], device[PATH_MAX]; - struct stat st; if (sscanf (buf, "%d %d %u:%u %s %s%n", &mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path, From 41a85f5508774c85e569917a0e9f6d5371b055a3 Mon Sep 17 00:00:00 2001 From: Alexander Kurtz Date: Wed, 23 Mar 2011 17:08:56 +0100 Subject: [PATCH 0733/1414] * grub-core/video/bitmap.c (match_extension): Ignore case. --- ChangeLog | 4 ++++ grub-core/video/bitmap.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c7bc69f58..e462dddc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-23 Alexander Kurtz + + * grub-core/video/bitmap.c (match_extension): Ignore case. + 2011-03-23 Vladimir Serbinenko * grub-core/normal/menu_entry.c (init_line): Fix off-by-one error. diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c index e06a5b696..659ab9a57 100644 --- a/grub-core/video/bitmap.c +++ b/grub-core/video/bitmap.c @@ -177,7 +177,7 @@ match_extension (const char *filename, const char *ext) pos -= ext_len; - return grub_strcmp (filename + pos, ext) == 0; + return grub_strcasecmp (filename + pos, ext) == 0; } /* Loads bitmap using registered bitmap readers. */ From 5657722c3c59ad45f3bebf9dae1f881a0e5e0186 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 23 Mar 2011 20:29:17 +0100 Subject: [PATCH 0734/1414] * grub-core/term/gfxterm.c (calculate_normal_character_width): Return 8 if no ASCII character is found to prevent crash. --- ChangeLog | 5 +++++ grub-core/term/gfxterm.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index e462dddc0..6e59b97ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-23 Vladimir Serbinenko + + * grub-core/term/gfxterm.c (calculate_normal_character_width): Return 8 + if no ASCII character is found to prevent crash. + 2011-03-23 Alexander Kurtz * grub-core/video/bitmap.c (match_extension): Ignore case. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 9a10d47b0..321479e0a 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -945,6 +945,8 @@ calculate_normal_character_width (grub_font_t font) if (glyph->device_width > width) width = glyph->device_width; } + if (!width) + return 8; return width; } From 8bc66a2ce617da1b721f7beebe8b0b164e733ae6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 24 Mar 2011 12:28:22 +0100 Subject: [PATCH 0735/1414] * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Account for modules headers when counting the needed allocation size. --- ChangeLog | 5 +++++ grub-core/loader/i386/bsdXX.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6e59b97ae..61adf1e26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-24 Vladimir Serbinenko + + * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Account + for modules headers when counting the needed allocation size. + 2011-03-23 Vladimir Serbinenko * grub-core/term/gfxterm.c (calculate_normal_character_width): Return 8 diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index 5b9e7689e..92d267534 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -195,6 +195,11 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, chunk_size = s->sh_addr + s->sh_size; } + if (chunk_size < sizeof (e)) + chunk_size = sizeof (e); + chunk_size += e.e_phnum * e.e_phentsize; + chunk_size += e.e_shnum * e.e_shentsize; + { grub_relocator_chunk_t ch; From ef6de21af47aba0485951dac352ea6cadcb18535 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 24 Mar 2011 12:39:48 +0100 Subject: [PATCH 0736/1414] * grub-core/lib/relocator.c (allocate_inreg): Avoid dprintf unless DEBUG_RELOCATOR is defined since gfxterm can't cope with output when malloc is disabled. --- ChangeLog | 6 ++++++ grub-core/lib/relocator.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 61adf1e26..2cdeb6dc4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-24 Vladimir Serbinenko + + * grub-core/lib/relocator.c (allocate_inreg): Avoid dprintf unless + DEBUG_RELOCATOR is defined since gfxterm can't cope with output when + malloc is disabled. + 2011-03-24 Vladimir Serbinenko * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Account diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index e1bb7b7ea..421054176 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -200,10 +200,12 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, struct grub_mm_header *foll = NULL; grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb)); +#ifdef DEBUG_RELOCATOR grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu," " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n", (unsigned long) paddr, (unsigned long) size, hb, hbp, rb, (unsigned long) vaddr); +#endif if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN <= (grub_addr_t) (hb + hb->size)) From 3f71cded814d7938bbb4e0d5bfa3b51440e3ffe4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 24 Mar 2011 12:43:28 +0100 Subject: [PATCH 0737/1414] * include/grub/mm.h (GRUB_MM_CHECK): Rename to ... (grub_mm_check): ... this. MAke a function-like macro and use GRUB_FILE. --- ChangeLog | 5 +++++ include/grub/mm.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2cdeb6dc4..cfce9988b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-24 Vladimir Serbinenko + + * include/grub/mm.h (GRUB_MM_CHECK): Rename to ... + (grub_mm_check): ... this. MAke a function-like macro and use GRUB_FILE. + 2011-03-24 Vladimir Serbinenko * grub-core/lib/relocator.c (allocate_inreg): Avoid dprintf unless diff --git a/include/grub/mm.h b/include/grub/mm.h index cc115907a..047006944 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -36,7 +36,7 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); void grub_mm_check_real (char *file, int line); -#define GRUB_MM_CHECK grub_mm_check_real (__FILE__, __LINE__); +#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); /* For debugging. */ #if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) From c7064d94250a9f9b78e5a08a44837626293fe596 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 24 Mar 2011 12:45:51 +0100 Subject: [PATCH 0738/1414] * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_addr) [DEBUG_RELOCATOR]: Reuse grub_mm_check. (grub_relocator_alloc_chunk_align) [DEBUG_RELOCATOR]: Likewise. --- ChangeLog | 6 ++++++ grub-core/lib/relocator.c | 39 ++++----------------------------------- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfce9988b..8744dbff3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-24 Vladimir Serbinenko + + * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_addr) + [DEBUG_RELOCATOR]: Reuse grub_mm_check. + (grub_relocator_alloc_chunk_align) [DEBUG_RELOCATOR]: Likewise. + 2011-03-24 Vladimir Serbinenko * include/grub/mm.h (GRUB_MM_CHECK): Rename to ... diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 421054176..7d29ab5cc 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -1284,23 +1284,8 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, chunk->srcv = grub_map_memory (chunk->src, chunk->size); *out = chunk; #ifdef DEBUG_RELOCATOR - { - grub_mm_region_t r; - grub_mm_header_t p; - grub_memset (chunk->srcv, 0xfa, chunk->size); - for (r = grub_mm_base; r; r = r->next) - { - p = r->first; - do - { - if ((grub_addr_t) p < (grub_addr_t) (r + 1) - || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) - grub_fatal (__FILE__ ":%d: out of range pointer: %p\n", __LINE__, p); - p = p->next; - } - while (p != r->first); - } - } + grub_memset (chunk->srcv, 0xfa, chunk->size); + grub_mm_check (); #endif return GRUB_ERR_NONE; } @@ -1438,24 +1423,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, chunk->srcv = grub_map_memory (chunk->src, chunk->size); *out = chunk; #ifdef DEBUG_RELOCATOR - { - grub_mm_region_t r; - grub_mm_header_t p; - - grub_memset (chunk->srcv, 0xfa, chunk->size); - for (r = grub_mm_base; r; r = r->next) - { - p = r->first; - do - { - if ((grub_addr_t) p < (grub_addr_t) (r + 1) - || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) - grub_fatal (__FILE__ "%d: out of range pointer: %p\n", __LINE__, p); - p = p->next; - } - while (p != r->first); - } - } + grub_memset (chunk->srcv, 0xfa, chunk->size); + grub_mm_check (); #endif return GRUB_ERR_NONE; } From 4c6c9431d2f72d6b7397a39e81e0112a01e3ec97 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 25 Mar 2011 00:03:54 +0000 Subject: [PATCH 0739/1414] * grub-core/video/fb/video_fb.c (grub_video_fb_get_info_and_fini): Switch back to page zero before loading a kernel, since some kernel drivers expect that. Thanks to: Felix Kuehling. --- ChangeLog | 7 +++++++ grub-core/video/fb/video_fb.c | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8744dbff3..b556c77e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-03-24 Colin Watson + + * grub-core/video/fb/video_fb.c (grub_video_fb_get_info_and_fini): + Switch back to page zero before loading a kernel, since some kernel + drivers expect that. + Thanks to: Felix Kuehling. + 2011-03-24 Vladimir Serbinenko * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_addr) diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c index 69626be5c..768b63328 100644 --- a/grub-core/video/fb/video_fb.c +++ b/grub-core/video/fb/video_fb.c @@ -1505,6 +1505,20 @@ grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info, { grub_memcpy (mode_info, &(framebuffer.front_target->mode_info), sizeof (*mode_info)); + + /* We are about to load a kernel. Switch back to page zero, since some + kernel drivers expect that. */ + if ((mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) + && framebuffer.set_page && framebuffer.displayed_page != 0) + { + /* Ensure both pages are exactly in sync. */ + grub_memcpy (framebuffer.back_target->data, + framebuffer.front_target->data, + framebuffer.back_target->mode_info.pitch + * framebuffer.back_target->mode_info.height); + grub_video_swap_buffers (); + } + *framebuf = framebuffer.front_target->data; grub_video_fb_fini (); From 82fe6c751bb32337045a57a18f2bb1f05c91d47b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 26 Mar 2011 12:49:34 +0100 Subject: [PATCH 0740/1414] Fix FreeBSD compilation problem. * grub-core/kern/emu/hostdisk.c (MAJOR) [FreeBSD]: New definition. (FLOPPY_MAJOR) [FreeBSD]: Likewise. --- ChangeLog | 7 +++++++ grub-core/kern/emu/hostdisk.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index b556c77e8..bf69511a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-03-26 Vladimir Serbinenko + + Fix FreeBSD compilation problem. + + * grub-core/kern/emu/hostdisk.c (MAJOR) [FreeBSD]: New definition. + (FLOPPY_MAJOR) [FreeBSD]: Likewise. + 2011-03-24 Colin Watson * grub-core/video/fb/video_fb.c (grub_video_fb_get_info_and_fini): diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 12dbe7469..b4f51da0f 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -92,6 +92,8 @@ struct hd_geometry # include /* DIOCGMEDIASIZE */ # include # include +# define MAJOR(dev) major(dev) +# define FLOPPY_MAJOR 2 #endif #if defined(__APPLE__) From f4727da93f55ba7a959848117b4c9db9afaba3ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 26 Mar 2011 12:59:02 +0100 Subject: [PATCH 0741/1414] Use libgeom on FreeBSD to detect partitions. * Makefile.util.def (grub-mkimage): Add LIBGEOM to ldadd. (grub-mkrelpath): Likewise. (grub-script-check): Likewise. (grub-editenv): Likewise. (grub-mkpasswd-pbkdf2): Likewise. (grub-fstest): Likewise. (grub-mkfont): Likewise. (grub-mkdevicemap): Likewise. (grub-probe): Likewise. (grub-setup): Likewise. (grub-ofpathname): Likewise. (grub-mklayout): Likewise. (example_unit_test): Likewise. (grub-menulst2cfg): Likewise. * grub-core/Makefile.core.def (grub-emu): Likewise. (grub-emu-lite): Likewise. * configure.ac: Check for -lgeom on FreeBSD and set LIBGEOM. * grub-core/kern/emu/hostdisk.c [FreeBSD]: Include libgeom.h. Don't define HAVE_DIOCGDINFO. (follow_geom_up) [FreeBSD]: New function. (find_partition_start) [FreeBSD]: Rewritten using follow_geom_up. (convert_system_partition_to_system_disk) [FreeBSD]: Likewise. (grub_util_biosdisk_get_grub_dev) [FreeBSD]: Use FreeBSD path unconditionally of HAVE_DIOCGDINFO. --- ChangeLog | 29 +++++++++++++ Makefile.util.def | 28 ++++++------ configure.ac | 9 ++++ grub-core/Makefile.core.def | 4 +- grub-core/kern/emu/hostdisk.c | 82 +++++++++++++++++++++++++++++++++-- 5 files changed, 132 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf69511a5..0d902ecd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2011-03-26 Vladimir Serbinenko + + Use libgeom on FreeBSD to detect partitions. + + * Makefile.util.def (grub-mkimage): Add LIBGEOM to ldadd. + (grub-mkrelpath): Likewise. + (grub-script-check): Likewise. + (grub-editenv): Likewise. + (grub-mkpasswd-pbkdf2): Likewise. + (grub-fstest): Likewise. + (grub-mkfont): Likewise. + (grub-mkdevicemap): Likewise. + (grub-probe): Likewise. + (grub-setup): Likewise. + (grub-ofpathname): Likewise. + (grub-mklayout): Likewise. + (example_unit_test): Likewise. + (grub-menulst2cfg): Likewise. + * grub-core/Makefile.core.def (grub-emu): Likewise. + (grub-emu-lite): Likewise. + * configure.ac: Check for -lgeom on FreeBSD and set LIBGEOM. + * grub-core/kern/emu/hostdisk.c [FreeBSD]: Include libgeom.h. Don't + define HAVE_DIOCGDINFO. + (follow_geom_up) [FreeBSD]: New function. + (find_partition_start) [FreeBSD]: Rewritten using follow_geom_up. + (convert_system_partition_to_system_disk) [FreeBSD]: Likewise. + (grub_util_biosdisk_get_grub_dev) [FreeBSD]: Use FreeBSD path + unconditionally of HAVE_DIOCGDINFO. + 2011-03-26 Vladimir Serbinenko Fix FreeBSD compilation problem. diff --git a/Makefile.util.def b/Makefile.util.def index 74984e2e9..303baea3f 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -122,7 +122,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBLZMA)'; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"'; }; @@ -135,7 +135,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -147,7 +147,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -159,7 +159,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -171,7 +171,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cflags = '$(CFLAGS_GCRY)'; cppflags = '$(CPPFLAGS_GCRY)'; }; @@ -209,7 +209,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -224,7 +224,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; condition = COND_GRUB_MKFONT; }; @@ -243,7 +243,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -255,7 +255,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -272,7 +272,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = i386_pc; enable = sparc64_ieee1275; @@ -287,7 +287,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)'; enable = sparc64_ieee1275; }; @@ -301,7 +301,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; data = { @@ -611,7 +611,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -624,5 +624,5 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; diff --git a/configure.ac b/configure.ac index c660ac41e..f9e974bca 100644 --- a/configure.ac +++ b/configure.ac @@ -890,6 +890,15 @@ fi AC_SUBST([LIBDEVMAPPER]) +LIBGEOM= +if test x$host_kernel = xkfreebsd; then + AC_CHECK_LIB([geom], [geom_gettree], [], + [AC_MSG_ERROR([Your platform requires libgeom])]) + LIBGEOM="-lgeom" +fi + +AC_SUBST([LIBGEOM]) + AC_CHECK_LIB([lzma], [lzma_code], [LIBLZMA="-llzma" AC_DEFINE([HAVE_LIBLZMA], [1], diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ce7d0b0c2..7c26b37e9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -200,7 +200,7 @@ program = { ldadd = 'kernel.img$(EXEEXT)'; ldadd = '$(MODULE_FILES)'; - ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = emu; }; @@ -212,7 +212,7 @@ program = { emu_nodist = symlist.c; ldadd = 'kernel.img$(EXEEXT)'; - ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)'; + ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = emu; }; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index b4f51da0f..73d023ce9 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -104,7 +104,9 @@ struct hd_geometry # include #endif -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#include +#elif defined(__NetBSD__) # define HAVE_DIOCGDINFO # include # include /* struct disklabel */ @@ -339,7 +341,68 @@ device_is_mapped (const char *dev) } #endif /* HAVE_DEVICE_MAPPER */ -#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +/* FIXME: geom actually gives us the whole container hierarchy. + It can be used more efficiently than this. */ +static void +follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out) +{ + struct gmesh mesh; + struct gclass *class; + int error; + struct ggeom *geom; + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + if (strcasecmp (class->lg_name, "part") == 0) + break; + if (!class) + grub_util_error ("couldn't open geom part"); + + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + char *name_tmp = xstrdup (geom->lg_name); + grub_disk_addr_t off = 0; + struct gconfig *config; + grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); + + follow_geom_up (name_tmp, &off, name_out); + free (name_tmp); + LIST_FOREACH (config, &provider->lg_config, lg_config) + if (strcasecmp (config->lg_name, "start") == 0) + off += strtoull (config->lg_val, 0, 10); + if (off_out) + *off_out = off; + return; + } + } + grub_util_info ("geom '%s' has no parent", name); + if (name_out) + *name_out = xstrdup (name); + if (off_out) + *off_out = 0; +} + +static grub_disk_addr_t +find_partition_start (const char *dev) +{ + grub_disk_addr_t out; + if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return 0; + follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL); + + return out; +} +#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) static grub_disk_addr_t find_partition_start (const char *dev) { @@ -1286,7 +1349,17 @@ devmapper_out: path[8] = 0; return path; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + char *out, *out2; + if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return xstrdup (os_dev); + follow_geom_up (os_dev + sizeof ("/dev/") - 1, NULL, &out); + + out2 = xasprintf ("/dev/%s", out); + free (out); + + return out2; +#elif defined(__APPLE__) char *path = xstrdup (os_dev); if (strncmp ("/dev/", path, 5) == 0) { @@ -1464,7 +1537,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) #endif return make_device_name (drive, -1, -1); -#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) +#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + /* Linux counts partitions uniformly, whether a BSD partition or a DOS partition, so mapping them to GRUB devices is not trivial. Here, get the start sector of a partition by HDIO_GETGEO, and From 5ee04984d113205aa413eb9b36164d4d2543aa88 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 26 Mar 2011 14:14:59 +0100 Subject: [PATCH 0742/1414] * grub-core/fs/iso9660.c (grub_iso9660_label): Rtrim the label. --- ChangeLog | 4 ++++ grub-core/fs/iso9660.c | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0d902ecd6..741f0f013 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-26 Vladimir Serbinenko + + * grub-core/fs/iso9660.c (grub_iso9660_label): Rtrim the label. + 2011-03-26 Vladimir Serbinenko Use libgeom on FreeBSD to detect partitions. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 6dc465f25..f72249d20 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -808,6 +808,15 @@ grub_iso9660_label (grub_device_t device, char **label) ((grub_uint16_t *) &data->voldesc.volname, 16); else *label = grub_strndup ((char *) data->voldesc.volname, 32); + if (*label) + { + char *ptr; + for (ptr = *label; *ptr;ptr++); + ptr--; + while (ptr >= *label && *ptr == ' ') + *ptr-- = 0; + } + grub_free (data); } else From c482ad98b370a53f2eac04eec824903ba1a557e6 Mon Sep 17 00:00:00 2001 From: Seth Goldberg Date: Sat, 26 Mar 2011 23:22:59 +0100 Subject: [PATCH 0743/1414] * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): Don't return freed string. --- ChangeLog | 5 +++++ grub-core/kern/emu/getroot.c | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 741f0f013..39ec5742e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-26 Seth Goldberg + + * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): Don't + return freed string. + 2011-03-26 Vladimir Serbinenko * grub-core/fs/iso9660.c (grub_iso9660_label): Rtrim the label. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 110e58b14..1d87442d9 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -184,7 +184,7 @@ find_root_device_from_mountinfo (const char *dir) static char * find_root_device_from_libzfs (const char *dir) { - char *device; + char *device = NULL; char *poolname; char *poolfs; @@ -225,7 +225,10 @@ find_root_device_from_libzfs (const char *dir) struct stat st; if (stat (device, &st) == 0) - break; + { + device = xstrdup (device); + break; + } device = NULL; } From f329eda79eb0340e148f6c827c910c317e083822 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Mar 2011 13:23:54 +0100 Subject: [PATCH 0744/1414] * grub-core/disk/raid.c (grub_raid_register): Adjust debug message to be specific about what kind of RAID device we're scanning for. --- ChangeLog | 5 +++++ grub-core/disk/raid.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 39ec5742e..24b608417 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-28 Colin Watson + + * grub-core/disk/raid.c (grub_raid_register): Adjust debug message + to be specific about what kind of RAID device we're scanning for. + 2011-03-26 Seth Goldberg * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): Don't diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 3972e1632..9d2468b88 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -696,7 +696,8 @@ grub_raid_register (grub_raid_t raid) struct grub_raid_array array; grub_disk_addr_t start_sector; - grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name); + grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n", + grub_raid_list->name, name); disk = grub_disk_open (name); if (!disk) From 24148725381450cc2dd2b4a19a0b496d22a304ba Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 28 Mar 2011 15:17:22 +0100 Subject: [PATCH 0745/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Remove stale comment. --- ChangeLog | 5 +++++ grub-core/disk/mdraid1x_linux.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 24b608417..d6afea1d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-28 Colin Watson + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Remove stale + comment. + 2011-03-28 Colin Watson * grub-core/disk/raid.c (grub_raid_register): Adjust debug message diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index f2e7555cb..296d1375b 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -110,7 +110,6 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, struct grub_raid_super_1x sb; grub_uint8_t minor_version; - /* The sector where the mdraid 0.90 superblock is stored, if available. */ size = grub_disk_get_size (disk); /* Check for an 1.x superblock. From 09573499ff62ebbeabfedc45dd8106ba715cbdf3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 02:02:55 +0200 Subject: [PATCH 0746/1414] Initial variable sector size support --- grub-core/disk/efi/efidisk.c | 17 ++++--- grub-core/disk/i386/pc/biosdisk.c | 52 +++++++++++---------- grub-core/disk/scsi.c | 36 +++++---------- grub-core/kern/disk.c | 77 +++++++++++++++++++++++-------- grub-core/kern/emu/hostdisk.c | 37 ++++++++++----- grub-core/partmap/msdos.c | 22 ++++++--- include/grub/disk.h | 10 ++-- 7 files changed, 155 insertions(+), 96 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 08094fa5c..20fea956f 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -536,8 +536,13 @@ grub_efidisk_open (const char *name, struct grub_disk *disk) and total sectors should be replaced with total blocks. */ grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n", m, (unsigned long long) m->last_block, m->block_size); - disk->total_sectors = (m->last_block - * (m->block_size >> GRUB_DISK_SECTOR_BITS)); + disk->total_sectors = m->last_block; + if (m->blocksize & (m->blocksize - 1) || !m->blocksize) + return grub_error (GRUB_ERR_IO, "invalid sector size %d", + m->blocksize); + for (disk->log_sector_size = 0; + (1 << disk->log_sector_size) < m->blocksize; + disk->log_sector_size++); disk->data = d; grub_dprintf ("efidisk", "opening %s succeeded\n", name); @@ -571,8 +576,8 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, (unsigned long) size, (unsigned long long) sector, disk->name); status = efi_call_5 (dio->read, dio, bio->media->media_id, - (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS, - (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS, + (grub_efi_uint64_t) sector << disk->log_sector_size, + (grub_efi_uintn_t) size << disk->log_sector_size, buf); if (status != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error"); @@ -599,8 +604,8 @@ grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector, (unsigned long) size, (unsigned long long) sector, disk->name); status = efi_call_5 (dio->write, dio, bio->media->media_id, - (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS, - (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS, + (grub_efi_uint64_t) sector << disk->log_sector_size, + (grub_efi_uintn_t) size << disk->log_sector_size, (void *) buf); if (status != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error"); diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 069bb0b59..6e48fff43 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -338,7 +338,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) if ((cd_drive) && (drive == cd_drive)) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; - data->sectors = 32; + data->sectors = 8; + disk->log_sector_size = 11; /* TODO: get the correct size. */ total_sectors = GRUB_DISK_SIZE_UNKNOWN; } @@ -347,6 +348,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) /* HDD */ int version; + disk->log_sector_size = 9; + version = grub_biosdisk_check_int13_extensions (drive); if (version) { @@ -367,6 +370,15 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) correctly but returns zero. So if it is zero, compute it by C/H/S returned by the LBA BIOS call. */ total_sectors = drp->cylinders * drp->heads * drp->sectors; + if (drp->bytes_per_sector + && !(drp->bytes_per_sector & (drp->bytes_per_sector - 1)) + && drp->bytes_per_sector >= 512 + && drp->bytes_per_sector <= 16384) + { + for (disk->log_sector_size = 0; + (1 << disk->log_sector_size) < drp->bytes_per_sector; + disk->log_sector_size++); + } } } } @@ -429,7 +441,7 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + (data->sectors - << GRUB_DISK_SECTOR_BITS)); + << disk->log_sector_size)); dap->length = sizeof (*dap); dap->reserved = 0; dap->blocks = size; @@ -443,9 +455,6 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, if (cmd) return grub_error (GRUB_ERR_WRITE_ERROR, "can\'t write to cdrom"); - dap->blocks = ALIGN_UP (dap->blocks, 4) >> 2; - dap->block >>= 2; - for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++) if (! grub_biosdisk_rw_int13_extensions (0x42, data->drive, dap)) break; @@ -501,10 +510,12 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, /* Return the number of sectors which can be read safely at a time. */ static grub_size_t -get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors) +get_safe_sectors (grub_disk_t disk, grub_disk_addr_t sector) { grub_size_t size; grub_uint32_t offset; + struct grub_biosdisk_data *data = disk->data; + grub_uint32_t sectors = data->sectors; /* OFFSET = SECTOR % SECTORS */ grub_divmod64 (sector, sectors, &offset); @@ -512,8 +523,8 @@ get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors) size = sectors - offset; /* Limit the max to 0x7f because of Phoenix EDD. */ - if (size > 0x7f) - size = 0x7f; + if (size > ((0x7fU << GRUB_DISK_SECTOR_BITS) >> disk->log_sector_size)) + size = ((0x7fU << GRUB_DISK_SECTOR_BITS) >> disk->log_sector_size); return size; } @@ -522,21 +533,11 @@ static grub_err_t grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) { - struct grub_biosdisk_data *data = disk->data; - while (size) { grub_size_t len; - grub_size_t cdoff = 0; - len = get_safe_sectors (sector, data->sectors); - - if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) - { - cdoff = (sector & 3) << GRUB_DISK_SECTOR_BITS; - len = ALIGN_UP (sector + len, 4) - (sector & ~3); - sector &= ~3; - } + len = get_safe_sectors (disk, sector); if (len > size) len = size; @@ -545,9 +546,10 @@ grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, GRUB_MEMORY_MACHINE_SCRATCH_SEG)) return grub_errno; - grub_memcpy (buf, (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + cdoff), - len << GRUB_DISK_SECTOR_BITS); - buf += len << GRUB_DISK_SECTOR_BITS; + grub_memcpy (buf, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, + len << disk->log_sector_size); + + buf += len << disk->log_sector_size; sector += len; size -= len; } @@ -568,18 +570,18 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, { grub_size_t len; - len = get_safe_sectors (sector, data->sectors); + len = get_safe_sectors (disk, sector); if (len > size) len = size; grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf, - len << GRUB_DISK_SECTOR_BITS); + len << disk->log_sector_size); if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len, GRUB_MEMORY_MACHINE_SCRATCH_SEG)) return grub_errno; - buf += len << GRUB_DISK_SECTOR_BITS; + buf += len << disk->log_sector_size; sector += len; size -= len; } diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index a40de278f..0d4734dc0 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -463,15 +463,20 @@ grub_scsi_open (const char *name, grub_disk_t disk) return err; } - /* SCSI blocks can be something else than 512, although GRUB - wants 512 byte blocks. */ - disk->total_sectors = ((grub_uint64_t)scsi->size - * (grub_uint64_t)scsi->blocksize) - >> GRUB_DISK_SECTOR_BITS; + disk->total_sectors = scsi->size; + if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize) + { + grub_free (scsi); + return grub_error (GRUB_ERR_IO, "invalid sector size %d", + scsi->blocksize); + } + for (disk->log_sector_size = 0; + (1 << disk->log_sector_size) < scsi->blocksize; + disk->log_sector_size++); grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", scsi->size, scsi->blocksize); - grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", + grub_dprintf ("scsi", "Disk total sectors = %llu\n", (unsigned long long) disk->total_sectors); return GRUB_ERR_NONE; @@ -501,25 +506,6 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, scsi = disk->data; - /* SCSI sectors are variable in size. GRUB uses 512 byte - sectors. */ - if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE) - { - unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS; - if (spb == 0 || (scsi->blocksize & (GRUB_DISK_SECTOR_SIZE - 1)) != 0) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported SCSI block size"); - - grub_uint32_t sector_mod = 0; - sector = grub_divmod64 (sector, spb, §or_mod); - - if (! (sector_mod == 0 && size % spb == 0)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unaligned SCSI read not supported"); - - size /= spb; - } - /* Depending on the type, select a read function. */ switch (scsi->devtype) { diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 807ee4277..af56527ad 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -247,6 +247,7 @@ grub_disk_open (const char *name) disk = (grub_disk_t) grub_zalloc (sizeof (*disk)); if (! disk) return 0; + disk->log_sector_size = GRUB_DISK_SECTOR_BITS; p = find_part_sep (name); if (p) @@ -266,7 +267,6 @@ grub_disk_open (const char *name) if (! disk->name) goto fail; - for (dev = grub_disk_dev_list; dev; dev = dev->next) { if ((dev->open) (raw, disk) == GRUB_ERR_NONE) @@ -282,6 +282,14 @@ grub_disk_open (const char *name) grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such disk"); goto fail; } + if (disk->log_sector_size > GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS + || disk->log_sector_size < GRUB_DISK_SECTOR_BITS) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "sector sizes of %d bytes aren't supported yet", + (1 << disk->log_sector_size)); + goto fail; + } disk->dev = dev; @@ -373,14 +381,23 @@ grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector, *sector += start; } - if (disk->total_sectors <= *sector - || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1) - >> GRUB_DISK_SECTOR_BITS) > disk->total_sectors - *sector) + if (disk->total_sectors != GRUB_DISK_SIZE_UNKNOWN + && ((disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)) <= *sector + || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS) > (disk->total_sectors + << (disk->log_sector_size + - GRUB_DISK_SECTOR_BITS)) - *sector)) return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk"); return GRUB_ERR_NONE; } +static inline grub_disk_addr_t +transform_sector (grub_disk_t disk, grub_disk_addr_t sector) +{ + return sector >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); +} + /* Read data from the disk. */ grub_err_t grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, @@ -433,27 +450,39 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, else { /* Otherwise read data from the disk actually. */ - if (start_sector + GRUB_DISK_CACHE_SIZE > disk->total_sectors - || (disk->dev->read) (disk, start_sector, - GRUB_DISK_CACHE_SIZE, tmp_buf) + if ((disk->total_sectors != GRUB_DISK_SIZE_UNKNOWN + && start_sector + GRUB_DISK_CACHE_SIZE + > (disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) + || (disk->dev->read) (disk, transform_sector (disk, start_sector), + 1 << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS + - disk->log_sector_size), tmp_buf) != GRUB_ERR_NONE) { /* Uggh... Failed. Instead, just read necessary data. */ unsigned num; char *p; + grub_disk_addr_t aligned_sector; grub_errno = GRUB_ERR_NONE; - num = ((size + real_offset + GRUB_DISK_SECTOR_SIZE - 1) - >> GRUB_DISK_SECTOR_BITS); + aligned_sector = (sector & ~((1 << (disk->log_sector_size + - GRUB_DISK_SECTOR_BITS)) + - 1)); + real_offset += ((sector - aligned_sector) + << GRUB_DISK_SECTOR_BITS); + num = ((size + real_offset + (1 << (disk->log_sector_size)) + - 1) >> (disk->log_sector_size)); - p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS); + p = grub_realloc (tmp_buf, num << disk->log_sector_size); if (!p) goto finish; tmp_buf = p; - if ((disk->dev->read) (disk, sector, num, tmp_buf)) + if ((disk->dev->read) (disk, transform_sector (disk, + aligned_sector), + num, tmp_buf)) { grub_error_push (); grub_dprintf ("disk", "%s read failed\n", disk->name); @@ -528,25 +557,31 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, grub_off_t offset, grub_size_t size, const void *buf) { unsigned real_offset; + grub_disk_addr_t aligned_sector; grub_dprintf ("disk", "Writing `%s'...\n", disk->name); if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) return -1; - real_offset = offset; + aligned_sector = (sector & ~((1 << (disk->log_sector_size + - GRUB_DISK_SECTOR_BITS)) - 1)); + real_offset = offset + ((sector - aligned_sector) << GRUB_DISK_SECTOR_BITS); + sector = aligned_sector; while (size) { - if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0)) + if (real_offset != 0 || (size < (1U << disk->log_sector_size) + && size != 0)) { - char tmp_buf[GRUB_DISK_SECTOR_SIZE]; + char tmp_buf[1 << disk->log_sector_size]; grub_size_t len; grub_partition_t part; part = disk->partition; disk->partition = 0; - if (grub_disk_read (disk, sector, 0, GRUB_DISK_SECTOR_SIZE, tmp_buf) + if (grub_disk_read (disk, sector, + 0, (1 << disk->log_sector_size), tmp_buf) != GRUB_ERR_NONE) { disk->partition = part; @@ -554,7 +589,7 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, } disk->partition = part; - len = GRUB_DISK_SECTOR_SIZE - real_offset; + len = (1 << disk->log_sector_size) - real_offset; if (len > size) len = size; @@ -565,7 +600,7 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE) goto finish; - sector++; + sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); buf = (char *) buf + len; size -= len; real_offset = 0; @@ -575,8 +610,8 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t len; grub_size_t n; - len = size & ~(GRUB_DISK_SECTOR_SIZE - 1); - n = size >> GRUB_DISK_SECTOR_BITS; + len = size & ~((1 << disk->log_sector_size) - 1); + n = size >> disk->log_sector_size; if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE) goto finish; @@ -599,6 +634,8 @@ grub_disk_get_size (grub_disk_t disk) { if (disk->partition) return grub_partition_get_len (disk->partition); + else if (disk->total_sectors != GRUB_DISK_SIZE_UNKNOWN) + return disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); else - return disk->total_sectors; + return GRUB_DISK_SIZE_UNKNOWN; } diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 73d023ce9..f082ada89 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -42,6 +42,7 @@ #ifdef __linux__ # include /* ioctl */ +# include # if !defined(__GLIBC__) || \ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) /* Maybe libc doesn't have large file support. */ @@ -264,6 +265,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) # else unsigned long long nr; # endif + int sector_size; int fd; fd = open (map[drive].device, O_RDONLY); @@ -295,16 +297,28 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) goto fail; } + if (ioctl (fd, BLKSSZGET, §or_size)) + { + close (fd); + goto fail; + } + close (fd); + if (sector_size & (sector_size - 1) || !sector_size) + goto fail; + for (disk->log_sector_size = 0; + (1 << disk->log_sector_size) < sector_size; + disk->log_sector_size++); + # if defined (__APPLE__) disk->total_sectors = nr; # elif defined(__NetBSD__) disk->total_sectors = label.d_secperunit; # else - disk->total_sectors = nr / 512; + disk->total_sectors = nr >> disk->log_sector_size; - if (nr % 512) + if (nr & ((1 << disk->log_sector_size) - 1)) grub_util_error ("unaligned device size"); # endif @@ -321,7 +335,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) if (stat (map[drive].device, &st) < 0) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot stat `%s'", map[drive].device); - disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS; + disk->total_sectors = st.st_size >> disk->log_sector_size; grub_util_info ("the size of %s is %lu", name, disk->total_sectors); @@ -760,7 +774,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, loff_t *, res, uint, wh); - offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS; + offset = (loff_t) sector << disk->log_sector_size; if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) { grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); @@ -770,7 +784,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) } #else { - off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS; + off_t offset = (off_t) sector << disk->log_sector_size; if (lseek (fd, offset, SEEK_SET) != offset) { @@ -870,20 +884,21 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, sectors that are read together with the MBR in one read. It should only remap the MBR, so we split the read in two parts. -jochen */ - if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) + if (nread (fd, buf, (1 << disk->log_sector_size)) + != (1 << disk->log_sector_size)) { grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device); close (fd); return grub_errno; } - buf += GRUB_DISK_SECTOR_SIZE; + buf += (1 << disk->log_sector_size); size--; } #endif /* __linux__ */ - if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS) - != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + if (nread (fd, buf, size << disk->log_sector_size) + != (ssize_t) (size << disk->log_sector_size)) grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device); return grub_errno; @@ -916,8 +931,8 @@ grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, if (fd < 0) return grub_errno; - if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS) - != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + if (nwrite (fd, buf, size << disk->log_sector_size) + != (ssize_t) (size << disk->log_sector_size)) grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device); return grub_errno; diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 31a0a0707..c2e726bd7 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -90,8 +90,11 @@ grub_partition_msdos_iterate (grub_disk_t disk, { e = mbr.entries + p.index; - p.start = p.offset + grub_le_to_cpu32 (e->start) - delta; - p.len = grub_le_to_cpu32 (e->length); + p.start = p.offset + + (grub_le_to_cpu32 (e->start) + << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)) - delta; + p.len = grub_le_to_cpu32 (e->length) + << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); p.msdostype = e->type; grub_dprintf ("partition", @@ -126,7 +129,9 @@ grub_partition_msdos_iterate (grub_disk_t disk, if (grub_msdos_partition_is_extended (e->type)) { - p.offset = ext_offset + grub_le_to_cpu32 (e->start); + p.offset = ext_offset + + (grub_le_to_cpu32 (e->start) + << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); if (! ext_offset) ext_offset = p.offset; @@ -204,8 +209,11 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, e = mbr.entries + i; if (!grub_msdos_partition_is_empty (e->type) - && end > offset + grub_le_to_cpu32 (e->start)) - end = offset + grub_le_to_cpu32 (e->start); + && end > offset + + (grub_le_to_cpu32 (e->start) + << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) + end = offset + (grub_le_to_cpu32 (e->start) + << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); /* If this is a GPT partition, this MBR is just a dummy. */ if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && i == 0) @@ -219,7 +227,9 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (grub_msdos_partition_is_extended (e->type)) { - offset = ext_offset + grub_le_to_cpu32 (e->start); + offset = ext_offset + + (grub_le_to_cpu32 (e->start) + << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); if (! ext_offset) ext_offset = offset; diff --git a/include/grub/disk.h b/include/grub/disk.h index 66db1149a..b46d6670a 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -100,6 +100,9 @@ struct grub_disk /* The total number of sectors. */ grub_uint64_t total_sectors; + /* Logarithm of sector size. */ + unsigned int log_sector_size; + /* The id used by the disk cache manager. */ unsigned long id; @@ -132,9 +135,10 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; /* The maximum number of disk caches. */ #define GRUB_DISK_CACHE_NUM 1021 -/* The size of a disk cache in sector units. */ -#define GRUB_DISK_CACHE_SIZE 8 -#define GRUB_DISK_CACHE_BITS 3 +/* The size of a disk cache in 512B units. Must be at least as big as the + largest supported sector size, currently 16K. */ +#define GRUB_DISK_CACHE_BITS 6 +#define GRUB_DISK_CACHE_SIZE (1 << GRUB_DISK_CACHE_BITS) /* Return value of grub_disk_get_size() in case disk size is unknown. */ #define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL From 9f3677d3c1dc361c570d6b20acff9e98563355aa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 02:20:52 +0200 Subject: [PATCH 0747/1414] * util/grub-setup.c: Copy the partition table zone if floppy support is disabled, even if no partition table is found. Otherwise, the BIOS on Dell Latitude E series laptops will freeze during POST if an invalid partition table is contained in the PBR of the active partition when GRUB is installed to a partition. --- ChangeLog | 9 +++++++++ util/grub-setup.c | 17 +++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d6afea1d2..1ea9ca076 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-03-29 Mario Limonciello + + * util/grub-setup.c: Copy the partition table zone if floppy support + is disabled, even if no partition table is found. + + Otherwise, the BIOS on Dell Latitude E series laptops will freeze + during POST if an invalid partition table is contained in the PBR + of the active partition when GRUB is installed to a partition. + 2011-03-28 Colin Watson * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Remove stale diff --git a/util/grub-setup.c b/util/grub-setup.c index b4749b433..c1f2a1f5e 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -399,6 +399,15 @@ setup (const char *dir, } #endif + /* Copy the partition table. */ + if (dest_partmap || + (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) + memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); + + free (tmp_img); + if (! dest_partmap) { grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); @@ -410,14 +419,6 @@ setup (const char *dir, goto unable_to_embed; } - /* Copy the partition table. */ - if (dest_partmap) - memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, - tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, - GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); - - free (tmp_img); - if (!dest_partmap->embed) { grub_util_warn ("Partition style '%s' doesn't support embeding", From a1dc717c5869064fda3553fd4055e00af6623d7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 08:20:19 +0200 Subject: [PATCH 0748/1414] * grub-core/lib/relocator.c (allocate_regstart) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Avoid grub_dprintf since not all terminals are capabple of malloc-free operation. (allocate_inreg) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Likewise. (malloc_in_range) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Likewise. --- ChangeLog | 8 ++++++++ grub-core/lib/relocator.c | 14 ++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ea9ca076..a07eff722 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-03-29 Vladimir Serbinenko + + * grub-core/lib/relocator.c (allocate_regstart) + [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Avoid grub_dprintf since not all + terminals are capabple of malloc-free operation. + (allocate_inreg) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Likewise. + (malloc_in_range) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Likewise. + 2011-03-29 Mario Limonciello * util/grub-setup.c: Copy the partition table zone if floppy support diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 7d29ab5cc..940b9133b 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -134,9 +134,10 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, grub_addr_t newreg_size, newreg_presize; grub_mm_header_t new_header; grub_mm_header_t hb = (grub_mm_header_t) (rb + 1); - - grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb); +#endif newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN); newreg_presize = newreg_start - newreg_raw_start; newreg_size = rb->size - (newreg_start - (grub_addr_t) rb); @@ -179,11 +180,12 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, if ((void *) h < (void *) (newreg + 1)) grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p", newreg, newreg->first, h, hp, hb); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF if ((void *) h == (void *) (newreg + 1)) grub_dprintf ("relocator", "Free start memory region: %p, %p, %p, %p, %p", newreg, newreg->first, h, hp, hb); - +#endif hp = h; h = h->next; } @@ -200,7 +202,7 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, struct grub_mm_header *foll = NULL; grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb)); -#ifdef DEBUG_RELOCATOR +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu," " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n", (unsigned long) paddr, (unsigned long) size, hb, hbp, @@ -213,8 +215,10 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN); foll->magic = GRUB_MM_FREE_MAGIC; foll->size = hb + hb->size - foll; +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll, (unsigned long) foll->size); +#endif } if (vaddr - (grub_addr_t) hb >= sizeof (*hb)) @@ -821,9 +825,11 @@ malloc_in_range (struct grub_relocator *rel, fend = ALIGN_UP (alloc_end, GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF grub_dprintf ("relocator", "requesting %lx-%lx\n", (unsigned long) fstart, (unsigned long) fend); +#endif /* The failure here can be very expensive. */ if (!grub_relocator_firmware_alloc_region (fstart, fend - fstart)) From ed5587afea4da065b2857906cacde451818c0e82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 08:33:28 +0200 Subject: [PATCH 0749/1414] * grub-core/term/gfxterm.c (dirty_region_add): Move core part to ... (dirty_region_add_real): ... this. (dirty_region_add): Don't discard margin refresh when performing scheduled repaint. --- ChangeLog | 7 +++++++ grub-core/term/gfxterm.c | 31 +++++++++++++++++-------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index a07eff722..c353b8fea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-03-29 Vladimir Serbinenko + + * grub-core/term/gfxterm.c (dirty_region_add): Move core part to ... + (dirty_region_add_real): ... this. + (dirty_region_add): Don't discard margin refresh when performing + scheduled repaint. + 2011-03-29 Vladimir Serbinenko * grub-core/lib/relocator.c (allocate_regstart) diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 321479e0a..44d1a9be8 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -532,21 +532,8 @@ dirty_region_is_empty (void) } static void -dirty_region_add (int x, int y, unsigned int width, unsigned int height) +dirty_region_add_real (int x, int y, unsigned int width, unsigned int height) { - if ((width == 0) || (height == 0)) - return; - - if (repaint_scheduled) - { - x = virtual_screen.offset_x; - y = virtual_screen.offset_y; - width = virtual_screen.width; - height = virtual_screen.height; - repaint_scheduled = 0; - repaint_was_scheduled = 1; - } - if (dirty_region_is_empty ()) { dirty_region.top_left_x = x; @@ -567,6 +554,22 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height) } } +static void +dirty_region_add (int x, int y, unsigned int width, unsigned int height) +{ + if ((width == 0) || (height == 0)) + return; + + if (repaint_scheduled) + { + dirty_region_add_real (virtual_screen.offset_x, virtual_screen.offset_y, + virtual_screen.width, virtual_screen.height); + repaint_scheduled = 0; + repaint_was_scheduled = 1; + } + dirty_region_add_real (x, y, width, height); +} + static void dirty_region_add_virtualscreen (void) { From d2e29d81a9fb4f07485a6948c5bb04ff8c0a9c69 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 10:56:14 +0200 Subject: [PATCH 0750/1414] * grub-core/fs/ext2.c (grub_ext2_read_inode): Fix an overflow. Reported and tested by: Timothy Nikkel. --- ChangeLog | 5 +++++ grub-core/fs/ext2.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c353b8fea..9e90df11e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-29 Vladimir Serbinenko + + * grub-core/fs/ext2.c (grub_ext2_read_inode): Fix an overflow. + Reported and tested by: Timothy Nikkel. + 2011-03-29 Vladimir Serbinenko * grub-core/term/gfxterm.c (dirty_region_add): Move core part to ... diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c index ed5fafd4c..9d7bbfd36 100644 --- a/grub-core/fs/ext2.c +++ b/grub-core/fs/ext2.c @@ -555,7 +555,7 @@ grub_ext2_read_inode (struct grub_ext2_data *data, /* Read the inode. */ if (grub_disk_read (data->disk, - ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno) + (((grub_disk_addr_t) grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno) << LOG2_EXT2_BLOCK_SIZE (data)), EXT2_INODE_SIZE (data) * blkoff, sizeof (struct grub_ext2_inode), inode)) From 35e5f84c18dde153c0671f3cf1f56371cde95631 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 11:25:04 +0200 Subject: [PATCH 0751/1414] * grub-core/normal/misc.c (grub_normal_print_device_info): Use correct printf clauses for printing size and start. --- ChangeLog | 5 +++++ grub-core/normal/misc.c | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e90df11e..8d976d770 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-29 Vladimir Serbinenko + + * grub-core/normal/misc.c (grub_normal_print_device_info): Use correct + printf clauses for printing size and start. + 2011-03-29 Vladimir Serbinenko * grub-core/fs/ext2.c (grub_ext2_read_inode): Fix an overflow. diff --git a/grub-core/normal/misc.c b/grub-core/normal/misc.c index d81b6d26f..4a7e6a3ea 100644 --- a/grub-core/normal/misc.c +++ b/grub-core/normal/misc.c @@ -112,14 +112,13 @@ grub_normal_print_device_info (const char *name) grub_printf ("%s", _("Not a known filesystem")); if (dev->disk->partition) - grub_printf (_(" - Partition start at %u"), - grub_partition_get_start (dev->disk->partition)); + grub_printf (_(" - Partition start at %llu"), + (unsigned long long) grub_partition_get_start (dev->disk->partition)); if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) - grub_printf (_(" - Total size unknown"), - grub_disk_get_size (dev->disk)); + grub_puts_ (" - Total size unknown"); else - grub_printf (_(" - Total size %u sectors"), - grub_disk_get_size (dev->disk)); + grub_printf (_(" - Total size %llu sectors"), + (unsigned long long) grub_disk_get_size (dev->disk)); grub_device_close (dev); } From b4db4f39f017cc7cf97890523bd6e6b219a9a326 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 29 Mar 2011 10:51:58 +0100 Subject: [PATCH 0752/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): If real_sb->size is zero (e.g. RAID-0), get the disk size from real_sb->data_size instead. Fixes Ubuntu bug #743136. --- ChangeLog | 7 +++++++ grub-core/disk/mdraid1x_linux.c | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8d976d770..ab5182b8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-03-29 Colin Watson + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): If + real_sb->size is zero (e.g. RAID-0), get the disk size from + real_sb->data_size instead. + Fixes Ubuntu bug #743136. + 2011-03-29 Vladimir Serbinenko * grub-core/normal/misc.c (grub_normal_print_device_info): Use correct diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index 296d1375b..1d08abf5b 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -192,7 +192,10 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, array->level = grub_le_to_cpu32 (real_sb->level); array->layout = grub_le_to_cpu32 (real_sb->layout); array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks); - array->disk_size = grub_le_to_cpu64 (real_sb->size); + if (real_sb->size) + array->disk_size = grub_le_to_cpu64 (real_sb->size); + else + array->disk_size = grub_le_to_cpu64 (real_sb->data_size); array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize); if (grub_le_to_cpu32 (real_sb->dev_number) >= From a307c0b206aebb15110a5c192ad0e5f2ddcd123f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 12:01:48 +0200 Subject: [PATCH 0753/1414] * util/grub.d/10_kfreebsd.in: Allow ufs.ko to be missing as it's per default compiled in kernel and prior to 8.0 isn't shipped at all. --- ChangeLog | 5 +++++ util/grub.d/10_kfreebsd.in | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ab5182b8c..8b593f634 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-29 Vladimir Serbinenko + + * util/grub.d/10_kfreebsd.in: Allow ufs.ko to be missing as it's + per default compiled in kernel and prior to 8.0 isn't shipped at all. + 2011-03-29 Colin Watson * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): If diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index dce5e945c..3600c74f9 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -110,7 +110,11 @@ EOF ;; esac - load_kfreebsd_module ${kfreebsd_fs} false + if [ x${kfreebsd_fs} = xufs ]; then + load_kfreebsd_module ${kfreebsd_fs} true + else + load_kfreebsd_module ${kfreebsd_fs} false + fi cat << EOF set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${kfreebsd_device} From 9e4d19e0d362613b566d824cc609b875c630e2b1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 15:00:23 +0200 Subject: [PATCH 0754/1414] * grub-core/kern/emu/hostdisk.c (find_partition_start) [HAVE_DIOCGDINFO]: Add safety checks. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b593f634..a7ed9fc94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-29 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (find_partition_start) + [HAVE_DIOCGDINFO]: Add safety checks. + 2011-03-29 Vladimir Serbinenko * util/grub.d/10_kfreebsd.in: Allow ufs.ko to be missing as it's diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 73d023ce9..9900a79bd 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -518,9 +518,12 @@ devmapper_fail: # if !defined(HAVE_DIOCGDINFO) return hdg.start; # else /* defined(HAVE_DIOCGDINFO) */ - p_index = dev[strlen(dev) - 1] - 'a'; - - if (p_index >= label.d_npartitions) + if (dev[0]) + p_index = dev[strlen(dev) - 1] - 'a'; + else + p_index = -1; + + if (p_index >= label.d_npartitions || p_index < 0) { grub_error (GRUB_ERR_BAD_DEVICE, "no disk label entry for `%s'", dev); From 994b82643247f936e07aa9652451a9d724bda615 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 29 Mar 2011 14:32:38 +0100 Subject: [PATCH 0755/1414] * docs/grub.texi (BIOS installation): New section, partly based on previous text in other sections. (Installing GRUB using grub-install): Replace BIOS discussion with a cross-reference. (Images): Likewise. --- ChangeLog | 8 ++++ docs/grub.texi | 100 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index a7ed9fc94..552d5dc7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-03-29 Colin Watson + + * docs/grub.texi (BIOS installation): New section, partly based on + previous text in other sections. + (Installing GRUB using grub-install): Replace BIOS discussion with a + cross-reference. + (Images): Likewise. + 2011-03-29 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (find_partition_start) diff --git a/docs/grub.texi b/docs/grub.texi index 83bd80023..cac4ffbf3 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -550,6 +550,7 @@ the @dfn{boot directory}. * Installing GRUB using grub-install:: * Making a GRUB bootable CD-ROM:: * Device map:: +* BIOS installation:: @end menu @@ -565,13 +566,8 @@ 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. -On BIOS platforms GRUB has to use a so-called embedding zone. On msdos -partition tables, this is the space between the MBR and the first partition -(called the MBR gap or the boot track), while on GPT partition tables it -uses a BIOS Boot Partition (a partition with GUID -21686148-6449-6e6f-744e656564454649). If you use GRUB on a BIOS system, make -sure that the embedding zone is at least 31 KiB (512KiB or more -recommended). +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 as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking @@ -744,6 +740,72 @@ comments in the file if needed, as the GRUB utilities assume that a line is just a comment if the first character is @samp{#}. +@node BIOS installation +@section BIOS installation + +@heading MBR + +The partition table format traditionally used on PC BIOS platforms is called +the Master Boot Record (MBR) format; this is the format that allows up to +four primary partitions and additional logical partitions. With this +partition table format, there are two ways to install GRUB: it can be +embedded in the area between the MBR and the first partition (called by +various names, such as the "boot track", "MBR gap", or "embedding area", and +which is usually at least 31 KiB), or the core image can be installed in a +file system and a list of the blocks that make it up can be stored in the +first sector of that partition. + +Each of these has different problems. There is no way to reserve space in +the embedding area with complete safety, and some proprietary software is +known to use it to make it difficult for users to work around licensing +restrictions; and systems are sometimes partitioned without leaving enough +space before the first partition. On the other hand, installing to a +filesystem means that GRUB is vulnerable to its blocks being moved around by +filesystem features such as tail packing, or even by aggressive fsck +implementations, so this approach is quite fragile; and this approach can +only be used if the @file{/boot} filesystem is on the same disk that the +BIOS boots from, so that GRUB does not have to rely on guessing BIOS drive +numbers. + +The GRUB development team generally recommends embedding GRUB before the +first partition, unless you have special requirements. You must ensure that +the first partition starts at least 31 KiB (63 sectors) from the start of +the disk; on modern disks, it is often a performance advantage to align +partitions on larger boundaries anyway, so the first partition might start 1 +MiB from the start of the disk. + +@heading GPT + +Some newer systems use the GUID Partition Table (GPT) format. This was +specified as part of the Extensible Firmware Interface (EFI), but it can +also be used on BIOS platforms if system software supports it; for example, +GRUB and GNU/Linux can be used in this configuration. With this format, it +is possible to reserve a whole partition for GRUB, called the BIOS Boot +Partition. GRUB can then be embedded into that partition without the risk +of being overwritten by other software and without being contained in a +filesystem which might move its blocks around. + +When creating a BIOS Boot Partition on a GPT system, you should make sure +that it is at least 31 KiB in size. (GPT-formatted disks are not usually +particularly small, so we recommend that you make it larger than the bare +minimum, such as 1 MiB, to allow plenty of room for growth.) You must also +make sure that it has the proper partition type. Using GNU Parted, you can +set this using a command such as the following: + +@example +# @kbd{parted /dev/@var{disk} set @var{partition-number} bios_grub on} +@end example + +If you are using gdisk, set the partition type to @samp{0xEF02}. With +partitioning programs that require setting the GUID directly, it should be +@samp{21686148-6449-6e6f-744e656564454649}. + +@strong{Caution:} Be very careful which partition you select! When GRUB +finds a BIOS Boot Partition during installation, it will automatically +overwrite part of it. Make sure that the partition does not contain any +other data. + + @node Booting @chapter Booting @@ -2021,28 +2083,8 @@ target operating systems, and so on) from the file system at run-time. The modular design allows the core image to be kept small, since the areas of disk where it must be installed are often as small as 32KB. -On PC systems using the traditional MBR partition table format, the core -image is usually installed in the "MBR gap" between the master boot record -and the first partition, or sometimes it is installed in a file system and -read directly from that. The latter is not recommended because GRUB needs -to encode the location of all the core image sectors in @file{diskboot.img}, -and if the file system ever moves the core image around (as it is entitled -to do) then GRUB must be reinstalled; it also means that GRUB will not be -able to reliably find the core image if it resides on a different disk than -the one to which @file{boot.img} was installed. - -On PC systems using the more recent GUID Partition Table (GPT) format, the -core image should be installed to a BIOS Boot Partition. This may be -created by GNU Parted using a command such as the following: - -@example -# @kbd{parted /dev/@var{disk} set @var{partition-number} bios_grub on} -@end example - -@strong{Caution:} Be very careful which partition you select! When GRUB -finds a BIOS Boot Partition during installation, it will automatically -overwrite part of it. Make sure that the partition does not contain any -other data. +@xref{BIOS installation}, for details on where the core image can be +installed on PC systems. @item *.mod Everything else in GRUB resides in dynamically loadable modules. These are From cf4d3fa6407417a6ecdc82ed886484400789cde5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 18:34:05 +0200 Subject: [PATCH 0756/1414] 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 61d7156b947cbb19cad2565b82fb599695a41bb1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 29 Mar 2011 18:00:23 +0100 Subject: [PATCH 0757/1414] * grub-core/disk/loopback.c (GRUB_MOD_INIT): Stop documenting removed -p option. --- ChangeLog | 5 +++++ grub-core/disk/loopback.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 552d5dc7c..36ca453f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-29 Colin Watson + + * grub-core/disk/loopback.c (GRUB_MOD_INIT): Stop documenting + removed -p option. + 2011-03-29 Colin Watson * docs/grub.texi (BIOS installation): New section, partly based on diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index ae4cb9a9c..b05940a4a 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -222,7 +222,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(loopback) { cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0, - N_("[-d|-p] DEVICENAME FILE."), + N_("[-d] DEVICENAME FILE."), N_("Make a device of a file."), options); grub_disk_dev_register (&grub_loopback_dev); } From 5c650f4c8ea62ea776807b9e1444a496c652608d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 29 Mar 2011 18:08:23 +0100 Subject: [PATCH 0758/1414] * docs/grub.texi (loopback): New section. --- ChangeLog | 4 ++++ docs/grub.texi | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index 36ca453f1..cf7b1b0d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-29 Colin Watson + + * docs/grub.texi (loopback): New section. + 2011-03-29 Colin Watson * grub-core/disk/loopback.c (GRUB_MOD_INIT): Stop documenting diff --git a/docs/grub.texi b/docs/grub.texi index cac4ffbf3..368d21f1d 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2589,6 +2589,7 @@ you forget a command, you can run the command @command{help} * keystatus:: Check key modifier status * linux:: Load a Linux kernel * linux16:: Load a Linux kernel (16-bit mode) +* loopback:: Make a device from a filesystem image * ls:: List devices or files * parttool:: Modify partition table entries * password:: Set a clear-text password @@ -2978,6 +2979,23 @@ This command is only available on x86 systems. @end deffn +@node loopback +@subsection loopback + +@deffn Command loopback [@option{-d}] device file +Make the device named @var{device} correspond to the contents of the +filesystem image in @var{file}. For example: + +@example +loopback loop0 /path/to/image +ls (loop0)/ +@end example + +With the @option{-d} option, delete a device previously created using this +command. +@end deffn + + @node ls @subsection ls From fc18f6a3cb15db980e65dda9e305a1d176b14b3a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 19:47:34 +0200 Subject: [PATCH 0759/1414] * util/grub.d/10_linux.in: Skip vmlinux-* on x86 platforms. --- ChangeLog | 4 + grub-core/disk/lvm.c | 354 ++++++++++++++++++++++++++-------------- include/grub/lvm.h | 13 ++ util/grub.d/10_linux.in | 14 +- 4 files changed, 260 insertions(+), 125 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf7b1b0d6..dcacc600c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-29 Vladimir Serbinenko + + * util/grub.d/10_linux.in: Skip vmlinux-* on x86 platforms. + 2011-03-29 Colin Watson * docs/grub.texi (loopback): New section. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 39fa84d91..b1a7a50a9 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -45,6 +45,7 @@ grub_lvm_getvalue (char **p, char *str) return grub_strtoul (*p, NULL, 10); } +#if 0 static int grub_lvm_checkvalue (char **p, char *str, char *tmpl) { @@ -57,6 +58,7 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl) return 0; return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"'); } +#endif static int grub_lvm_check_flag (char *p, char *str, char *flag) @@ -100,7 +102,7 @@ grub_lvm_iterate (int (*hook) (const char *name)) struct grub_lvm_lv *lv; if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (hook (lv->name)) + if (lv->visible && hook (lv->name)) return 1; } @@ -164,11 +166,10 @@ grub_lvm_close (grub_disk_t disk __attribute ((unused))) } static grub_err_t -grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) +read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, + grub_size_t size, char *buf) { grub_err_t err = 0; - struct grub_lvm_lv *lv = disk->data; struct grub_lvm_vg *vg = lv->vg; struct grub_lvm_segment *seg = lv->segments; struct grub_lvm_pv *pv; @@ -176,6 +177,9 @@ grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, grub_uint64_t extent; unsigned int i; + if (!lv) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume"); + extent = grub_divmod64 (sector, vg->extent_size, NULL); /* Find the right segment. */ @@ -190,59 +194,88 @@ grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, seg++; } - if (seg->stripe_count == 1) + if (i == lv->segment_count) + return grub_error (GRUB_ERR_READ_ERROR, "incorrect segment"); + + switch (seg->type) { - /* This segment is linear, so that's easy. We just need to find - out the offset in the physical volume and read SIZE bytes - from that. */ - struct grub_lvm_stripe *stripe = seg->stripes; - grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ + case GRUB_LVM_STRIPED: + if (seg->stripe_count == 1) + { + /* This segment is linear, so that's easy. We just need to find + out the offset in the physical volume and read SIZE bytes + from that. */ + struct grub_lvm_stripe *stripe = seg->stripes; + grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ - pv = stripe->pv; - seg_offset = ((grub_uint64_t) stripe->start - * (grub_uint64_t) vg->extent_size) + pv->start; + pv = stripe->pv; + seg_offset = ((grub_uint64_t) stripe->start + * (grub_uint64_t) vg->extent_size) + pv->start; - offset = sector - ((grub_uint64_t) seg->start_extent - * (grub_uint64_t) vg->extent_size) + seg_offset; + offset = sector - ((grub_uint64_t) seg->start_extent + * (grub_uint64_t) vg->extent_size) + seg_offset; + } + else + { + /* This is a striped segment. We have to find the right PV + similar to RAID0. */ + struct grub_lvm_stripe *stripe = seg->stripes; + grub_uint32_t a, b; + grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ + unsigned int stripenr; + + offset = sector - ((grub_uint64_t) seg->start_extent + * (grub_uint64_t) vg->extent_size); + + a = grub_divmod64 (offset, seg->stripe_size, NULL); + grub_divmod64 (a, seg->stripe_count, &stripenr); + + a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL); + grub_divmod64 (offset, seg->stripe_size, &b); + offset = a * seg->stripe_size + b; + + stripe += stripenr; + pv = stripe->pv; + + seg_offset = ((grub_uint64_t) stripe->start + * (grub_uint64_t) vg->extent_size) + pv->start; + + offset += seg_offset; + } + /* Check whether we actually know the physical volume we want to + read from. */ + if (pv->disk) + err = grub_disk_read (pv->disk, offset, 0, + size << GRUB_DISK_SECTOR_BITS, buf); + else + err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "physical volume %s not found", pv->name); + + return err; + case GRUB_LVM_MIRROR: + i = 0; + while (1) + { + if (!seg->mirrors[i].lv) + err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume '%s'", + seg->mirrors[i].lvname); + else + err = read_lv (seg->mirrors[i].lv, sector, size, buf); + if (!err) + return err; + if (++i >= seg->mirror_count) + return err; + grub_errno = GRUB_ERR_NONE; + } } - else - { - /* This is a striped segment. We have to find the right PV - similar to RAID0. */ - struct grub_lvm_stripe *stripe = seg->stripes; - grub_uint32_t a, b; - grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ - unsigned int stripenr; + return grub_error (GRUB_ERR_IO, "unknown LVM segment"); +} - offset = sector - ((grub_uint64_t) seg->start_extent - * (grub_uint64_t) vg->extent_size); - - a = grub_divmod64 (offset, seg->stripe_size, NULL); - grub_divmod64 (a, seg->stripe_count, &stripenr); - - a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL); - grub_divmod64 (offset, seg->stripe_size, &b); - offset = a * seg->stripe_size + b; - - stripe += stripenr; - pv = stripe->pv; - - seg_offset = ((grub_uint64_t) stripe->start - * (grub_uint64_t) vg->extent_size) + pv->start; - - offset += seg_offset; - } - - /* Check whether we actually know the physical volume we want to - read from. */ - if (pv->disk) - err = grub_disk_read (pv->disk, offset, 0, - size << GRUB_DISK_SECTOR_BITS, buf); - else - err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "physical volume %s not found", pv->name); - - return err; +static grub_err_t +grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + return read_lv (disk->data, sector, size, buf); } static grub_err_t @@ -533,11 +566,7 @@ grub_lvm_scan_device (const char *name) lv->size = 0; - if (!grub_lvm_check_flag (p, "status", "VISIBLE")) - { - skip_lv = 1; - goto lv_parsed; - } + lv->visible = grub_lvm_check_flag (p, "status", "VISIBLE"); lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); if (p == NULL) @@ -552,7 +581,6 @@ grub_lvm_scan_device (const char *name) for (i = 0; i < lv->segment_count; i++) { - struct grub_lvm_stripe *stripe; p = grub_strstr (p, "segment"); if (p == NULL) @@ -580,78 +608,147 @@ grub_lvm_scan_device (const char *name) goto lvs_segment_fail; } - if (grub_lvm_checkvalue (&p, "type = ", "snapshot")) - { - /* Found a snapshot, give up and move on. */ - skip_lv = 1; - break; - } - - seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); + p = grub_strstr (p, "type = \""); if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown stripe_count\n"); -#endif - goto lvs_segment_fail; - } + goto lvs_segment_fail; + p += sizeof("type = \"") - 1; lv->size += seg->extent_count * vg->extent_size; - if (seg->stripe_count != 1) - seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); + if (grub_memcmp (p, "striped\"", + sizeof ("striped\"") - 1) == 0) + { + struct grub_lvm_stripe *stripe; - seg->stripes = grub_malloc (sizeof (*stripe) - * seg->stripe_count); - stripe = seg->stripes; + seg->type = GRUB_LVM_STRIPED; + seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); + if (p == NULL) + { +#ifdef GRUB_UTIL + grub_util_info ("unknown stripe_count\n"); +#endif + goto lvs_segment_fail; + } - p = grub_strstr (p, "stripes = ["); - if (p == NULL) + if (seg->stripe_count != 1) + seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); + + seg->stripes = grub_malloc (sizeof (*stripe) + * seg->stripe_count); + stripe = seg->stripes; + + p = grub_strstr (p, "stripes = ["); + if (p == NULL) + { +#ifdef GRUB_UTIL + grub_util_info ("unknown stripes\n"); +#endif + goto lvs_segment_fail2; + } + p += sizeof("stripes = [") - 1; + + for (j = 0; j < seg->stripe_count; j++) + { + char *pvname; + + p = grub_strchr (p, '"'); + if (p == NULL) + continue; + q = ++p; + while (*q != '"') + q++; + + s = q - p; + + pvname = grub_malloc (s + 1); + if (pvname == NULL) + goto lvs_segment_fail2; + + grub_memcpy (pvname, p, s); + pvname[s] = '\0'; + + if (vg->pvs) + for (pv = vg->pvs; pv; pv = pv->next) + { + if (! grub_strcmp (pvname, pv->name)) + { + stripe->pv = pv; + break; + } + } + + grub_free(pvname); + + stripe->start = grub_lvm_getvalue (&p, ","); + if (p == NULL) + continue; + + stripe++; + } + } + else if (grub_memcmp (p, "mirror\"", sizeof ("mirror\"") - 1) + == 0) + { + seg->type = GRUB_LVM_MIRROR; + seg->mirror_count = grub_lvm_getvalue (&p, "mirror_count = "); + if (p == NULL) + { +#ifdef GRUB_UTIL + grub_util_info ("unknown mirror_count\n"); +#endif + goto lvs_segment_fail; + } + + seg->mirrors = grub_zalloc (sizeof (seg->mirrors[0]) + * seg->mirror_count); + + p = grub_strstr (p, "mirrors = ["); + if (p == NULL) + { +#ifdef GRUB_UTIL + grub_util_info ("unknown mirrors\n"); +#endif + goto lvs_segment_fail2; + } + p += sizeof("mirrors = [") - 1; + + for (j = 0; j < seg->mirror_count; j++) + { + char *lvname; + + p = grub_strchr (p, '"'); + if (p == NULL) + continue; + q = ++p; + while (*q != '"') + q++; + + s = q - p; + + lvname = grub_malloc (s + 1); + if (lvname == NULL) + goto lvs_segment_fail2; + + grub_memcpy (lvname, p, s); + lvname[s] = '\0'; + seg->mirrors[j].lvname = lvname; + p = q + 1; + } + } + else { #ifdef GRUB_UTIL - grub_util_info ("unknown stripes\n"); + char *p2; + p2 = grub_strchr (p, '"'); + if (p2) + *p2 = 0; + grub_util_info ("unknown LVM type %s\n", p); + if (p2) + *p2 ='"'; #endif - goto lvs_segment_fail2; - } - p += sizeof("stripes = [") - 1; - - for (j = 0; j < seg->stripe_count; j++) - { - char *pvname; - - p = grub_strchr (p, '"'); - if (p == NULL) - continue; - q = ++p; - while (*q != '"') - q++; - - s = q - p; - - pvname = grub_malloc (s + 1); - if (pvname == NULL) - goto lvs_segment_fail2; - - grub_memcpy (pvname, p, s); - pvname[s] = '\0'; - - if (vg->pvs) - for (pv = vg->pvs; pv; pv = pv->next) - { - if (! grub_strcmp (pvname, pv->name)) - { - stripe->pv = pv; - break; - } - } - - grub_free(pvname); - - stripe->start = grub_lvm_getvalue (&p, ","); - if (p == NULL) - continue; - - stripe++; + /* Found a non-supported type, give up and move on. */ + skip_lv = 1; + break; } seg++; @@ -663,7 +760,6 @@ grub_lvm_scan_device (const char *name) goto fail4; } - lv_parsed: if (p != NULL) p = grub_strchr (p, '}'); if (p == NULL) @@ -690,6 +786,20 @@ grub_lvm_scan_device (const char *name) } } + /* Match mirrors */ + { + struct grub_lvm_lv *lv1; + struct grub_lvm_lv *lv2; + for (lv1 = vg->lvs; lv1; lv1 = lv1->next) + for (i = 0; i < lv1->segment_count; i++) + if (lv1->segments[i].type == GRUB_LVM_MIRROR) + for (j = 0; j < lv1->segments[i].mirror_count; j++) + for (lv2 = vg->lvs; lv2; lv2 = lv2->next) + if (grub_strcmp (lv2->name + grub_strlen (vg->name) + 1, + lv1->segments[i].mirrors[j].lvname) == 0) + lv1->segments[i].mirrors[j].lv = lv2; + } + vg->next = vg_list; vg_list = vg; } diff --git a/include/grub/lvm.h b/include/grub/lvm.h index a4bf3b288..220517183 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -47,6 +47,9 @@ struct grub_lvm_lv { unsigned int number; unsigned int segment_count; grub_uint64_t size; + + int visible; + struct grub_lvm_segment *segments; /* Pointer to segment_count segments. */ struct grub_lvm_vg *vg; struct grub_lvm_lv *next; @@ -55,6 +58,11 @@ struct grub_lvm_lv { struct grub_lvm_segment { unsigned int start_extent; unsigned int extent_count; + enum { GRUB_LVM_STRIPED, GRUB_LVM_MIRROR } type; + + unsigned int mirror_count; + struct grub_lvm_mirror *mirrors; + unsigned int stripe_count; unsigned int stripe_size; struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */ @@ -65,6 +73,11 @@ struct grub_lvm_stripe { struct grub_lvm_pv *pv; }; +struct grub_lvm_mirror { + char *lvname; + struct grub_lvm_lv *lv; +}; + #define GRUB_LVM_LABEL_SIZE GRUB_DISK_SECTOR_SIZE #define GRUB_LVM_LABEL_SCAN_SECTORS 4L diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 491d2b5ce..d12902e33 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -111,9 +111,17 @@ EOF EOF } -list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do - if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi - done` +case x`uname -m` in + xi?86 | xx86_64) + list=`for i in /boot/vmlinuz-* /vmlinuz-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` ;; + *) + list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` ;; +esac + prepare_boot_cache= while [ "x$list" != "x" ] ; do From 70e75364fa8627e24bb5ed9eead391c778c4504e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 20:33:32 +0200 Subject: [PATCH 0760/1414] * include/grub/lvm.h (grub_lvm_lv): New field 'visible'. (grub_lvm_segment): New fields 'type', 'mirror_count' and 'mirrors'. (grub_lvm_mirror): New struct. * grub-core/disk/lvm.c (grub_lvm_checkvalue): Commented out. (grub_lvm_iterate): Iterate only visible volumes. (grub_lvm_read): Factor out to .. (read_lv): ... this. Support mirrors. (grub_lvm_read): New wrapper function. (grub_lvm_scan_device): Parse mirrors. Skip everything that isn't stripped or mirrored. --- ChangeLog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index dcacc600c..e93ffe4c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-03-29 Vladimir Serbinenko + + * include/grub/lvm.h (grub_lvm_lv): New field 'visible'. + (grub_lvm_segment): New fields 'type', 'mirror_count' and 'mirrors'. + (grub_lvm_mirror): New struct. + * grub-core/disk/lvm.c (grub_lvm_checkvalue): Commented out. + (grub_lvm_iterate): Iterate only visible volumes. + (grub_lvm_read): Factor out to .. + (read_lv): ... this. Support mirrors. + (grub_lvm_read): New wrapper function. + (grub_lvm_scan_device): Parse mirrors. Skip everything that isn't + stripped or mirrored. + 2011-03-29 Vladimir Serbinenko * util/grub.d/10_linux.in: Skip vmlinux-* on x86 platforms. From e1eb511d9a069dd09472889322ff53844e56e432 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Mar 2011 21:12:13 +0200 Subject: [PATCH 0761/1414] * util/grub.d/20_linux_xen.in: Accept old-style xen kernels. --- ChangeLog | 4 ++++ util/grub.d/20_linux_xen.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e93ffe4c4..073543c16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-29 Vladimir Serbinenko + + * util/grub.d/20_linux_xen.in: Accept old-style xen kernels. + 2011-03-29 Vladimir Serbinenko * include/grub/lvm.h (grub_lvm_lv): New field 'visible'. diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index e71fc1458..bacd8ffea 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -96,7 +96,7 @@ EOF linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do basename=$(basename $i) version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") - if grub_file_is_not_garbage "$i" && grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null ; then echo -n "$i " ; fi + if grub_file_is_not_garbage "$i" && (grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" /boot/config-${version} 2> /dev/null); then echo -n "$i " ; fi done` if [ "x${linux_list}" = "x" ] ; then exit 0 From fc8584825cb513ffaca12585657b1682ef79a3e5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 00:05:25 +0200 Subject: [PATCH 0762/1414] Old macs search for boot.efi rather than for bootia32.efi. * util/grub-install.in: Copy bootia32.efi to boot.efi. * util/grub-mkrescue.in: Likewise. Suggested by: Peter Jones. --- ChangeLog | 8 ++++++++ util/grub-install.in | 4 ++++ util/grub-mkrescue.in | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index 073543c16..661f08502 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-03-29 Vladimir Serbinenko + + Old macs search for boot.efi rather than for bootia32.efi. + + * util/grub-install.in: Copy bootia32.efi to boot.efi. + * util/grub-mkrescue.in: Likewise. + Suggested by: Peter Jones. + 2011-03-29 Vladimir Serbinenko * util/grub.d/20_linux_xen.in: Accept old-style xen kernels. diff --git a/util/grub-install.in b/util/grub-install.in index b4a4b3f26..4e78dfadb 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -620,6 +620,10 @@ elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${pla fi elif [ x"$platform" = xefi ]; then cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}" + # For old macs. Suggested by Peter Jones. + if [ x$target_cpu = xi386 ]; then + cp "${grubdir}/core.${imgext}" "${efidir}/boot.efi" + fi # Try to make this image bootable using the EFI Boot Manager, if available. efibootmgr="`which efibootmgr`" diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 690bddb30..455534009 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -286,6 +286,10 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then make_image "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi "" # build bootia32.efi make_image "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi "" + if [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then + # For old macs. Suggested by Peter Jones. + cp "${efi_dir}"/efi/boot/bootia32.efi "${efi_dir}"/efi/boot/boot.efi + fi mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ From e30af0297db09528ca5a9e08aaf31154859e0fe4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 03:20:09 +0100 Subject: [PATCH 0763/1414] * docs/grub.texi (Simple configuration): Explain some of the current limitations of grub-mkconfig. --- ChangeLog | 5 +++++ docs/grub.texi | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/ChangeLog b/ChangeLog index 661f08502..35fd04154 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Colin Watson + + * docs/grub.texi (Simple configuration): Explain some of the + current limitations of grub-mkconfig. + 2011-03-29 Vladimir Serbinenko Old macs search for boot.efi rather than for bootia32.efi. diff --git a/docs/grub.texi b/docs/grub.texi index 368d21f1d..9ff72798b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1066,6 +1066,16 @@ generates @file{grub.cfg} files suitable for most cases. It is suitable for use when upgrading a distribution, and will discover available kernels and attempt to generate menu entries for them. +@command{grub-mkconfig} does have some limitations. While adding extra +custom menu entries to the end of the list can be done by editing +@file{/etc/grub.d/40_custom} or creating @file{/boot/grub/custom.cfg}, +changing the order of menu entries or changing their titles may require +making complex changes to shell scripts stored in @file{/etc/grub.d/}. This +may be improved in the future. In the meantime, those who feel that it +would be easier to write @file{grub.cfg} directly are encouraged to do so +(@pxref{Booting}, and @ref{Shell-like scripting}), and to disable any system +provided by their distribution to automatically run @command{grub-mkconfig}. + The file @file{/etc/default/grub} controls the operation of @command{grub-mkconfig}. It is sourced by a shell script, and so must be valid POSIX shell input; normally, it will just be a sequence of From 8a748df2fdcabe3bbb4f0ca8654654ae55aac422 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 03:22:37 +0100 Subject: [PATCH 0764/1414] credit --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 35fd04154..3939f1d81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ * docs/grub.texi (Simple configuration): Explain some of the current limitations of grub-mkconfig. + Reported by: Leslie Rhorer. 2011-03-29 Vladimir Serbinenko From a7527639063a314a11af11bc11acb681bbc9e724 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 03:26:11 +0100 Subject: [PATCH 0765/1414] * docs/grub.texi (Changes from GRUB Legacy): Minor proofreading. --- ChangeLog | 6 +++++- docs/grub.texi | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3939f1d81..b34443efc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2011-03-30 Colin Watson +2011-03-30 Colin Watson + + * docs/grub.texi (Changes from GRUB Legacy): Minor proofreading. + +2011-03-30 Colin Watson * docs/grub.texi (Simple configuration): Explain some of the current limitations of grub-mkconfig. diff --git a/docs/grub.texi b/docs/grub.texi index 9ff72798b..a07377348 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -229,9 +229,10 @@ scripting language: variables, conditionals, and loops are available. @item A small amount of persistent storage is available across reboots, using the @command{save_env} and @command{load_env} commands in GRUB and the -@command{grub-editenv} utility. For safety reasons this storage is only -available when installed on plain disk (no LVM or RAID), using non-checksumming -filesystem (no ZFS) and using BIOS or EFI functions (no ATA, USB or IEEE1275) +@command{grub-editenv} utility. For safety reasons, this storage is only +available when installed on a plain disk (no LVM or RAID), using a +non-checksumming filesystem (no ZFS), and using BIOS or EFI functions (no +ATA, USB or IEEE1275). @item GRUB 2 has more reliable ways to find its own files and those of target From 2a2da1d030c71912cf11a07dffa8a155673fd4c6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 03:49:22 +0100 Subject: [PATCH 0766/1414] * docs/grub.texi (Menu-specific commands): Remove some semantics that were true in GRUB Legacy but not in GRUB 2. (submenu): New section. (false): New section. (read): New section. (true): New section. --- ChangeLog | 9 ++++++++ docs/grub.texi | 59 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b34443efc..9fc7fdcf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-03-30 Colin Watson + + * docs/grub.texi (Menu-specific commands): Remove some semantics + that were true in GRUB Legacy but not in GRUB 2. + (submenu): New section. + (false): New section. + (read): New section. + (true): New section. + 2011-03-30 Colin Watson * docs/grub.texi (Changes from GRUB Legacy): Minor proofreading. diff --git a/docs/grub.texi b/docs/grub.texi index a07377348..9abf1b174 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2411,9 +2411,6 @@ In rescue mode, only the @command{insmod} (@pxref{insmod}), @command{ls} The semantics used in parsing the configuration file are the following: @itemize @bullet -@item -The menu-specific commands have to be used before any others. - @item The files @emph{must} be in plain-text format. @@ -2427,20 +2424,13 @@ Options are separated by spaces. @item All numbers can be either decimal or hexadecimal. A hexadecimal number must be preceded by @samp{0x}, and is case-insensitive. - -@item -Extra options or text at the end of the line are ignored unless otherwise -specified. - -@item -Unrecognized commands are added to the current entry, except before entries -start, where they are ignored. @end itemize These commands can only be used in the menu: @menu * menuentry:: Start a menu entry +* submenu:: Group menu entries @end menu @@ -2470,6 +2460,22 @@ The @option{--hotkey} option associates a hotkey with a menu entry. @end deffn +@node submenu +@subsection submenu + +@deffn Command submenu @var{title} @ + [@option{--class=class} @dots{}] [@option{--users=users}] @ + [@option{--hotkey=key}] @ + @{ @var{menu entries} @dots{} @} +This defines a submenu. An entry called @var{title} will be added to the +menu; when that entry is selected, a new menu will be displayed showing all +the entries within this submenu. + +All options are the same as in the @command{menuentry} command +(@pxref{menuentry}). +@end deffn + + @node General commands @section The list of general commands @@ -2590,6 +2596,7 @@ you forget a command, you can run the command @command{help} * drivemap:: Map a drive to another * echo:: Display a line of text * export:: Export an environment variable +* false:: Do nothing, unsuccessfully * gettext:: Translate a string * gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer @@ -2607,10 +2614,12 @@ you forget a command, you can run the command @command{help} * password_pbkdf2:: Set a hashed password * play:: Play a tune * pxe_unload:: Unload the PXE environment +* read:: Read user input * reboot:: Reboot your computer * search:: Search devices by file, label, or UUID * sendkey:: Emulate keystrokes * set:: Set an environment variable +* true:: Do nothing, successfully * unset:: Unset an environment variable * uppermem:: Set the upper memory size @end menu @@ -2853,6 +2862,15 @@ to subsidiary configuration files loaded using @command{configfile}. @end deffn +@node false +@subsection false + +@deffn Command false +Do nothing, unsuccessfully. This is mainly useful in control constructs +such as @code{if} and @code{while} (@pxref{Shell-like scripting}). +@end deffn + + @node gettext @subsection gettext @@ -3106,6 +3124,16 @@ This command is only available on PC BIOS systems. @end deffn +@node read +@subsection read + +@deffn Command read [var] +Read a line of input from the user. If an environment variable @var{var} is +given, set that environment variable to the line of input that was read, +with no terminating newline. +@end deffn + + @node reboot @subsection reboot @@ -3294,6 +3322,15 @@ arguments, print all environment variables with their values. @end deffn +@node true +@subsection true + +@deffn Command true +Do nothing, successfully. This is mainly useful in control constructs such +as @code{if} and @code{while} (@pxref{Shell-like scripting}). +@end deffn + + @node unset @subsection unset From 5d8031749e8b8642d31f6f9da510bca3872ffea2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 09:26:23 +0200 Subject: [PATCH 0767/1414] * grub-core/term/at_keyboard.c (set_scancodes) [!GRUB_MACHINE_MIPS_YEELOONG && !GRUB_MACHINE_QEMU]: Use scancode set 1. --- ChangeLog | 5 +++++ grub-core/term/at_keyboard.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9fc7fdcf0..778d86145 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c (set_scancodes) + [!GRUB_MACHINE_MIPS_YEELOONG && !GRUB_MACHINE_QEMU]: Use scancode set 1. + 2011-03-30 Colin Watson * docs/grub.texi (Menu-specific commands): Remove some semantics diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 55cb76483..7ce287ecc 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -330,6 +330,11 @@ set_scancodes (void) return; } +#if !(defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_QEMU)) + current_set = 1; + return; +#endif + grub_keyboard_controller_write (grub_keyboard_controller_orig & ~KEYBOARD_AT_TRANSLATE); From e1ad0edd11ea71bdb059fd2768a5e2dbe6589315 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 09:35:35 +0200 Subject: [PATCH 0768/1414] * docs/grub.texi: Correctly use "terminal_input" and not "terminal" in the example. --- ChangeLog | 5 +++++ docs/grub.texi | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 778d86145..c28b07653 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Vladimir Serbinenko + + * docs/grub.texi: Correctly use "terminal_input" and not "terminal" in + the example. + 2011-03-30 Vladimir Serbinenko * grub-core/term/at_keyboard.c (set_scancodes) diff --git a/docs/grub.texi b/docs/grub.texi index 9abf1b174..a347579b3 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1998,7 +1998,7 @@ The commands @command{terminal_input} (@pxref{terminal_input}) and @command{terminal_output} (@pxref{terminal_output}) choose which type of terminal you want to use. In the case above, the terminal will be a serial terminal, but you can also pass @code{console} to the command, -as @samp{terminal serial console}. In this case, a terminal in which +as @samp{terminal_input serial console}. In this case, a terminal in which you press any key will be selected as a GRUB terminal. In the example above, note that you need to put both commands on the same command line, as you will lose the ability to type commands on the console after the first From 421284f2998aa3e9134372379a2bd03de08a2740 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 10:19:08 +0100 Subject: [PATCH 0769/1414] * docs/grub.texi (Simple configuration): Update GRUB_GFXMODE documentation. --- ChangeLog.vbe-autodetect | 2 ++ docs/grub.texi | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog.vbe-autodetect b/ChangeLog.vbe-autodetect index 3341e8cc3..6308e5793 100644 --- a/ChangeLog.vbe-autodetect +++ b/ChangeLog.vbe-autodetect @@ -29,3 +29,5 @@ * util/grub.d/00_header.in (GRUB_GFXMODE): Default to "auto". This is more appropriate on a wider range of platforms than 640x480. + * docs/grub.texi (Simple configuration): Update GRUB_GFXMODE + documentation. diff --git a/docs/grub.texi b/docs/grub.texi index 54a2d8791..885bb4731 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1140,7 +1140,8 @@ listed in @file{/boot/grub/video.lst}. Set the resolution used on the @samp{gfxterm} graphical terminal. Note that you can only use modes which your graphics card supports via VESA BIOS Extensions (VBE), so for example native LCD panel resolutions may not be -available. The default is @samp{640x480}. +available. The default is @samp{auto}, which tries to select a preferred +resolution. @item GRUB_BACKGROUND Set a background image for use with the @samp{gfxterm} graphical terminal. From abf042006ef39370254e3758970d9bcab37218cb Mon Sep 17 00:00:00 2001 From: <> Date: Wed, 30 Mar 2011 11:31:33 +0100 Subject: [PATCH 0770/1414] * docs/grub.texi (Environment): New chapter. (Changes from GRUB Legacy): Link to "Environment block" section for details of limitations. (Simple configuration): Likewise. Link to documentation of gfxmode and gfxpayload variables from GRUB_GFXMODE and GRUB_GFXPAYLOAD respectively. (Shell-like scripting): Note that normal variables are stored in the environment. (gettext): Link to documentation of lang and locale_dir. (list_env): New section. (load_env): New section. (save_env): New section. (Reporting bugs): Fix typo. --- ChangeLog | 17 ++ docs/grub.texi | 493 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 498 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index c28b07653..61727a1dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-03-30 Colin Watson + + * docs/grub.texi (Environment): New chapter. + (Changes from GRUB Legacy): Link to "Environment block" section for + details of limitations. + (Simple configuration): Likewise. Link to documentation of gfxmode + and gfxpayload variables from GRUB_GFXMODE and GRUB_GFXPAYLOAD + respectively. + (Shell-like scripting): Note that normal variables are stored in the + environment. + (gettext): Link to documentation of lang and locale_dir. + (list_env): New section. + (load_env): New section. + (save_env): New section. + + (Reporting bugs): Fix typo. + 2011-03-30 Vladimir Serbinenko * docs/grub.texi: Correctly use "terminal_input" and not "terminal" in diff --git a/docs/grub.texi b/docs/grub.texi index a347579b3..8441dd267 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -87,6 +87,7 @@ This edition documents version @value{VERSION}. * Images:: GRUB image files * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line +* Environment:: GRUB environment variables * Commands:: The list of available builtin commands * Security:: Authentication and authorisation * Supported kernels:: The list of supported kernels @@ -229,10 +230,8 @@ scripting language: variables, conditionals, and loops are available. @item A small amount of persistent storage is available across reboots, using the @command{save_env} and @command{load_env} commands in GRUB and the -@command{grub-editenv} utility. For safety reasons, this storage is only -available when installed on a plain disk (no LVM or RAID), using a -non-checksumming filesystem (no ZFS), and using BIOS or EFI functions (no -ATA, USB or IEEE1275). +@command{grub-editenv} utility. This is not available in all configurations +(@pxref{Environment block}). @item GRUB 2 has more reliable ways to find its own files and those of target @@ -1109,8 +1108,8 @@ it as a new default entry for use by future runs of GRUB. This is only useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because @samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with @command{grub-set-default} or @command{grub-reboot}. Unset by default. -@samp{save_env} may not be available in all situations -(@pxref{Changes from GRUB Legacy}). +This option relies on the environment block, which may not be available in +all situations (@pxref{Environment block}). @item GRUB_TIMEOUT Boot the default entry this many seconds after the menu is displayed, unless @@ -1215,7 +1214,7 @@ listed in @file{/boot/grub/video.lst}. Set the resolution used on the @samp{gfxterm} graphical terminal. Note that you can only use modes which your graphics card supports via VESA BIOS Extensions (VBE), so for example native LCD panel resolutions may not be -available. The default is @samp{640x480}. +available. The default is @samp{640x480}. @xref{gfxmode}. @item GRUB_BACKGROUND Set a background image for use with the @samp{gfxterm} graphical terminal. @@ -1231,7 +1230,7 @@ Set to @samp{text} to force the Linux kernel to boot in normal text mode, @samp{keep} to preserve the graphics mode set using @samp{GRUB_GFXMODE}, @samp{@var{width}x@var{height}}[@samp{x@var{depth}}] to set a particular graphics mode, or a sequence of these separated by commas or semicolons to -try several modes in sequence. +try several modes in sequence. @xref{gfxpayload}. Depending on your kernel, your distribution, your graphics card, and the phase of the moon, note that using this option may cause GNU/Linux to suffer @@ -1342,7 +1341,8 @@ protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name. Normal variable names begin with an alphabetic character, followed by zero -or more alphanumeric characters. +or more alphanumeric characters. These names refer to entries in the GRUB +environment (@pxref{Environment}). Positional variable names consist of one or more digits. They represent parameters passed to function calls, with @samp{$1} representing the first @@ -2384,6 +2384,437 @@ Although GRUB unfortunately does not support @dfn{undo}, you can do almost the same thing by just returning to the main menu using @key{ESC}. +@node Environment +@chapter GRUB environment variables + +GRUB supports environment variables which are rather like those offered by +all Unix-like systems. Environment variables have a name, which is unique +and is usually a short identifier, and a value, which is an arbitrary string +of characters. They may be set (@pxref{set}), unset (@pxref{unset}), or +looked up (@pxref{Shell-like scripting}) by name. + +A number of environment variables have special meanings to various parts of +GRUB. Others may be used freely in GRUB configuration files. + + +@menu +* Special environment variables:: +* Environment block:: +@end menu + + +@node Special environment variables +@section Special environment variables + +These variables have special meaning to GRUB. + +@menu +* biosnum:: +* chosen:: +* color_highlight:: +* color_normal:: +* debug:: +* default:: +* fallback:: +* gfxmode:: +* gfxpayload:: +* gfxterm_font:: +* icondir:: +* lang:: +* locale_dir:: +* menu_color_highlight:: +* menu_color_normal:: +* net_pxe_boot_file:: +* net_pxe_dhcp_server_name:: +* net_pxe_domain:: +* net_pxe_extensionspath:: +* net_pxe_hostname:: +* net_pxe_ip:: +* net_pxe_mac:: +* net_pxe_rootpath:: +* pager:: +* prefix:: +* pxe_blksize:: +* pxe_default_gateway:: +* pxe_default_server:: +* root:: +* superusers:: +* theme:: +* timeout:: +@end menu + + +@node biosnum +@subsection biosnum + +When chain-loading another boot loader (@pxref{Chain-loading}), GRUB may +need to know what BIOS drive number corresponds to the root device +(@pxref{root}) so that it can set up registers properly. If the +@var{biosnum} variable is set, it overrides GRUB's own means of guessing +this. + +For an alternative approach which also changes BIOS drive mappings for the +chain-loaded system, @pxref{drivemap}. + + +@node chosen +@subsection chosen + +When executing a menu entry, GRUB sets the @var{chosen} variable to the +title of the entry being executed. + +If the menu entry is in one or more submenus, then @var{chosen} is set to +the titles of each of the submenus starting from the top level followed by +the title of the menu entry itself, separated by @samp{>}. + + +@node color_highlight +@subsection color_highlight + +This variable contains the ``highlight'' foreground and background terminal +colors, separated by a slash (@samp{/}). Setting this variable changes +those colors. For the available color names, @pxref{color_normal}. + +The default is @samp{black/white}. + + +@node color_normal +@subsection color_normal + +This variable contains the ``normal'' foreground and background terminal +colors, separated by a slash (@samp{/}). Setting this variable changes +those colors. Each color must be a name from the following list: + +@itemize @bullet +@item black +@item blue +@item green +@item cyan +@item red +@item magenta +@item brown +@item light-gray +@item dark-gray +@item light-blue +@item light-green +@item light-cyan +@item light-red +@item light-magenta +@item yellow +@item white +@end itemize + +The default is @samp{white/black}. + + +@node debug +@subsection debug + +This variable may be set to enable debugging output from various components +of GRUB. The value is a list of debug facility names separated by +whitespace or @samp{,}, or @samp{all} to enable all available debugging +output. + + +@node default +@subsection default + +If this variable is set, it identifies a menu entry that should be selected +by default, possibly after a timeout (@pxref{timeout}). The entry may be +identified by number or by title. + +If the entry is in a submenu, then it must be identified using the titles of +each of the submenus starting from the top level followed by the number or +title of the menu entry itself, separated by @samp{>}. For example, take +the following menu structure: + +@itemize @w +@item Submenu 1 +@itemize @w +@item Menu Entry 1 +@item Menu Entry 2 +@end itemize +@item Submenu 2 +@itemize @w +@item Submenu 3 +@itemize @w +@item Menu Entry 3 +@item Menu Entry 4 +@end itemize +@item Menu Entry 5 +@end itemize +@end itemize + +``Menu Entry 3'' would then be identified as +@samp{Submenu 2>Submenu 3>Menu Entry 3}. + +This variable is often set by @samp{GRUB_DEFAULT} (@pxref{Simple +configuration}), @command{grub-set-default}, or @command{grub-reboot}. + + +@node fallback +@subsection fallback + +If this variable is set, it identifies a menu entry that should be selected +if the default menu entry fails to boot. Entries are identified in the same +way as for @samp{default} (@pxref{default}). + + +@node gfxmode +@subsection gfxmode + +If this variable is set, it sets the resolution used on the @samp{gfxterm} +graphical terminal. Note that you can only use modes which your graphics +card supports via VESA BIOS Extensions (VBE), so for example native LCD +panel resolutions may not be available. The default is @samp{auto}, which +selects a platform-specific default that should look reasonable. + +The resolution may be specified as a sequence of one or more modes, +separated by commas (@samp{,}) or semicolons (@samp{;}); each will be tried +in turn until one is found. Each mode should be either @samp{auto}, +@samp{@var{width}x@var{height}}, or +@samp{@var{width}x@var{height}x@var{depth}}. + + +@node gfxpayload +@subsection gfxpayload + +If this variable is set, it controls the video mode in which the Linux +kernel starts up, replacing the @samp{vga=} boot option (@pxref{linux}). It +may be set to @samp{text} to force the Linux kernel to boot in normal text +mode, @samp{keep} to preserve the graphics mode set using @samp{gfxmode}, or +any of the permitted values for @samp{gfxmode} to set a particular graphics +mode (@pxref{gfxmode}). + +Depending on your kernel, your distribution, your graphics card, and the +phase of the moon, note that using this option may cause GNU/Linux to suffer +from various display problems, particularly during the early part of the +boot sequence. If you have problems, set this variable to @samp{text} and +GRUB will tell Linux to boot in normal text mode. + +The default is platform-specific. On platforms with a native text mode +(such as PC BIOS platforms), the default is @samp{text}. Otherwise the +default may be @samp{auto} or a specific video mode. + +This variable is often set by @samp{GRUB_GFXPAYLOAD_LINUX} (@pxref{Simple +configuration}). + + +@node gfxterm_font +@subsection gfxterm_font + +If this variable is set, it names a font to use for text on the +@samp{gfxterm} graphical terminal. Otherwise, @samp{gfxterm} may use any +available font. + + +@node icondir +@subsection icondir + +If this variable is set, it names a directory in which the GRUB graphical +menu should look for icons after looking in the theme's @samp{icons} +directory. @xref{Theme file format}. + + +@node lang +@subsection lang + +If this variable is set, it names the language code that the +@command{gettext} command (@pxref{gettext}) uses to translate strings. For +example, French would be named as @samp{fr}, and Simplified Chinese as +@samp{zh_CN}. + +@command{grub-mkconfig} (@pxref{Simple configuration}) will try to set a +reasonable default for this variable based on the system locale. + + +@node locale_dir +@subsection locale_dir + +If this variable is set, it names the directory where translation files may +be found (@pxref{gettext}), usually @file{/boot/grub/locale}. Otherwise, +internationalization is disabled. + +@command{grub-mkconfig} (@pxref{Simple configuration}) will set a reasonable +default for this variable if internationalization is needed and any +translation files are available. + + +@node menu_color_highlight +@subsection menu_color_highlight + +This variable contains the foreground and background colors to be used for +the highlighted menu entry, separated by a slash (@samp{/}). Setting this +variable changes those colors. For the available color names, +@pxref{color_normal}. + +The default is the value of @samp{color_highlight} +(@pxref{color_highlight}). + + +@node menu_color_normal +@subsection menu_color_normal + +This variable contains the foreground and background colors to be used for +non-highlighted menu entries, separated by a slash (@samp{/}). Setting this +variable changes those colors. For the available color names, +@pxref{color_normal}. + +The default is the value of @samp{color_normal} (@pxref{color_normal}). + + +@node net_pxe_boot_file +@subsection net_pxe_boot_file + +@xref{Network}. + + +@node net_pxe_dhcp_server_name +@subsection net_pxe_dhcp_server_name + +@xref{Network}. + + +@node net_pxe_domain +@subsection net_pxe_domain + +@xref{Network}. + + +@node net_pxe_extensionspath +@subsection net_pxe_extensionspath + +@xref{Network}. + + +@node net_pxe_hostname +@subsection net_pxe_hostname + +@xref{Network}. + + +@node net_pxe_ip +@subsection net_pxe_ip + +@xref{Network}. + + +@node net_pxe_mac +@subsection net_pxe_mac + +@xref{Network}. + + +@node net_pxe_rootpath +@subsection net_pxe_rootpath + +@xref{Network}. + + +@node pager +@subsection pager + +If set to @samp{1}, pause output after each screenful and wait for keyboard +input. The default is not to pause output. + + +@node prefix +@subsection prefix + +The location of the @samp{/boot/grub} directory as an absolute file name +(@pxref{File name syntax}). This is normally set by GRUB at startup based +on information provided by @command{grub-install}. GRUB modules are +dynamically loaded from this directory, so it must be set correctly in order +for many parts of GRUB to work. + + +@node pxe_blksize +@subsection pxe_blksize + +@xref{Network}. + + +@node pxe_default_gateway +@subsection pxe_default_gateway + +@xref{Network}. + + +@node pxe_default_server +@subsection pxe_default_server + +@xref{Network}. + + +@node root +@subsection root + +The root device name (@pxref{Device syntax}). Any file names that do not +specify an explicit device name are read from this device. The default is +normally set by GRUB at startup based on the value of @samp{prefix} +(@pxref{prefix}). + +For example, if GRUB was installed to the first partition of the first hard +disk, then @samp{prefix} might be set to @samp{(hd0,msdos1)/boot/grub} and +@samp{root} to @samp{hd0,msdos1}. + + +@node superusers +@subsection superusers + +This variable may be set to a list of superuser names to enable +authentication support. @xref{Security}. + + +@node theme +@subsection theme + +This variable may be set to a directory containing a GRUB graphical menu +theme. @xref{Theme file format}. + +This variable is often set by @samp{GRUB_THEME} (@pxref{Simple +configuration}). + + +@node timeout +@subsection timeout + +If this variable is set, it specifies the time in seconds to wait for +keyboard input before booting the default menu entry. A timeout of @samp{0} +means to boot the default entry immediately without displaying the menu; a +timeout of @samp{-1} (or unset) means to wait indefinitely. + +This variable is often set by @samp{GRUB_TIMEOUT} or +@samp{GRUB_HIDDEN_TIMEOUT} (@pxref{Simple configuration}). + + +@node Environment block +@section The GRUB environment block + +It is often useful to be able to remember a small amount of information from +one boot to the next. For example, you might want to set the default menu +entry based on what was selected the last time. GRUB deliberately does not +implement support for writing files in order to minimise the possibility of +the boot loader being responsible for file system corruption, so a GRUB +configuration file cannot just create a file in the ordinary way. However, +GRUB provides an ``environment block'' which can be used to save a small +amount of state. + +The environment block is a preallocated 1024-byte file, which normally lives +in @file{/boot/grub/grubenv} (although you should not assume this). At boot +time, the @command{load_env} command (@pxref{load_env}) loads environment +variables from it, and the @command{save_env} (@pxref{save_env}) command +saves environment variables to it. From a running system, the +@command{grub-editenv} utility can be used to edit the environment block. + +For safety reasons, this storage is only available when installed on a plain +disk (no LVM or RAID), using a non-checksumming filesystem (no ZFS), and +using BIOS or EFI functions (no ATA, USB or IEEE1275). + +@command{grub-mkconfig} uses this facility to implement +@samp{GRUB_SAVEDEFAULT} (@pxref{Simple configuration}). + + @node Commands @chapter The list of available commands @@ -2607,6 +3038,8 @@ you forget a command, you can run the command @command{help} * keystatus:: Check key modifier status * linux:: Load a Linux kernel * linux16:: Load a Linux kernel (16-bit mode) +* list_env:: List variables in environment block +* load_env:: Load variables from environment block * loopback:: Make a device from a filesystem image * ls:: List devices or files * parttool:: Modify partition table entries @@ -2616,6 +3049,7 @@ you forget a command, you can run the command @command{help} * pxe_unload:: Unload the PXE environment * read:: Read user input * reboot:: Reboot your computer +* save_env:: Save variables to environment block * search:: Search devices by file, label, or UUID * sendkey:: Emulate keystrokes * set:: Set an environment variable @@ -2878,8 +3312,8 @@ such as @code{if} and @code{while} (@pxref{Shell-like scripting}). Translate @var{string} into the current language. The current language code is stored in the @samp{lang} variable in GRUB's -environment. Translation files in MO format are read from -@samp{locale_dir}, usually @file{/boot/grub/locale}. +environment (@pxref{lang}). Translation files in MO format are read from +@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub/locale}. @end deffn @@ -3008,6 +3442,29 @@ This command is only available on x86 systems. @end deffn +@node list_env +@subsection list_env + +@deffn Command list_env [@option{-f} file] +List all variables in the environment block file. @xref{Environment block}. + +The @option{-f} option overrides the default location of the environment +block. +@end deffn + + +@node load_env +@subsection load_env + +@deffn Command load_env [@option{-f} file] +Load all variables from the environment block file into the environment. +@xref{Environment block}. + +The @option{-f} option overrides the default location of the environment +block. +@end deffn + + @node loopback @subsection loopback @@ -3142,6 +3599,18 @@ Reboot the computer. @end deffn +@node save_env +@subsection save_env + +@deffn Command save_env [@option{-f} file] var @dots{} +Save the named variables from the environment to the environment block file. +@xref{Environment block}. + +The @option{-f} option overrides the default location of the environment +block. +@end deffn + + @node search @subsection search @@ -3868,7 +4337,7 @@ for. @item Write down anything that you think might be related. Please understand -that we often need to reproduce the same problem you encounterred in our +that we often need to reproduce the same problem you encountered in our environment. So your information should be sufficient for us to do the same thing---Don't forget that we cannot see your computer directly. If you are not sure whether to state a fact or leave it out, state it! From 3d7ed04e92786d287be33a31aa62daff823e4435 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 11:34:52 +0100 Subject: [PATCH 0771/1414] * docs/grub.texi (Future): Update. --- ChangeLog | 4 ++++ docs/grub.texi | 11 +++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61727a1dd..10bb289cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-30 Colin Watson + + * docs/grub.texi (Future): Update. + 2011-03-30 Colin Watson * docs/grub.texi (Environment): New chapter. diff --git a/docs/grub.texi b/docs/grub.texi index 8441dd267..1c21cb67d 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4357,12 +4357,11 @@ Once we get your report, we will try to fix the bugs. @node Future @appendix Where GRUB will go -We started the next generation of GRUB, GRUB 2. GRUB 2 includes -internationalization, dynamic module loading, real memory management, -multiple architecture support, a scripting language, and many other -nice features. If you are interested in the development of GRUB 2, take -a look at @uref{http://www.gnu.org/software/grub/grub.html, the -homepage}. +GRUB 2 is now quite stable and used in many production systems. We are +currently working towards a 2.0 release. + +If you are interested in the development of GRUB 2, take a look at +@uref{http://www.gnu.org/software/grub/grub.html, the homepage}. @node Internals From 2d5d0333d6982e175edc5982b487cf11514e1fb3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 11:46:36 +0100 Subject: [PATCH 0772/1414] * docs/grub.texi (default): Use @example rather than nested itemized lists to avoid breaking gendocs. --- ChangeLog | 5 +++++ docs/grub.texi | 26 ++++++++++---------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 10bb289cc..1e20b132e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Colin Watson + + * docs/grub.texi (default): Use @example rather than nested + itemized lists to avoid breaking gendocs. + 2011-03-30 Colin Watson * docs/grub.texi (Future): Update. diff --git a/docs/grub.texi b/docs/grub.texi index 1c21cb67d..dd3afcf48 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2528,22 +2528,16 @@ each of the submenus starting from the top level followed by the number or title of the menu entry itself, separated by @samp{>}. For example, take the following menu structure: -@itemize @w -@item Submenu 1 -@itemize @w -@item Menu Entry 1 -@item Menu Entry 2 -@end itemize -@item Submenu 2 -@itemize @w -@item Submenu 3 -@itemize @w -@item Menu Entry 3 -@item Menu Entry 4 -@end itemize -@item Menu Entry 5 -@end itemize -@end itemize +@example +Submenu 1 + Menu Entry 1 + Menu Entry 2 +Submenu 2 + Submenu 3 + Menu Entry 3 + Menu Entry 4 + Menu Entry 5 +@end example ``Menu Entry 3'' would then be identified as @samp{Submenu 2>Submenu 3>Menu Entry 3}. From 87d1aa1927c2e91dcd37341e6e363011a8a48c05 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 13:02:39 +0200 Subject: [PATCH 0773/1414] * grub-core/disk/lvm.c (grub_lvm_scan_device): Remove spurious \n. --- ChangeLog | 4 ++++ grub-core/disk/lvm.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1e20b132e..103d12189 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,10 @@ (Reporting bugs): Fix typo. +2011-03-30 Vladimir Serbinenko + + * grub-core/disk/lvm.c (grub_lvm_scan_device): Remove spurious \n. + 2011-03-30 Vladimir Serbinenko * docs/grub.texi: Correctly use "terminal_input" and not "terminal" in diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index b1a7a50a9..5a79063da 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -336,7 +336,7 @@ grub_lvm_scan_device (const char *name) if (i == GRUB_LVM_LABEL_SCAN_SECTORS) { #ifdef GRUB_UTIL - grub_util_info ("no LVM signature found\n"); + grub_util_info ("no LVM signature found"); #endif goto fail; } From 5e631b4fcb6cf6a5b47834a55a32c65c1121c905 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 12:07:43 +0100 Subject: [PATCH 0774/1414] fix ChangeLog ordering --- ChangeLog | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 103d12189..b251826af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-30 Vladimir Serbinenko + + * grub-core/disk/lvm.c (grub_lvm_scan_device): Remove spurious \n. + 2011-03-30 Colin Watson * docs/grub.texi (default): Use @example rather than nested @@ -24,10 +28,6 @@ (Reporting bugs): Fix typo. -2011-03-30 Vladimir Serbinenko - - * grub-core/disk/lvm.c (grub_lvm_scan_device): Remove spurious \n. - 2011-03-30 Vladimir Serbinenko * docs/grub.texi: Correctly use "terminal_input" and not "terminal" in From c871b1c6d0ff9dcb79f7b4b9503eacfa8b405509 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 13:13:25 +0200 Subject: [PATCH 0775/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Add few potentially useful grub_util_info. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index b251826af..b93141df6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Add + few potentially useful grub_util_info. + 2011-03-30 Vladimir Serbinenko * grub-core/disk/lvm.c (grub_lvm_scan_device): Remove spurious \n. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 9900a79bd..d5b0439fb 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1518,6 +1518,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (stat (os_dev, &st) < 0) { grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev); + grub_util_info ("cannot stat `%s'", os_dev); return 0; } @@ -1526,6 +1527,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no mapping exists for `%s'", os_dev); + grub_util_info ("no mapping exists for `%s'", os_dev); return 0; } From 56445fb2b459f3dce2b7dc8b70cf9db90aae9d88 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 16:37:10 +0200 Subject: [PATCH 0776/1414] * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev) [__linux__]: Preserve partition number in mdadm code path. --- ChangeLog | 5 +++++ grub-core/kern/emu/getroot.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index b93141df6..0afcadf68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Vladimir Serbinenko + + * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev) [__linux__]: + Preserve partition number in mdadm code path. + 2011-03-30 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Add diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 1d87442d9..ae066d2f8 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -808,12 +808,30 @@ grub_util_get_grub_dev (const char *os_dev) if (mdadm_name) { char *newname; + char *q; + + for (q = os_dev + strlen (os_dev) - 1; q >= os_dev && isdigit (*q); + q--); + + if (q >= os_dev && *q == 'p') + { + newname = xasprintf ("/dev/md/%sp%s", mdadm_name, q + 1); + if (stat (newname, &st) == 0) + { + free (grub_dev); + grub_dev = xasprintf ("md/%s,%s", mdadm_name, q + 1); + goto done; + } + free (newname); + } newname = xasprintf ("/dev/md/%s", mdadm_name); if (stat (newname, &st) == 0) { free (grub_dev); grub_dev = xasprintf ("md/%s", mdadm_name); } + + done: free (newname); free (mdadm_name); } From 241e41f55c5cb9b05f7f596a8ea039bcb6ebb031 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 16:54:11 +0200 Subject: [PATCH 0777/1414] * grub-core/disk/raid.c (insert_array): Add few potentially useful grub_util_info. (grub_raid_register): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/raid.c | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0afcadf68..35a2de3e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-30 Vladimir Serbinenko + + * grub-core/disk/raid.c (insert_array): Add few potentially + useful grub_util_info. + (grub_raid_register): Likewise. + 2011-03-30 Vladimir Serbinenko * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev) [__linux__]: diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 9d2468b88..c89ca62a1 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -638,6 +638,10 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_dprintf ("raid", "Found array %s (%s)\n", array->name, scanner_name); +#ifdef GRUB_UTIL + grub_util_info ("Found array %s (%s)", array->name, + scanner_name); +#endif /* Add our new array to the list. */ array->next = array_list; @@ -698,6 +702,10 @@ grub_raid_register (grub_raid_t raid) grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n", grub_raid_list->name, name); +#ifdef GRUB_UTIL + grub_util_info ("Scanning for %s RAID devices on disk %s", + grub_raid_list->name, name); +#endif disk = grub_disk_open (name); if (!disk) From baad885c14a5e982e19ad8d8c00177dd8ffda8e4 Mon Sep 17 00:00:00 2001 From: Alexey Shvetsov Date: Wed, 30 Mar 2011 19:22:28 +0200 Subject: [PATCH 0778/1414] * util/grub.d/10_linux.in: Add gentoo-specific Linux and initrd names. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 8 +++++--- util/grub.d/20_linux_xen.in | 6 ++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35a2de3e3..462b15810 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Alexey Shvetsov + + * util/grub.d/10_linux.in: Add gentoo-specific Linux and initrd names. + * util/grub.d/20_linux_xen.in: Likewise. + 2011-03-30 Vladimir Serbinenko * grub-core/disk/raid.c (insert_array): Add few potentially diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index d12902e33..9d13529d6 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -113,11 +113,11 @@ EOF case x`uname -m` in xi?86 | xx86_64) - list=`for i in /boot/vmlinuz-* /vmlinuz-* ; do + list=`for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` ;; *) - list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do + list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` ;; esac @@ -138,7 +138,9 @@ while [ "x$list" != "x" ] ; do for i in "initrd.img-${version}" "initrd-${version}.img" \ "initrd-${version}" "initramfs-${version}.img" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ - "initrd-${alt_version}" "initramfs-${alt_version}.img"; do + "initrd-${alt_version}" "initramfs-${alt_version}.img" \ + "initramfs-genkernel-${version}" \ + "initramfs-genkernel-${alt_version}"; do if test -e "${dirname}/${i}" ; then initrd="$i" break diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index bacd8ffea..50938d1c7 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -93,7 +93,7 @@ EOF EOF } -linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do +linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do basename=$(basename $i) version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") if grub_file_is_not_garbage "$i" && (grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" /boot/config-${version} 2> /dev/null); then echo -n "$i " ; fi @@ -127,7 +127,9 @@ while [ "x${xen_list}" != "x" ] ; do initrd= for i in "initrd.img-${version}" "initrd-${version}.img" \ "initrd-${version}" "initrd.img-${alt_version}" \ - "initrd-${alt_version}.img" "initrd-${alt_version}"; do + "initrd-${alt_version}.img" "initrd-${alt_version}" \ + "initramfs-genkernel-${version}" \ + "initramfs-genkernel-${alt_version}" ; do if test -e "${dirname}/${i}" ; then initrd="$i" break From 090b1b6ac665f656a5f3ba0e3e59d9d138994238 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Mar 2011 20:42:42 +0200 Subject: [PATCH 0779/1414] * util/grub.d/10_linux.in: Try alternative config filenames where we parse config file. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 6 ++++++ util/grub.d/10_linux.in | 13 +++++++++---- util/grub.d/20_linux_xen.in | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 462b15810..95e7363a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-30 Vladimir Serbinenko + + * util/grub.d/10_linux.in: Try alternative config filenames where + we parse config file. + * util/grub.d/20_linux_xen.in: Likewise. + 2011-03-30 Alexey Shvetsov * util/grub.d/10_linux.in: Add gentoo-specific Linux and initrd names. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 9d13529d6..4f8a7927c 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -73,8 +73,8 @@ linux_entry () cat << EOF load_video EOF - if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null \ - && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then + if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \ + && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2> /dev/null; then cat << EOF set gfxpayload=keep EOF @@ -147,14 +147,19 @@ while [ "x$list" != "x" ] ; do fi done - initramfs= + config= for i in "config-${version}" "config-${alt_version}"; do if test -e "${dirname}/${i}" ; then - initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${dirname}/${i}" | cut -f2 -d= | tr -d \"` + config="${dirname}/${i}" break fi done + initramfs= + if test -n "${config}" ; then + initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"` + fi + if test -n "${initrd}" ; then echo "Found initrd image: ${dirname}/${initrd}" >&2 elif test -z "${initramfs}" ; then diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 50938d1c7..59a953ebb 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -94,10 +94,20 @@ EOF } linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do + if grub_file_is_not_garbage "$i"; then basename=$(basename $i) version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") - if grub_file_is_not_garbage "$i" && (grep -qx "CONFIG_XEN_DOM0=y" /boot/config-${version} 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" /boot/config-${version} 2> /dev/null); then echo -n "$i " ; fi - done` + dirname=$(dirname $i) + config= + for j in "config-${version}" "config-${alt_version}"; do + if test -e "${dirname}/${j}" ; then + config="${dirname}/${j}" + break + fi + done + if (grep -qx "CONFIG_XEN_DOM0=y" "${config}" 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" "${config}" 2> /dev/null); then echo -n "$i " ; fi + fi + done` if [ "x${linux_list}" = "x" ] ; then exit 0 fi From fd7cd914c6763c4aa2810974c69dc0edb3000946 Mon Sep 17 00:00:00 2001 From: Alexey Shvetsov Date: Wed, 30 Mar 2011 20:53:23 +0200 Subject: [PATCH 0780/1414] * util/grub.d/10_linux.in: Add gentoo-specific config filename. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 6 +++--- util/grub.d/20_linux_xen.in | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95e7363a2..d0f2acacc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Alexey Shvetsov + + * util/grub.d/10_linux.in: Add gentoo-specific config filename. + * util/grub.d/20_linux_xen.in: Likewise. + 2011-03-30 Vladimir Serbinenko * util/grub.d/10_linux.in: Try alternative config filenames where diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 4f8a7927c..930ce06ef 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -148,9 +148,9 @@ while [ "x$list" != "x" ] ; do done config= - for i in "config-${version}" "config-${alt_version}"; do - if test -e "${dirname}/${i}" ; then - config="${dirname}/${i}" + for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do + if test -e "${i}" ; then + config="${i}" break fi done diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 59a953ebb..858627aa3 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -99,9 +99,9 @@ linux_list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") dirname=$(dirname $i) config= - for j in "config-${version}" "config-${alt_version}"; do - if test -e "${dirname}/${j}" ; then - config="${dirname}/${j}" + for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do + if test -e "${j}" ; then + config="${j}" break fi done From 875b67ba09992be7f75534513d84e505789c48b5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 30 Mar 2011 20:52:26 +0100 Subject: [PATCH 0781/1414] * docs/grub.texi (Commands): Link to "GRUB only offers a rescue shell". --- ChangeLog | 5 +++++ docs/grub.texi | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d0f2acacc..1a533ae17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-30 Colin Watson + + * docs/grub.texi (Commands): Link to "GRUB only offers a rescue + shell". + 2011-03-30 Alexey Shvetsov * util/grub.d/10_linux.in: Add gentoo-specific config filename. diff --git a/docs/grub.texi b/docs/grub.texi index dd3afcf48..fa38b96ff 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2821,7 +2821,9 @@ anywhere in the menu or specifically in the menu entries. In rescue mode, only the @command{insmod} (@pxref{insmod}), @command{ls} (@pxref{ls}), @command{set} (@pxref{set}), and @command{unset} -(@pxref{unset}) commands are normally available. +(@pxref{unset}) commands are normally available. If you end up in rescue +mode and do not know what to do, then @pxref{GRUB only offers a rescue +shell}. @menu * Menu-specific commands:: From a826cc7d7e09da20b514f3e2b973f89888d3d994 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 31 Mar 2011 08:46:41 +0100 Subject: [PATCH 0782/1414] * docs/grub.texi (Simple configuration): Be more explicit about GRUB_DEFAULT, and add an example. Reported by: Leslie Rhorer. --- ChangeLog | 6 ++++++ docs/grub.texi | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a533ae17..ff9582918 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-31 Colin Watson + + * docs/grub.texi (Simple configuration): Be more explicit about + GRUB_DEFAULT, and add an example. + Reported by: Leslie Rhorer. + 2011-03-30 Colin Watson * docs/grub.texi (Commands): Link to "GRUB only offers a rescue diff --git a/docs/grub.texi b/docs/grub.texi index fa38b96ff..0808ded6b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1091,11 +1091,25 @@ Valid keys in @file{/etc/default/grub} are as follows: @table @samp @item GRUB_DEFAULT The default menu entry. This may be a number, in which case it identifies -the Nth entry in the generated menu counted from zero, or the full name of a -menu entry, or the special string @samp{saved}. Using the full name may be +the Nth entry in the generated menu counted from zero, or the title of a +menu entry, or the special string @samp{saved}. Using the title may be useful if you want to set a menu entry as the default even though there may be a variable number of entries before it. +For example, if you have: + +@verbatim +menuentry 'Example GNU/Linux distribution' --class gnu-linux { + ... +} +@end verbatim + +then you can make this the default using: + +@example +GRUB_DEFAULT='Example GNU/Linux distribution' +@end example + If you set this to @samp{saved}, then the default menu entry will be that saved by @samp{GRUB_SAVEDEFAULT}, @command{grub-set-default}, or @command{grub-reboot}. From a8afc1d12c9f4a10dc107b8a6ab819f879b10883 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 31 Mar 2011 12:25:10 +0100 Subject: [PATCH 0783/1414] * grub-core/mmap/efi/mmap.c (grub_mmap_unregister): Remove set-but-not-used variable. --- ChangeLog | 5 +++++ grub-core/mmap/efi/mmap.c | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff9582918..25aa0a496 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-31 Colin Watson + + * grub-core/mmap/efi/mmap.c (grub_mmap_unregister): Remove + set-but-not-used variable. + 2011-03-31 Colin Watson * docs/grub.texi (Simple configuration): Be more explicit about diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index 5b82a8717..8e5cce0d0 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -194,7 +194,6 @@ grub_mmap_unregister (int handle) { struct overlay *curover, *prevover; grub_efi_boot_services_t *b; - grub_efi_status_t status; b = grub_efi_system_table->boot_services; @@ -204,7 +203,7 @@ grub_mmap_unregister (int handle) { if (curover->handle == handle) { - status = efi_call_2 (b->free_pages, curover->address, curover->pages); + efi_call_2 (b->free_pages, curover->address, curover->pages); if (prevover != 0) prevover->next = curover->next; else From 91dc6073309e5582d3293c6c0a037d7f3457dc32 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 31 Mar 2011 16:48:36 +0200 Subject: [PATCH 0784/1414] * grub-core/kern/x86_64/efi/callwrap.S (efi_wrap_0): Preserve 16-byte stack alignment. (efi_wrap_1): Likewise. (efi_wrap_2): Likewise. (efi_wrap_3): Likewise. (efi_wrap_4): Likewise. (efi_wrap_5): Likewise. (efi_wrap_6): Likewise. (efi_wrap_10): Likewise. Based on information by: Red Hat/Peter Jones. --- ChangeLog | 13 ++++++++ grub-core/kern/x86_64/efi/callwrap.S | 44 ++++++++++++++-------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 25aa0a496..847d04b03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-03-31 Vladimir Serbinenko + + * grub-core/kern/x86_64/efi/callwrap.S (efi_wrap_0): Preserve 16-byte + stack alignment. + (efi_wrap_1): Likewise. + (efi_wrap_2): Likewise. + (efi_wrap_3): Likewise. + (efi_wrap_4): Likewise. + (efi_wrap_5): Likewise. + (efi_wrap_6): Likewise. + (efi_wrap_10): Likewise. + Based on information by: Red Hat/Peter Jones. + 2011-03-31 Colin Watson * grub-core/mmap/efi/mmap.c (grub_mmap_unregister): Remove diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S index 1946732ae..aae267872 100644 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ b/grub-core/kern/x86_64/efi/callwrap.S @@ -37,80 +37,80 @@ .text FUNCTION(efi_wrap_0) - subq $40, %rsp + subq $48, %rsp call *%rdi - addq $40, %rsp + addq $48, %rsp ret FUNCTION(efi_wrap_1) - subq $40, %rsp + subq $48, %rsp mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $48, %rsp ret FUNCTION(efi_wrap_2) - subq $40, %rsp + subq $48, %rsp mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $48, %rsp ret FUNCTION(efi_wrap_3) - subq $40, %rsp + subq $48, %rsp mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $48, %rsp ret FUNCTION(efi_wrap_4) - subq $40, %rsp + subq $48, %rsp mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $48, %rsp ret FUNCTION(efi_wrap_5) - subq $40, %rsp + subq $48, %rsp mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $40, %rsp + addq $48, %rsp ret FUNCTION(efi_wrap_6) - subq $56, %rsp - mov 56+8(%rsp), %rax + subq $64, %rsp + mov 64+8(%rsp), %rax mov %rax, 40(%rsp) mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $56, %rsp + addq $64, %rsp ret FUNCTION(efi_wrap_10) - subq $88, %rsp - mov 88+40(%rsp), %rax + subq $96, %rsp + mov 96+40(%rsp), %rax mov %rax, 72(%rsp) - mov 88+32(%rsp), %rax + mov 96+32(%rsp), %rax mov %rax, 64(%rsp) - mov 88+24(%rsp), %rax + mov 96+24(%rsp), %rax mov %rax, 56(%rsp) - mov 88+16(%rsp), %rax + mov 96+16(%rsp), %rax mov %rax, 48(%rsp) - mov 88+8(%rsp), %rax + mov 96+8(%rsp), %rax mov %rax, 40(%rsp) mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $88, %rsp + addq $96, %rsp ret From 6dc14451f4769d68d96c40f66644fe52e5a29d39 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:12:44 -0300 Subject: [PATCH 0785/1414] Iterate sockets to see if we expect this packet. Let the App layer to remove its own header. Add packet to socket list if it contains data. Undesired packets are freed. --- grub-core/net/udp.c | 62 ++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index a73431f83..16b2011ff 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -5,63 +5,51 @@ #include grub_err_t -grub_net_send_udp_packet (const grub_net_network_level_address_t *target, - struct grub_net_buff *nb, grub_uint16_t srcport, - grub_uint16_t destport) +grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb) { struct udphdr *udph; - struct grub_net_network_level_interface *inf; - grub_err_t err; - grub_net_network_level_address_t gateway; - - err = grub_net_route_address (*target, &gateway, &inf); - if (err) - return err; grub_netbuff_push (nb,sizeof(*udph)); udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16 (srcport); - udph->dst = grub_cpu_to_be16 (destport); + udph->src = grub_cpu_to_be16 (socket->in_port); + udph->dst = grub_cpu_to_be16 (socket->out_port); /* No chechksum. */ udph->chksum = 0; udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - return grub_net_send_ip_packet (inf, target, nb); + return grub_net_send_ip_packet (socket->inf, &(socket->out_nla), nb); } grub_err_t -grub_net_recv_udp_packet (const grub_net_network_level_address_t *target, - struct grub_net_buff *buf, - grub_uint16_t srcport, grub_uint16_t destport) +grub_net_recv_udp_packet (struct grub_net_buff *nb) { - grub_err_t err; - struct grub_net_packet *pkt; - struct grub_net_network_level_interface *inf; - grub_net_network_level_address_t gateway; + //grub_err_t err; + struct udphdr *udph; + grub_net_socket_t sock; + udph = (struct udphdr *) nb->data; + grub_netbuff_pull (nb, sizeof (*udph)); - err = grub_net_route_address (*target, &gateway, &inf); - if (err) - return err; - - (void) srcport; - - err = grub_net_recv_ip_packets (inf); - - FOR_NET_NL_PACKETS(inf, pkt) + FOR_NET_SOCKETS(sock) { - struct udphdr *udph; - struct grub_net_buff *nb = pkt->nb; - udph = (struct udphdr *) nb->data; - if (grub_be_to_cpu16 (udph->dst) == destport) + if (grub_be_to_cpu16 (udph->dst) == sock->in_port) { - grub_net_remove_packet (pkt); - grub_netbuff_pull (nb, sizeof(*udph)); - grub_memcpy (buf, nb, sizeof (buf)); - + if (sock->status == 0) + sock->out_port = udph->src; + + + /* App protocol remove its own reader. */ + sock->app->read (sock,nb); + + /* If there is data, puts packet in socket list */ + if ((nb->tail - nb->data) > 0) + grub_net_put_packet (sock->packs, nb); + else + grub_netbuff_free (nb); return GRUB_ERR_NONE; } } + grub_netbuff_free (nb); return GRUB_ERR_NONE; } From d5e0a358f1252bb4af4002a9589e89ec70f0944c Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:14:16 -0300 Subject: [PATCH 0786/1414] Correctly match network. --- grub-core/net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 54663f4b0..ab6b39261 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -105,7 +105,7 @@ match_net (const grub_net_network_level_netaddress_t *net, { case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { - grub_int32_t mask = (1 << net->ipv4.masksize) - 1; + grub_int32_t mask = ((1 << net->ipv4.masksize) - 1) << (32 - net->ipv4.masksize); return ((grub_be_to_cpu32 (net->ipv4.base) & mask) == (grub_be_to_cpu32 (addr->ipv4) & mask)); } From fbdee79b1729f432e4673a5088b20509be5e032b Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:22:41 -0300 Subject: [PATCH 0787/1414] Add generic functions to read and seek in network file. Allocate socket with network and adress information. --- grub-core/net/net.c | 164 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index ab6b39261..8c9229915 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -17,8 +17,12 @@ */ #include +#include +#include +#include #include #include +#include #include #include #include @@ -40,6 +44,7 @@ struct grub_net_route struct grub_net_route *grub_net_routes = NULL; struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; struct grub_net_card *grub_net_cards = NULL; +struct grub_net_card_driver *grub_net_card_drivers = NULL; struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; static inline void @@ -538,6 +543,7 @@ grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)), } grub_net_app_level_t grub_net_app_level_list; +struct grub_net_socket *grub_net_sockets; static grub_net_t grub_net_open_real (const char *name) @@ -570,6 +576,159 @@ grub_net_open_real (const char *name) return NULL; } +static grub_err_t +grub_net_file_open_real (struct grub_file *file, const char *name) +{ + grub_err_t err; + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inf; + grub_net_network_level_address_t gateway; + grub_net_socket_t socket; + static int port = 25300; + + err = grub_net_resolve_address (file->device->net->name + + sizeof (file->device->net->protocol->name) + 1, &addr); + if (err) + return err; + + err = grub_net_route_address (addr, &gateway, &inf); + if (err) + return err; + + if ((socket = (grub_net_socket_t) grub_malloc (sizeof (*socket))) == NULL) + return GRUB_ERR_OUT_OF_MEMORY; + + socket->inf = inf; + socket->out_nla = addr; + socket->in_port = port++; + socket->status = 0; + socket->app = file->device->net->protocol; + socket->packs = NULL; + file->device->net->socket = socket; + grub_net_socket_register (socket); + + if ((err = file->device->net->protocol->open (file,name))) + goto fail; + + return GRUB_ERR_NONE; +fail: + grub_net_socket_unregister (socket); + grub_free (socket); + return err; + +} + +static grub_err_t +receive_packets (struct grub_net_card *card) +{ + /* Maybe should be better have a fixed number of packets for each card + and just mark them as used and not used. */ + struct grub_net_buff *nb; + nb = grub_netbuff_alloc (1500); + if (!nb) + return grub_errno; + + card->driver->recv (card, nb); + return GRUB_ERR_NONE; +} + +void +grub_net_pool_cards (unsigned time) +{ + struct grub_net_card *card; + grub_uint64_t start_time; + FOR_NET_CARDS (card) + { + start_time = grub_get_time_ms (); + while( (grub_get_time_ms () - start_time) < time) + receive_packets (card); + } +} + +static grub_ssize_t +process_packets (grub_file_t file, void *buf, grub_size_t len, + void *NESTED_FUNC_ATTR (hook) (void *dest, const void *src, grub_size_t n)) +{ + grub_net_socket_t sock = file->device->net->socket; + struct grub_net_buff *nb; + char *ptr = (char *) buf; + grub_size_t amount, total = 0; + int try = 0; + while (try <= 3) + { + while (sock->packs->first) + { + try = 0; + nb = sock->packs->first->nb; + amount = (grub_size_t)(len <= (grub_size_t) (nb->tail - nb->data))? len :(grub_size_t)(nb->tail - nb->data); + len -= amount; + total += amount; + hook (ptr, nb->data, amount); + ptr += amount; + if (amount == (grub_size_t) (nb->tail - nb->data)) + { + grub_netbuff_free (nb); + grub_net_remove_packet (sock->packs->first); + } + else + nb->data += amount; + + if (!len) + return total; + } + if (sock->status == 1) + { + try++; + grub_net_pool_cards (200); + } + else + return total; + } + return total; +} + + +/* Read from the packets list*/ +static grub_ssize_t +grub_net_read_real (grub_file_t file, void *buf, grub_size_t len ) +{ + auto void *NESTED_FUNC_ATTR memcpy_hook (void *dest, const void *src, grub_size_t n); + void *NESTED_FUNC_ATTR memcpy_hook (void *dest __attribute__ ((unused)), const void *src __attribute__ ((unused)), + grub_size_t n __attribute__ ((unused))) + { + return grub_memcpy (dest, src, n); + } + return process_packets (file, buf, len, memcpy_hook); +} + +/* Read from the packets list*/ +static grub_err_t +grub_net_seek_real (struct grub_file *file, grub_off_t offset) +{ + grub_net_socket_t sock = file->device->net->socket; + struct grub_net_buff *nb; + grub_size_t len = offset - file->offset; + + if (!len) + return GRUB_ERR_NONE; + + /* We cant seek backwards past the current packet. */ + if (file->offset > offset) + { + nb = sock->packs->first->nb; + return grub_netbuff_push (nb, file->offset - offset); + } + + auto void *NESTED_FUNC_ATTR dummy (void *dest, const void *src, grub_size_t n); + void *NESTED_FUNC_ATTR dummy (void *dest __attribute__ ((unused)), const void *src __attribute__ ((unused)), + grub_size_t n __attribute__ ((unused))) + { + return NULL; + } + process_packets (file, NULL, len, dummy); + return GRUB_ERR_NONE; +} + static char * grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), const char *val __attribute__ ((unused))) @@ -857,6 +1016,9 @@ GRUB_MOD_INIT(net) N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); grub_net_open = grub_net_open_real; + grub_file_net_open = grub_net_file_open_real; + grub_file_net_read = grub_net_read_real; + grub_file_net_seek = grub_net_seek_real; } GRUB_MOD_FINI(net) @@ -869,4 +1031,6 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_lscards); grub_unregister_command (cmd_getdhcp); grub_net_open = NULL; + grub_file_net_read = NULL; + grub_file_net_open = NULL; } From 6ccb7a35e61a2853549dc90fe00981aebc09571b Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:26:27 -0300 Subject: [PATCH 0788/1414] Remove unused file. --- grub-core/net/device.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 grub-core/net/device.c diff --git a/grub-core/net/device.c b/grub-core/net/device.c deleted file mode 100644 index e69de29bb..000000000 From 6d5c2ed68a8b5f126c2eec349e39496af86d63ab Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:27:06 -0300 Subject: [PATCH 0789/1414] Use nb in all function declarations for consistency. --- grub-core/net/netbuff.c | 45 +++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index cc366ae09..be9fc9de2 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -22,43 +22,43 @@ #include -grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len) +grub_err_t grub_netbuff_put (struct grub_net_buff *nb ,grub_size_t len) { - net_buff->tail += len; - if (net_buff->tail > net_buff->end) + nb->tail += len; + if (nb->tail > nb->end) return grub_error (GRUB_ERR_OUT_OF_RANGE, "put out of the packet range."); return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len) +grub_err_t grub_netbuff_unput (struct grub_net_buff *nb ,grub_size_t len) { - net_buff->tail -= len; - if (net_buff->tail < net_buff->head) + nb->tail -= len; + if (nb->tail < nb->head) return grub_error (GRUB_ERR_OUT_OF_RANGE, "unput out of the packet range."); return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len) +grub_err_t grub_netbuff_push (struct grub_net_buff *nb ,grub_size_t len) { - net_buff->data -= len; - if (net_buff->data < net_buff->head) + nb->data -= len; + if (nb->data < nb->head) return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range."); return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len) +grub_err_t grub_netbuff_pull (struct grub_net_buff *nb ,grub_size_t len) { - net_buff->data += len; - if (net_buff->data > net_buff->end) + nb->data += len; + if (nb->data > nb->end) return grub_error (GRUB_ERR_OUT_OF_RANGE, "pull out of the packet range."); return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len) +grub_err_t grub_netbuff_reserve (struct grub_net_buff *nb ,grub_size_t len) { - net_buff->data += len; - net_buff->tail += len; - if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end)) + nb->data += len; + nb->tail += len; + if ((nb->tail > nb->end) || (nb->data > nb->end)) return grub_error (GRUB_ERR_OUT_OF_RANGE, "reserve out of the packet range."); return GRUB_ERR_NONE; } @@ -73,22 +73,23 @@ struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) len = ALIGN_UP (len,NETBUFF_ALIGN); data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); + if (!data) + return NULL; nb = (struct grub_net_buff *) ((grub_uint8_t *) data + len); nb->head = nb->data = nb->tail = data; - nb->end = (char *) nb; - + nb->end = (char *) nb; return nb; } -grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff) +grub_err_t grub_netbuff_free (struct grub_net_buff *nb) { - grub_free (net_buff->head); + grub_free (nb->head); return 0; } -grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff) +grub_err_t grub_netbuff_clear (struct grub_net_buff *nb) { - net_buff->data = net_buff->tail = net_buff->head; + nb->data = nb->tail = nb->head; return 0; } From 59b361a2df22426b6d34870bdbcc312641414369 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:39:06 -0300 Subject: [PATCH 0790/1414] Use bootp packet to set prefix and card address. --- grub-core/kern/ieee1275/init.c | 19 +++++- grub-core/kern/ieee1275/openfw.c | 1 + grub-core/net/drivers/ieee1275/ofnet.c | 89 +++++++++++++++++--------- include/grub/ieee1275/ofnet.h | 6 +- 4 files changed, 77 insertions(+), 38 deletions(-) diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 682a8b5a4..ad34ea188 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include @@ -74,7 +76,22 @@ grub_machine_set_prefix (void) char bootpath[64]; /* XXX check length */ char *filename; char *prefix; - + grub_bootp_t bootp_pckt; + char addr[GRUB_NET_MAX_STR_ADDR_LEN]; + + /* Set the net prefix when possible. */ + if (grub_getbootp && (bootp_pckt = grub_getbootp())) + { + grub_uint32_t n = bootp_pckt->siaddr; + grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d", + ((n >> 24) & 0xff), ((n >> 16) & 0xff), + ((n >> 8) & 0xff), ((n >> 0) & 0xff)); + prefix = grub_xasprintf ("(tftp,%s)%s", addr,grub_prefix); + grub_env_set ("prefix", prefix); + grub_free (prefix); + return; + } + if (grub_prefix[0]) { grub_env_set ("prefix", grub_prefix); diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 3c228f574..fed4f7e76 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -28,6 +28,7 @@ #include #include +grub_bootp_t (*grub_getbootp) (void); enum grub_ieee1275_parse_type { GRUB_PARSE_FILENAME, diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index ce5276efe..10de81bc7 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -78,12 +78,11 @@ bootp_response_properties[] = { .name = "bootpreply-packet", .offset = 0x2a }, }; - -grub_bootp_t -grub_getbootp( void ) +static grub_bootp_t +grub_getbootp_real ( void ) { - grub_bootp_t packet = grub_malloc(sizeof *packet); - void *bootp_response = NULL; + grub_bootp_t packet = grub_malloc (sizeof *packet); + char *bootp_response; grub_ssize_t size; unsigned int i; @@ -94,30 +93,27 @@ grub_getbootp( void ) break; if (size < 0) - { - grub_printf("Error to get bootp\n"); return NULL; - } + bootp_response = grub_malloc (size); if (grub_ieee1275_get_property (grub_ieee1275_chosen, bootp_response_properties[i].name, bootp_response , size, 0) < 0) - { - grub_printf("Error to get bootp\n"); return NULL; - } - packet = (void *) ((int)bootp_response - + bootp_response_properties[i].offset); + grub_memcpy (packet, bootp_response + bootp_response_properties[i].offset, sizeof (*packet)); + grub_free (bootp_response); return packet; } +static void grub_ofnet_findcards (void) { struct grub_net_card *card; + grub_ieee1275_phandle_t devhandle; + grub_net_link_level_address_t lla; int i = 0; - auto int search_net_devices (struct grub_ieee1275_devalias *alias); int search_net_devices (struct grub_ieee1275_devalias *alias) @@ -128,53 +124,82 @@ void grub_ofnet_findcards (void) card = grub_malloc (sizeof (struct grub_net_card)); struct grub_ofnetcard_data *ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); ofdata->path = grub_strdup (alias->path); - card->data = ofdata; + + grub_ieee1275_finddevice (ofdata->path, &devhandle); + + if (grub_ieee1275_get_integer_property + (devhandle, "max-frame-size", &(ofdata->mtu), sizeof (ofdata->mtu), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve mtu size."); + + if (grub_ieee1275_get_property (devhandle, "mac-address", &(lla.mac), 6, 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); + + lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + card->default_address = lla; + + card->data = ofdata; + card->flags = 0; card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name); grub_net_card_register (card); } return 0; } - /*Look at all nodes for devices of the type network*/ + /* Look at all nodes for devices of the type network. */ grub_ieee1275_devices_iterate (search_net_devices); - } +static void grub_ofnet_probecards (void) { struct grub_net_card *card; struct grub_net_card_driver *driver; + struct grub_net_network_level_interface *inter; + grub_bootp_t bootp_pckt; + grub_net_network_level_address_t addr; + grub_net_network_level_netaddress_t net; - /*Assign correspondent driver for each device. */ + /* Assign correspondent driver for each device. */ FOR_NET_CARDS (card) { FOR_NET_CARD_DRIVERS (driver) { if (driver->init(card) == GRUB_ERR_NONE) - { - card->driver = driver; - continue; - } + { + card->driver = driver; + bootp_pckt = grub_getbootp (); + if (bootp_pckt) + { + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + addr.ipv4 = bootp_pckt->yiaddr; + grub_net_add_addr ("bootp_cli_addr", card, addr, card->default_address, 0); + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, "bootp_cli_addr") == 0) + break; + net.type = addr.type; + net.ipv4.base = addr.ipv4; + net.ipv4.masksize = 24; + grub_net_add_route ("bootp-router", net, inter); + } + grub_free (bootp_pckt); + break; + } } } } -GRUB_MOD_INIT(ofnet) +GRUB_MOD_INIT (ofnet) { + grub_getbootp = grub_getbootp_real; grub_net_card_driver_register (&ofdriver); - grub_ofnet_findcards(); - grub_ofnet_probecards(); - - /*init tftp stack - will be handled by module subsystem in the future*/ - tftp_ini (); - /*get bootp packet - won't be needed in the future*/ - bootp_pckt = grub_getbootp (); - grub_disknet_init(); + grub_ofnet_findcards (); + grub_ofnet_probecards (); } -GRUB_MODE_FINI(ofnet) +GRUB_MOD_FINI (ofnet) { grub_net_card_driver_unregister (&ofdriver); + grub_getbootp = NULL; } diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h index ba4c62630..9a0ae29e3 100644 --- a/include/grub/ieee1275/ofnet.h +++ b/include/grub/ieee1275/ofnet.h @@ -60,14 +60,10 @@ struct grub_bootp { unsigned char chaddr [16]; /* Client hardware address */ char sname [64]; /* Server name */ char file [128]; /* Boot filename */ -// grub_uint32_t filesize ; /*File size (testing)*/ unsigned char vend [64]; }; typedef struct grub_bootp* grub_bootp_t; -char * grub_get_filestr(const char * ); -char * grub_ip2str (grub_uint32_t ip); -void grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet); -grub_bootp_t grub_getbootp (void); +extern grub_bootp_t (*EXPORT_VAR (grub_getbootp)) (void); #endif /* ! GRUB_NET_HEADER */ From 457d1104f6137887a04c479ee43b5168b7733987 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:40:44 -0300 Subject: [PATCH 0791/1414] Add ofnet.h to Makefile.am --- grub-core/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 050075ef8..0fdb4b1db 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -113,6 +113,7 @@ endif if COND_i386_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h @@ -148,6 +149,7 @@ endif if COND_powerpc_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h @@ -155,6 +157,7 @@ endif if COND_sparc64_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h From 09375846b9ea73269302e97affc85dbb3a43f1b8 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:41:37 -0300 Subject: [PATCH 0792/1414] Add mtu to ieee1275 driver data. --- include/grub/ieee1275/ieee1275.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 94a69d73d..87294610d 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -68,6 +68,7 @@ struct grub_ofnetcard_data { char *path; grub_ieee1275_ihandle_t handle; + grub_uint32_t mtu; }; /* Maps a device alias to a pathname. */ @@ -201,8 +202,6 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) (struct grub_ieee1275_devalias * alias)); char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); -void EXPORT_FUNC(grub_ofnet_findcards) (void); -void EXPORT_FUNC(grub_ofnet_probecards) (void); char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); #endif /* ! GRUB_IEEE1275_HEADER */ From 25f1579b4348935084a7f349b1ee6c345fe83d39 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 1 Apr 2011 05:42:34 -0300 Subject: [PATCH 0793/1414] Adapt protocols to new network struct. --- Makefile.util.def | 1 + grub-core/kern/file.c | 29 ++++++- grub-core/kern/fs.c | 2 +- grub-core/net/arp.c | 100 ++++++++++++------------ grub-core/net/ethernet.c | 18 ++--- grub-core/net/i386/pc/pxe.c | 2 +- grub-core/net/ip.c | 36 +++++---- grub-core/net/tftp.c | 151 ++++++++++++++++++------------------ include/grub/net.h | 125 ++++++++++++++++++++++------- include/grub/net/arp.h | 3 +- include/grub/net/device.h | 7 -- include/grub/net/ethernet.h | 4 +- include/grub/net/ip.h | 2 +- include/grub/net/tftp.h | 12 ++- include/grub/net/udp.h | 12 +-- 15 files changed, 296 insertions(+), 208 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 579fd0714..0f7643b58 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -37,6 +37,7 @@ library = { common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; common = grub-core/net/net.c; + common = grub-core/net/netbuff.c; common = grub-core/disk/dmraid_nvidia.c; common = grub-core/disk/loopback.c; common = grub-core/disk/lvm.c; diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index c93fbf737..85ba8536c 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -20,10 +20,15 @@ #include #include #include +#include #include #include #include +grub_ssize_t (*grub_file_net_read) (grub_file_t file, void *buf, grub_size_t len) = NULL; +grub_err_t (*grub_file_net_open) (struct grub_file *file, const char *name) = NULL; +grub_err_t (*grub_file_net_seek) (struct grub_file *file, grub_off_t offset) = NULL; + grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX]; grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX]; @@ -85,6 +90,13 @@ grub_file_open (const char *name) file->device = device; + if (device->net && grub_file_net_open) + { + if (grub_file_net_open (file, file_name)) + goto fail; + return file; + } + if (device->disk && file_name[0] != '/') /* This is a block list. */ file->fs = &grub_fs_blocklist; @@ -130,7 +142,7 @@ grub_file_open (const char *name) grub_ssize_t grub_file_read (grub_file_t file, void *buf, grub_size_t len) { - grub_ssize_t res; + grub_ssize_t res = 0; if (file->offset > file->size) { @@ -148,8 +160,12 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) if (len == 0) return 0; - - res = (file->fs->read) (file, buf, len); + if (file->device->disk) + res = (file->fs->read) (file, buf, len); + else + if (grub_file_net_read && file->device->net) + res = grub_file_net_read (file, buf, len); + if (res > 0) file->offset += res; @@ -159,6 +175,9 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) grub_err_t grub_file_close (grub_file_t file) { + if (file->device->net) + return grub_errno; + if (file->fs->close) (file->fs->close) (file); @@ -179,8 +198,12 @@ grub_file_seek (grub_file_t file, grub_off_t offset) "attempt to seek outside of the file"); return -1; } + + if (file->device->net && grub_file_net_seek) + grub_file_net_seek (file, offset); old = file->offset; file->offset = offset; + return old; } diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c index c4d6efa96..7166648be 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -95,7 +95,7 @@ grub_fs_probe (grub_device_t device) } } else if (device->net) - return device->net->protocol; + return NULL; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); return 0; diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index c7b5d0573..8778a6e51 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -35,36 +35,40 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, grub_net_link_level_address_t *hw_addr) { struct arp_entry *entry; - struct grub_net_buff *nb; + struct grub_net_buff nb; struct arphdr *arp_header; grub_net_link_level_address_t target_hw_addr; - grub_uint8_t *aux, i; + char *aux, arp_data[128]; + int i; - /* Check cache table */ + /* Check cache table. */ entry = arp_find_entry (proto_addr); if (entry) { *hw_addr = entry->ll_address; return GRUB_ERR_NONE; } - /* Build a request packet */ - nb = grub_netbuff_alloc (2048); - if (!nb) - return grub_errno; - grub_netbuff_reserve(nb, 2048); - grub_netbuff_push(nb, sizeof(*arp_header) + 2 * (6 + 6)); - arp_header = (struct arphdr *)nb->data; + /* Build a request packet. */ + nb.head = arp_data; + nb.end = arp_data + sizeof (arp_data); + grub_netbuff_clear (&nb); + + grub_netbuff_reserve (&nb,128); + grub_netbuff_push (&nb, sizeof(*arp_header) + 2 * (6 + 4)); + arp_header = (struct arphdr *) nb.data; arp_header->hrd = grub_cpu_to_be16 (GRUB_NET_ARPHRD_ETHERNET); arp_header->pro = grub_cpu_to_be16 (GRUB_NET_ETHERTYPE_IP); + /* FIXME Add support to ipv6 address. */ arp_header->hln = 6; arp_header->pln = 4; arp_header->op = grub_cpu_to_be16 (ARP_REQUEST); - aux = (grub_uint8_t *)arp_header + sizeof(*arp_header); - /* Sender hardware address */ - grub_memcpy(aux, &inf->hwaddress.mac, 6); + aux = (char *) arp_header + sizeof (*arp_header); + /* Sender hardware address. */ + grub_memcpy (aux, &inf->hwaddress.mac, 6); + aux += 6; /* Sender protocol address */ - grub_memcpy(aux, &inf->address.ipv4, 4); + grub_memcpy (aux, &inf->address.ipv4, 4); aux += 4; /* Target hardware address */ for(i = 0; i < 6; i++) @@ -72,49 +76,40 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, aux += 6; /* Target protocol address */ grub_memcpy(aux, &proto_addr->ipv4, 4); - grub_memset (&target_hw_addr.mac, 0xff, 6); - send_ethernet_packet (inf, nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP); - grub_netbuff_clear(nb); - grub_netbuff_reserve(nb, 2048); - - grub_uint64_t start_time, current_time; - start_time = grub_get_time_ms(); - do + send_ethernet_packet (inf, &nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP); + for (i = 0; i < 3; i++) { - grub_net_recv_ethernet_packet (inf, nb, GRUB_NET_ETHERTYPE_ARP); - /* Now check cache table again */ - entry = arp_find_entry(proto_addr); + entry = arp_find_entry (proto_addr); if (entry) - { - grub_memcpy(hw_addr, &entry->ll_address, sizeof (*hw_addr)); - grub_netbuff_clear(nb); - return GRUB_ERR_NONE; - } - current_time = grub_get_time_ms(); - if (current_time - start_time > 3000) - break; - } while (! entry); - grub_netbuff_clear(nb); + { + grub_memcpy (hw_addr, &entry->ll_address, sizeof (*hw_addr)); + return GRUB_ERR_NONE; + } + grub_net_pool_cards (200); + + } + return grub_error (GRUB_ERR_TIMEOUT, "Timeout: could not resolve hardware address."); } grub_err_t -grub_net_arp_receive (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb) +grub_net_arp_receive (struct grub_net_buff *nb) { struct arphdr *arp_header = (struct arphdr *)nb->data; struct arp_entry *entry; grub_uint8_t *sender_hardware_address, *sender_protocol_address; grub_uint8_t *target_hardware_address, *target_protocol_address; grub_net_network_level_address_t hwaddress; + struct grub_net_network_level_interface *inf; sender_hardware_address = (grub_uint8_t *) arp_header + sizeof(*arp_header); sender_protocol_address = sender_hardware_address + arp_header->hln; target_hardware_address = sender_protocol_address + arp_header->pln; target_protocol_address = target_hardware_address + arp_header->hln; grub_memcpy (&hwaddress.ipv4, sender_protocol_address, 4); + /* Check if the sender is in the cache table */ entry = arp_find_entry(&hwaddress); /* Update sender hardware address */ @@ -134,21 +129,24 @@ grub_net_arp_receive (struct grub_net_network_level_interface *inf, new_table_entry = 0; } - /* Am I the protocol address target? */ - if (grub_memcmp(target_protocol_address, inf->hwaddress.mac, 6) == 0 - && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST) + FOR_NET_NETWORK_LEVEL_INTERFACES(inf) { - grub_net_link_level_address_t aux; - /* Swap hardware fields */ - grub_memcpy(target_hardware_address, sender_hardware_address, arp_header->hln); - grub_memcpy(sender_hardware_address, inf->hwaddress.mac, 6); - grub_memcpy(aux.mac, sender_protocol_address, 6); - grub_memcpy(sender_protocol_address, target_protocol_address, arp_header->pln); - grub_memcpy(target_protocol_address, aux.mac, arp_header->pln); - /* Change operation to REPLY and send packet */ - arp_header->op = grub_be_to_cpu16 (ARP_REPLY); - grub_memcpy (aux.mac, target_hardware_address, 6); - send_ethernet_packet (inf, nb, aux, GRUB_NET_ETHERTYPE_ARP); + /* Am I the protocol address target? */ + if (grub_memcmp (target_protocol_address, &inf->address.ipv4, 6) == 0 + && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST) + { + grub_net_link_level_address_t aux; + /* Swap hardware fields */ + grub_memcpy (target_hardware_address, sender_hardware_address, arp_header->hln); + grub_memcpy (sender_hardware_address, inf->hwaddress.mac, 6); + grub_memcpy (aux.mac, sender_protocol_address, 6); + grub_memcpy (sender_protocol_address, target_protocol_address, arp_header->pln); + grub_memcpy (target_protocol_address, aux.mac, arp_header->pln); + /* Change operation to REPLY and send packet */ + arp_header->op = grub_be_to_cpu16 (ARP_REPLY); + grub_memcpy (aux.mac, target_hardware_address, 6); + send_ethernet_packet (inf, nb, aux, GRUB_NET_ETHERTYPE_ARP); + } } return GRUB_ERR_NONE; } diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index cbda4c875..c96a65602 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -23,23 +23,20 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, eth->type = grub_cpu_to_be16 (ethertype); - return inf->card->driver->send (inf->card,nb); + return inf->card->driver->send (inf->card, nb); } grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb, - grub_uint16_t ethertype) +grub_net_recv_ethernet_packet (struct grub_net_buff *nb) { struct etherhdr *eth; struct llchdr *llch; struct snaphdr *snaph; grub_uint16_t type; - inf->card->driver->recv (inf->card, nb); eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); - grub_netbuff_pull(nb,sizeof (*eth)); + grub_netbuff_pull (nb, sizeof (*eth)); if (type <= 1500) { @@ -56,10 +53,13 @@ grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, /* ARP packet */ if (type == GRUB_NET_ETHERTYPE_ARP) - grub_net_arp_receive(inf, nb); + { + grub_net_arp_receive (nb); + grub_netbuff_free (nb); + } /* IP packet */ - if(type == GRUB_NET_ETHERTYPE_IP && ethertype == GRUB_NET_ETHERTYPE_IP) - return GRUB_ERR_NONE; + if (type == GRUB_NET_ETHERTYPE_IP) + grub_net_recv_ip_packets (nb); return GRUB_ERR_NONE; } diff --git a/grub-core/net/i386/pc/pxe.c b/grub-core/net/i386/pc/pxe.c index c07aa78f9..8e7f75ed8 100644 --- a/grub-core/net/i386/pc/pxe.c +++ b/grub-core/net/i386/pc/pxe.c @@ -292,7 +292,7 @@ grub_pxefs_label (grub_device_t device __attribute ((unused)), return GRUB_ERR_NONE; } -static struct grub_fs grub_pxefs_fs = +static struct grub_net_app_protocol grub_pxefs_fs = { .name = "pxe", .dir = grub_pxefs_dir, diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 9a96ef532..d6684c29e 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, grub_net_link_level_address_t ll_target_addr; grub_err_t err; - grub_netbuff_push(nb,sizeof(*iph)); + grub_netbuff_push (nb, sizeof(*iph)); iph = (struct iphdr *) nb->data; iph->verhdrlen = ((4 << 4) | 5); @@ -49,17 +50,15 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, iph->chksum = 0 ; iph->chksum = ipchksum((void *)nb->data, sizeof(*iph)); - /* Determine link layer target address via ARP */ - err = grub_net_arp_resolve(inf, target, &ll_target_addr); + /* Determine link layer target address via ARP. */ + err = grub_net_arp_resolve (inf, target, &ll_target_addr); if (err) return err; - return send_ethernet_packet (inf, nb, ll_target_addr, GRUB_NET_ETHERTYPE_IP); } - +/* static int -ip_filter (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf) +ip_filter (struct grub_net_buff *nb) { struct iphdr *iph = (struct iphdr *) nb->data; grub_err_t err; @@ -80,15 +79,22 @@ ip_filter (struct grub_net_buff *nb, } return 1; } - +*/ grub_err_t -grub_net_recv_ip_packets (struct grub_net_network_level_interface *inf) +grub_net_recv_ip_packets (struct grub_net_buff *nb) { - struct grub_net_buff *nb; - nb = grub_netbuff_alloc (2048); - if (!nb) - return grub_errno; - grub_net_recv_ethernet_packet (inf, nb, GRUB_NET_ETHERTYPE_IP); - ip_filter (nb, inf); + struct iphdr *iph = (struct iphdr *) nb->data; + grub_netbuff_pull (nb, sizeof (*iph)); + + switch (iph->protocol) + { + case IP_UDP: + return grub_net_recv_udp_packet (nb); + break; + default: + grub_netbuff_free (nb); + break; + } + return GRUB_ERR_NONE; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 16b60eeb6..cafb30585 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -14,26 +14,23 @@ tftp_open (struct grub_file *file, const char *filename) { struct tftphdr *tftph; char *rrq; - char *ptr; + int i; int rrqlen; - int hdrlen; - struct grub_net_buff *nb; - grub_net_network_level_address_t addr; + int hdrlen; + char open_data[1500]; + struct grub_net_buff nb; + tftp_data_t data = grub_malloc (sizeof *data); grub_err_t err; + + file->device->net->socket->data = (void *) data; + nb.head = open_data; + nb.end = open_data + sizeof (open_data); + grub_netbuff_clear (&nb); - err = grub_net_resolve_address (file->device->net->name - + sizeof ("tftp,") - 1, &addr); - if (err) - return err; + grub_netbuff_reserve (&nb,1500); + grub_netbuff_push (&nb,sizeof (*tftph)); - nb = grub_netbuff_alloc (2048); - if (!nb) - return grub_errno; - - grub_netbuff_reserve (nb,2048); - grub_netbuff_push (nb,sizeof (*tftph)); - - tftph = (struct tftphdr *) nb->data; + tftph = (struct tftphdr *) nb.data; rrq = (char *) tftph->u.rrq; rrqlen = 0; @@ -64,89 +61,93 @@ tftp_open (struct grub_file *file, const char *filename) rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; - grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); + grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); - err = grub_net_send_udp_packet (&addr, - nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + file->device->net->socket->out_port = TFTP_SERVER_PORT; + + err = grub_net_send_udp_packet (file->device->net->socket, &nb); if (err) return err; - /* Receive OACK. */ - grub_netbuff_clear (nb); - grub_netbuff_reserve (nb,2048); - - do + /* Receive OACK packet. */ + for ( i = 0; i < 3; i++) { - err = grub_net_recv_udp_packet (&addr, nb, - TFTP_CLIENT_PORT, TFTP_SERVER_PORT); - if (err) - return err; + grub_net_pool_cards (100); + if (grub_errno) + return grub_errno; + if (file->device->net->socket->status != 0) + break; + /* Retry. */ + //err = grub_net_send_udp_packet (file->device->net->socket, &nb); + // if (err) + // return err; } - while (nb->tail == nb->data); - file->size = 0; + if (file->device->net->socket->status == 0) + return grub_error (GRUB_ERR_TIMEOUT,"Time out opening tftp."); + file->size = data->file_size; - for (ptr = nb->data; ptr < nb->tail; ) - grub_printf ("%02x ", *ptr); - - for (ptr = nb->data; ptr < nb->tail; ) - { - if (grub_memcmp (ptr, "tsize\0=", sizeof ("tsize\0=") - 1) == 0) - { - file->size = grub_strtoul (ptr + sizeof ("tsize\0=") - 1, 0, 0); - grub_errno = GRUB_ERR_NONE; - } - while (ptr < nb->tail && *ptr) - ptr++; - ptr++; - } return GRUB_ERR_NONE; } -static grub_ssize_t -tftp_receive (struct grub_file *file, char *buf, grub_size_t len) +static grub_err_t +tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) { struct tftphdr *tftph; - // char *token,*value,*temp; + char nbdata[128]; + tftp_data_t data = sock->data; grub_err_t err; - grub_net_network_level_address_t addr; - struct grub_net_buff nb; + char *ptr; + struct grub_net_buff nb_ack; - err = grub_net_resolve_address (file->device->net->name - + sizeof ("tftp,") - 1, &addr); - if (err) - return err; + nb_ack.head = nbdata; + nb_ack.end = nbdata + sizeof (nbdata); - grub_net_recv_udp_packet (&addr, &nb, - TFTP_CLIENT_PORT, TFTP_SERVER_PORT); - - tftph = (struct tftphdr *) nb.data; + + tftph = (struct tftphdr *) nb->data; switch (grub_be_to_cpu16 (tftph->opcode)) { + case TFTP_OACK: + for (ptr = nb->data; ptr < nb->tail; ) + { + if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) + data->file_size = grub_strtoul (ptr + sizeof ("tsize\0") - 1, 0, 0); + while (ptr < nb->tail && *ptr) + ptr++; + ptr++; + } + sock->status = 1; + data->block = 0; + grub_netbuff_clear(nb); + break; case TFTP_DATA: - grub_netbuff_pull (&nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block)); - // if (tftph->u.data.block == block + 1) - //{ - // block = tftph->u.data.block; - grub_memcpy (buf, nb.data, len); - //} - //else - //grub_netbuff_clear(&nb); - break; + grub_netbuff_pull (nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block)); + + if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) + { + data->block++; + if (nb->tail - nb->data < 1024) + sock->status = 2; + } + else + grub_netbuff_clear(nb); + + break; case TFTP_ERROR: - grub_netbuff_clear (&nb); + grub_netbuff_clear (nb); return grub_error (GRUB_ERR_IO, (char *)tftph->u.err.errmsg); + break; } + grub_netbuff_clear (&nb_ack); + grub_netbuff_reserve (&nb_ack,128); + grub_netbuff_push (&nb_ack,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block)); - nb.data = nb.tail = nb.end; - - grub_netbuff_push (&nb,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block)); - - tftph = (struct tftphdr *) nb.data; + tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); - // tftph->u.ack.block = block; + tftph->u.ack.block = data->block; - return grub_net_send_udp_packet (&addr, &nb, TFTP_CLIENT_PORT, TFTP_SERVER_PORT); + err = grub_net_send_udp_packet (sock, &nb_ack); + return err; } static grub_err_t @@ -155,7 +156,7 @@ tftp_close (struct grub_file *file __attribute__ ((unused))) return 0; } -static struct grub_fs grub_tftp_protocol = +static struct grub_net_app_protocol grub_tftp_protocol = { .name = "tftp", .open = tftp_open, diff --git a/include/grub/net.h b/include/grub/net.h index 20bf3c0e6..37b258f36 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -23,19 +23,10 @@ #include #include #include +#include #include #include -typedef struct grub_fs *grub_net_app_level_t; - -typedef struct grub_net -{ - char *name; - grub_net_app_level_t protocol; -} *grub_net_t; - -extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); - typedef enum grub_link_level_protocol_id { GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET @@ -75,6 +66,37 @@ struct grub_net_card_driver grub_size_t (*recv) (struct grub_net_card *dev, struct grub_net_buff *buf); }; +extern struct grub_net_card_driver *grub_net_card_drivers; + +static inline void +grub_net_card_driver_register (struct grub_net_card_driver *driver) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_card_drivers), + GRUB_AS_LIST (driver)); +} + +static inline void +grub_net_card_driver_unregister (struct grub_net_card_driver *driver) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_card_drivers), + GRUB_AS_LIST (driver)); +} + +#define FOR_NET_CARD_DRIVERS(var) for (var = grub_net_card_drivers; var; var = var->next) + +typedef struct grub_net_packet +{ + struct grub_net_packet *next; + struct grub_net_packet *prev; + struct grub_net_packets *up; + struct grub_net_buff *nb; +} grub_net_packet_t; + +typedef struct grub_net_packets +{ + grub_net_packet_t *first; + grub_net_packet_t *last; +} grub_net_packets_t; struct grub_net_card { @@ -118,20 +140,6 @@ typedef struct grub_net_network_level_netaddress }; } grub_net_network_level_netaddress_t; -typedef struct grub_net_packet -{ - struct grub_net_packet *next; - struct grub_net_packet *prev; - struct grub_net_packets *up; - struct grub_net_buff *nb; -} grub_net_packet_t; - -typedef struct grub_net_packets -{ - struct grub_net_packet *first; - struct grub_net_packet *last; -} grub_net_packets_t; - #define FOR_PACKETS(cont,var) for (var = (cont).first; var; var = var->next) static inline grub_err_t @@ -172,6 +180,66 @@ grub_net_remove_packet (grub_net_packet_t *pkt) pkt->up->last = pkt->prev; } +typedef struct grub_net_app_protocol *grub_net_app_level_t; + +typedef struct grub_net_socket *grub_net_socket_t; + +struct grub_net_app_protocol +{ + struct grub_net_app_protocol *next; + char *name; + grub_err_t (*dir) (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)); + grub_err_t (*open) (struct grub_file *file, const char *filename); + grub_err_t (*read) (grub_net_socket_t sock, struct grub_net_buff *nb); + grub_err_t (*close) (struct grub_file *file); + grub_err_t (*label) (grub_device_t device, char **label); +}; + +struct grub_net_socket +{ + struct grub_net_socket *next; + int status; + int in_port; + int out_port; + grub_net_app_level_t app; + grub_net_network_level_address_t out_nla; + struct grub_net_network_level_interface *inf; + grub_net_packets_t *packs; + void *data; +}; + +extern struct grub_net_socket *grub_net_sockets; + +static inline void +grub_net_socket_register (grub_net_socket_t socket) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_sockets), + GRUB_AS_LIST (socket)); +} + +static inline void +grub_net_socket_unregister (grub_net_socket_t socket) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_sockets), + GRUB_AS_LIST (socket)); +} + +#define FOR_NET_SOCKETS(var) for (var = grub_net_sockets; var; var = var->next) + +typedef struct grub_net +{ + char *name; + grub_net_app_level_t protocol; + grub_net_socket_t socket; +} *grub_net_t; + +extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); +extern grub_ssize_t (*EXPORT_VAR (grub_file_net_read)) (grub_file_t file, void *buf, grub_size_t len); +extern grub_err_t (*EXPORT_VAR (grub_file_net_open)) (struct grub_file *file, const char *name); +extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, grub_off_t offset); + struct grub_net_network_level_interface { struct grub_net_network_level_interface *next; @@ -182,7 +250,6 @@ struct grub_net_network_level_interface grub_net_interface_flags_t flags; struct grub_net_bootp_ack *dhcp_ack; grub_size_t dhcp_acklen; - grub_net_packets_t nl_pending; void *data; }; @@ -354,7 +421,7 @@ grub_err_t grub_net_recv_link_layer (struct grub_net_network_level_interface *in grub_net_packet_handler_t handler); grub_err_t -grub_net_recv_ip_packets (struct grub_net_network_level_interface *inf); +grub_net_recv_ip_packets (struct grub_net_buff *nb); grub_err_t grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, @@ -363,4 +430,10 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, #define FOR_NET_NL_PACKETS(inf, var) FOR_PACKETS(inf->nl_pending, var) +void +grub_net_pool_cards (unsigned time); + +void +hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str); + #endif /* ! GRUB_NET_HEADER */ diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 691fda307..c60ea333f 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -27,8 +27,7 @@ struct arphdr { grub_uint16_t op; } __attribute__ ((packed)); -extern grub_err_t grub_net_arp_receive(struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb); +extern grub_err_t grub_net_arp_receive(struct grub_net_buff *nb); extern grub_err_t grub_net_arp_resolve(struct grub_net_network_level_interface *inf, const grub_net_network_level_address_t *addr, diff --git a/include/grub/net/device.h b/include/grub/net/device.h index 9f1b9bf1d..e69de29bb 100644 --- a/include/grub/net/device.h +++ b/include/grub/net/device.h @@ -1,7 +0,0 @@ -struct grub_net_card -{ - struct grub_net_card *next; - char *name; - struct grub_net_card_driver *driver; - void *data; -}; diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 7a0235be6..7ff7a4562 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -52,8 +52,6 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, grub_net_link_level_address_t target_addr, grub_uint16_t ethertype); grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb, - grub_uint16_t ethertype); +grub_net_recv_ethernet_packet (struct grub_net_buff *nb); #endif diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index 6f748bbf3..cb8481a7d 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -26,7 +26,7 @@ struct ip6hdr grub_uint8_t daddr[16]; } __attribute__ ((packed)); -#define IP_UDP 17 /* UDP protocol */ +#define IP_UDP 0x11 /* UDP protocol */ #define IP_BROADCAST 0xFFFFFFFF grub_uint16_t ipchksum(void *ipv, int len); diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h index 1f1c48616..c67380817 100644 --- a/include/grub/net/tftp.h +++ b/include/grub/net/tftp.h @@ -14,7 +14,6 @@ /* IP port for the TFTP server */ #define TFTP_SERVER_PORT 69 -#define TFTP_CLIENT_PORT 26300 /* We define these based on what's in arpa/tftp.h. We just like our @@ -40,10 +39,17 @@ #define TFTP_EBADID 5 /* unknown transfer ID */ #define TFTP_EEXISTS 6 /* file already exists */ #define TFTP_ENOUSER 7 /* no such user */ -#define TFTP_DEFAULT_FILENAME "kernel" /* * own here because this is cleaner, and maps to the same data layout. * */ + +typedef struct tftp_data + { + int file_size; + int block; + } *tftp_data_t; + + struct tftphdr { grub_uint16_t opcode; union { @@ -65,6 +71,4 @@ struct tftphdr { } u; } __attribute__ ((packed)) ; -void tftp_ini(void); -void tftp_fini(void); #endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index f1992467d..86311ccf1 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -12,20 +12,12 @@ struct udphdr } __attribute__ ((packed)); grub_err_t -grub_net_send_udp_packet (const grub_net_network_level_address_t *target, - struct grub_net_buff *nb, grub_uint16_t srcport, - grub_uint16_t destport); - +grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb); grub_err_t -grub_net_recv_udp_packets (struct grub_net_network_level_interface *inf); +grub_net_recv_udp_packet (struct grub_net_buff *nb); -grub_err_t -grub_net_recv_udp_packet (const grub_net_network_level_address_t *target, - struct grub_net_buff *buf, - grub_uint16_t srcport, grub_uint16_t destport); #define FOR_NET_UDP_PACKETS(inf, var) FOR_PACKETS(inf->udp_pending, var) - #endif From 05d2ed3277a7c7057b77b2e62bda9d0ed8c6ef13 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 1 Apr 2011 11:43:51 +0100 Subject: [PATCH 0794/1414] * grub-core/normal/menu_entry.c (run): Quieten uninitialised warning. (This was in fact always initialised before use, but GCC wasn't smart enough to prove that.) * grub-core/script/lexer.c (grub_script_lexer_yywrap): Likewise. --- ChangeLog | 7 +++++++ grub-core/normal/menu_entry.c | 2 +- grub-core/script/lexer.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 847d04b03..21fd6b68b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-04-01 Colin Watson + + * grub-core/normal/menu_entry.c (run): Quieten uninitialised + warning. (This was in fact always initialised before use, but GCC + wasn't smart enough to prove that.) + * grub-core/script/lexer.c (grub_script_lexer_yywrap): Likewise. + 2011-03-31 Vladimir Serbinenko * grub-core/kern/x86_64/efi/callwrap.S (efi_wrap_0): Preserve 16-byte diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 94f6e7f32..a675ff005 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1165,7 +1165,7 @@ run (struct screen *screen) { char *script; int errs_before; - grub_menu_t menu; + grub_menu_t menu = NULL; char *dummy[1] = { NULL }; auto char * editor_getsource (void); diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c index 909b515fa..98279079f 100644 --- a/grub-core/script/lexer.c +++ b/grub-core/script/lexer.c @@ -126,7 +126,7 @@ int grub_script_lexer_yywrap (struct grub_parser_param *parserstate, const char *input) { - int len; + int len = 0; char *p = 0; char *line = 0; YY_BUFFER_STATE buffer; From cfed2ad09766fb9243afe4c6ec4c4d782c75ecef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 1 Apr 2011 15:53:06 +0200 Subject: [PATCH 0795/1414] Fix incorrect types in jfs.c. This enables >2TiB disks and fixes some memory corruptions. * grub-core/fs/jfs.c (struct grub_jfs_diropen): Interpret bytes as unsigned. (grub_jfs_lookup_symlink): Make ino a grub_uint32_t rather than int. (grub_jfs_blkno): Use 64-bit quantities for block sectors. (grub_jfs_read_inode): Likewise. (grub_jfs_opendir): Likewise. Remove now useless casts. (grub_jfs_getent): Likewise. Make ino a grub_uint32_t rather than int. (grub_jfs_mount): Ensure that blksize and log2_blksize are consistent. (grub_jfs_read_file): Use 64-bit quantities when necessary. Replace division and module with bit operations. (grub_jfs_find_file): Make ino a grub_uint32_t. (grub_jfs_lookup_symlink): Likewise. Use 64-bit quantities --- ChangeLog | 19 +++++++++++++ grub-core/fs/jfs.c | 69 +++++++++++++++++++++++++--------------------- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 21fd6b68b..044be9d5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-04-01 Vladimir Serbinenko + + Fix incorrect types in jfs.c. This enables >2TiB disks and fixes some + memory corruptions. + + * grub-core/fs/jfs.c (struct grub_jfs_diropen): Interpret bytes as + unsigned. + (grub_jfs_lookup_symlink): Make ino a grub_uint32_t rather than int. + (grub_jfs_blkno): Use 64-bit quantities for block sectors. + (grub_jfs_read_inode): Likewise. + (grub_jfs_opendir): Likewise. Remove now useless casts. + (grub_jfs_getent): Likewise. + Make ino a grub_uint32_t rather than int. + (grub_jfs_mount): Ensure that blksize and log2_blksize are consistent. + (grub_jfs_read_file): Use 64-bit quantities when necessary. Replace + division and module with bit operations. + (grub_jfs_find_file): Make ino a grub_uint32_t. + (grub_jfs_lookup_symlink): Likewise. Use 64-bit quantities + 2011-04-01 Colin Watson * grub-core/normal/menu_entry.c (run): Quieten uninitialised diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 76ef2e540..6857c4a2c 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -217,12 +217,12 @@ struct grub_jfs_diropen struct grub_jfs_tree_dir header; struct grub_jfs_leaf_dirent dirent[0]; struct grub_jfs_leaf_next_dirent next_dirent[0]; - char sorted[0]; + grub_uint8_t sorted[0]; } *dirpage __attribute__ ((packed)); struct grub_jfs_data *data; struct grub_jfs_inode *inode; int count; - char *sorted; + grub_uint8_t *sorted; struct grub_jfs_leaf_dirent *leaf; struct grub_jfs_leaf_next_dirent *next_leaf; @@ -234,13 +234,13 @@ struct grub_jfs_diropen static grub_dl_t my_mod; -static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino); +static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino); /* Get the block number for the block BLK in the node INODE in the mounted filesystem DATA. */ -static int +static grub_int64_t grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, - unsigned int blk) + grub_uint64_t blk) { auto int getblk (struct grub_jfs_treehead *treehead, struct grub_jfs_tree_extent *extents); @@ -294,15 +294,15 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, static grub_err_t -grub_jfs_read_inode (struct grub_jfs_data *data, int ino, +grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino, struct grub_jfs_inode *inode) { struct grub_jfs_iag iag; - int iagnum = ino / 4096; - int inoext = (ino % 4096) / 32; - int inonum = (ino % 4096) % 32; - grub_uint32_t iagblk; - grub_uint32_t inoblk; + grub_uint32_t iagnum = ino / 4096; + unsigned inoext = (ino % 4096) / 32; + unsigned inonum = (ino % 4096) % 32; + grub_uint64_t iagblk; + grub_uint64_t inoblk; iagblk = grub_jfs_blkno (data, &data->fileset, iagnum + 1); if (grub_errno) @@ -348,6 +348,13 @@ grub_jfs_mount (grub_disk_t disk) goto fail; } + if (grub_le_to_cpu32 (data->sblock.blksz) + != (1U << grub_le_to_cpu16 (data->sblock.log2_blksz))) + { + grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem"); + goto fail; + } + data->disk = disk; data->pos = 0; data->linknest = 0; @@ -374,7 +381,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) { struct grub_jfs_internal_dirent *de; struct grub_jfs_diropen *diro; - int blk; + grub_disk_addr_t blk; de = (struct grub_jfs_internal_dirent *) inode->dir.dirents; @@ -397,7 +404,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) { diro->leaf = inode->dir.dirents; diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de; - diro->sorted = (char *) (inode->dir.header.sorted); + diro->sorted = inode->dir.header.sorted; diro->count = inode->dir.header.count; return diro; @@ -475,7 +482,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) /* The last node, read in more. */ if (diro->index == diro->count) { - unsigned int next; + grub_disk_addr_t next; /* If the inode contains the entry tree or if this was the last node, there is nothing to read. */ @@ -499,7 +506,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) diro->index = 0; } - leaf = &diro->leaf[(int) diro->sorted[diro->index]]; + leaf = &diro->leaf[diro->sorted[diro->index]]; next_leaf = &diro->next_leaf[diro->index]; len = leaf->len; @@ -540,21 +547,21 @@ static grub_ssize_t grub_jfs_read_file (struct grub_jfs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_uint64_t pos, grub_size_t len, char *buf) { - int i; - int blockcnt; + grub_uint64_t i; + grub_uint64_t blockcnt; - blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) - / grub_le_to_cpu32 (data->sblock.blksz)); + blockcnt = (len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) + >> grub_le_to_cpu16 (data->sblock.log2_blksz); - for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++) + for (i = pos >> grub_le_to_cpu16 (data->sblock.log2_blksz); i < blockcnt; i++) { - int blknr; - int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz); - int blockend = grub_le_to_cpu32 (data->sblock.blksz); + grub_disk_addr_t blknr; + grub_uint32_t blockoff = pos & (grub_le_to_cpu32 (data->sblock.blksz) - 1); + grub_uint32_t blockend = grub_le_to_cpu32 (data->sblock.blksz); - int skipfirst = 0; + grub_uint64_t skipfirst = 0; blknr = grub_jfs_blkno (data, &data->currinode, i); if (grub_errno) @@ -563,14 +570,14 @@ grub_jfs_read_file (struct grub_jfs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % grub_le_to_cpu32 (data->sblock.blksz); + blockend = (len + pos) & (grub_le_to_cpu32 (data->sblock.blksz) - 1); if (!blockend) blockend = grub_le_to_cpu32 (data->sblock.blksz); } /* First block. */ - if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz))) + if (i == (pos >> grub_le_to_cpu16 (data->sblock.log2_blksz))) { skipfirst = blockoff; blockend -= skipfirst; @@ -642,8 +649,8 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path) pathname. */ if (!grub_strcmp (name, diro->name)) { - int ino = diro->ino; - int dirino = grub_le_to_cpu32 (data->currinode.inode); + grub_uint32_t ino = diro->ino; + grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode); grub_jfs_closedir (diro); diro = 0; @@ -687,9 +694,9 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path) static grub_err_t -grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino) +grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) { - int size = grub_le_to_cpu64 (data->currinode.size); + grub_uint64_t size = grub_le_to_cpu64 (data->currinode.size); char symlink[size + 1]; if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT) From 186ae367af232e0c8faa43abad07085d5787071c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 1 Apr 2011 15:35:09 +0100 Subject: [PATCH 0796/1414] * grub-core/disk/loopback.c (grub_cmd_loopback): Fix a memory leak when replacing an existing device. --- ChangeLog | 5 +++++ grub-core/disk/loopback.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 044be9d5c..512b61cac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-01 Colin Watson + + * grub-core/disk/loopback.c (grub_cmd_loopback): Fix a memory leak + when replacing an existing device. + 2011-04-01 Vladimir Serbinenko Fix incorrect types in jfs.c. This enables >2TiB disks and fixes some diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index b05940a4a..02e6c164f 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -97,10 +97,6 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) if (newdev) { - char *newname = grub_strdup (args[1]); - if (! newname) - goto fail; - grub_file_close (newdev->file); newdev->file = file; From 2cccc747acc482e710e3dd23c672ce6151fd59e9 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 1 Apr 2011 17:04:10 +0100 Subject: [PATCH 0797/1414] Store the loopback device as data on loopback grub_disk structures, rather than the file it points to. This fixes use of freed memory if an existing loopback device is replaced. * grub-core/disk/loopback.c (grub_loopback_open): Store dev in disk->data, not dev->file. (grub_loopback_read): Adjust file assignment to match. Fixes Ubuntu bug #742967. --- ChangeLog | 11 +++++++++++ grub-core/disk/loopback.c | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 512b61cac..fb6875c69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-04-01 Colin Watson + + Store the loopback device as data on loopback grub_disk structures, + rather than the file it points to. This fixes use of freed memory + if an existing loopback device is replaced. + + * grub-core/disk/loopback.c (grub_loopback_open): Store dev in + disk->data, not dev->file. + (grub_loopback_read): Adjust file assignment to match. + Fixes Ubuntu bug #742967. + 2011-04-01 Colin Watson * grub-core/disk/loopback.c (grub_cmd_loopback): Fix a memory leak diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index 02e6c164f..939043f01 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -162,7 +162,7 @@ grub_loopback_open (const char *name, grub_disk_t disk) disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; disk->id = (unsigned long) dev; - disk->data = dev->file; + disk->data = dev; return 0; } @@ -171,7 +171,7 @@ static grub_err_t grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) { - grub_file_t file = (grub_file_t) disk->data; + grub_file_t file = ((struct grub_loopback *) disk->data)->file; grub_off_t pos; grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS); From caee5efd313a3f95babb176cc710ff193fcdb81f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 3 Apr 2011 15:30:28 +0200 Subject: [PATCH 0798/1414] GRUB developper manual based on existing Internals section and contributions by the various authors with active copyright assignment. * docs/Makefile.am (info_TEXINFOS): Add grub-dev.texi. * docs/font_char_metrics.png: New file. * docs/font_char_metrics.txt: Likewise. * docs/grub-dev.texi: Likewise. * docs/grub.texi (Internals): Move from here ... * docs/grub-dev.texi: ... here. --- ChangeLog | 12 + docs/Makefile.am | 2 +- docs/font_char_metrics.png | Bin 0 -> 16443 bytes docs/font_char_metrics.txt | 1 + docs/grub-dev.texi | 1515 ++++++++++++++++++++++++++++++++++++ docs/grub.texi | 106 --- 6 files changed, 1529 insertions(+), 107 deletions(-) create mode 100644 docs/font_char_metrics.png create mode 100644 docs/font_char_metrics.txt create mode 100644 docs/grub-dev.texi diff --git a/ChangeLog b/ChangeLog index fb6875c69..47bb01e7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-04-02 Vladimir Serbinenko + + GRUB developper manual based on existing Internals section and + contributions by the various authors with active copyright assignment. + + * docs/Makefile.am (info_TEXINFOS): Add grub-dev.texi. + * docs/font_char_metrics.png: New file. + * docs/font_char_metrics.txt: Likewise. + * docs/grub-dev.texi: Likewise. + * docs/grub.texi (Internals): Move from here ... + * docs/grub-dev.texi: ... here. + 2011-04-01 Colin Watson Store the loopback device as data on loopback grub_disk structures, diff --git a/docs/Makefile.am b/docs/Makefile.am index 8d9fb8445..6e1500601 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects # AM_MAKEINFOFLAGS = --no-split --no-validate -info_TEXINFOS = grub.texi +info_TEXINFOS = grub.texi grub-dev.texi grub_TEXINFOS = fdl.texi diff --git a/docs/font_char_metrics.png b/docs/font_char_metrics.png new file mode 100644 index 0000000000000000000000000000000000000000..8d10d1f645e3a22b1535716256adc73f262e56cb GIT binary patch literal 16443 zcmc(`_dlE8|37Z;RcfyyMr~pXswk;dt-VJDwfEjsZGw`TMQQCVC}JxyO6?%1Rl5i^ zKc27mpYZ+Ro7*kPb_{?|aar;wve%qo zs^45(oJB+*o=})5Kf-(bxF3rjhoqQDgX+;E8;z(4Q2_0$AF>W<63{-x-Q9e-!@EC* zzH_@v%QN0bfwL99?gsh#%QGE12aVClBvsCIjWhP?UkVZb9X-y#^ZBpiDfk&Lb-ZdJ z^#4=yjOy7G3-n{UL@^rm)x!-#fsxKG1p=xUzexpaUuun~HF+d@k!qMW7;U^0Pq_uK z<}Fx>C53m%4Q1^JgP&27W3Uc!=>%n317upg39oaB=kbk8qg`KcI4OXQG(J_2@oe?g z+N98Jrr^6dHKyt`VAnZ8!j(gA8fSrdsv-=c8!rL;$AWeI$BxN%IqdUzIW>b~zkX<6 z`X2|3ZD{zU1B&9rpoZ9nI4jt0l8r-N+e#$gNl}zlI3bVW1OWs&WB66Crp9O% z{J4b(stB|wQBIK7?W-Fi(N@?k*H^k(oI65uSBU$2aZ;?&Sbk^CAjzBXd>E`$@AC>Z zA{ep!FHA1EbT@J)k~@+&GM8y%EEC3fDRZ}V!hg&T3@$D0oQd3w42}$^f6N#kPB{Jc zPZjxhsw*p2V*>aD^3GCx#rK$SSqS3SUFsWAj@*y`psDLa1Jqp7@4}A5A`mq7aD#aq zI>YRyu^rxTq~c8A9^n#h{kfxoKV~2dAp+sM5GE1(wvud0k-ENZrB{KKh#!Ok&rWfU zHDtmGL@mmYCkXG)Rj~~OC|o4nNC?ODUB;#0Ur%d&nR{_jY&Z@5AweFYR>rQwtw+cv zUEx6+qEcw2DyywvsCQL8!T@N`M43q63tz$K!BPLc$V8k+9zs>~4~!N^d!ZM#+O$=a zG#yeDDD!ZV2v-O!N$pd{&g=O+jASkXF5M`}3m4XWS0|iCLyUYWpSZGKQuC7T;6{jS zwz!MEddALxhmeBVsmFTl*{9qBZvrL=K9UWUaq|{w4*HNBzfjS@-V=Xi?asQWB;&n* z>9J2@-R9xa`0Anq=Cu@OcS?8GDJ$xF84jp>!zVBGri=@RDMyxQa5VBuZ~d1(2Y+c% zPL^C6WBE7kJm|PJQ=?IqRo)QkT>BJO))9+bSwo&8C9JOGi5dqy9TMN{ADPT?mEWW& zuLW@C;xH7o*I_zlTXz+~SWbJ0Y#Ebh-EZnT&7Kq$VhwICG7y8vZ)ClzIEuDMvt0R$ zBBP^==Ec4DQ!mLvRBQIt5J1@N#t#L)-V?&eMDgn{IPGt>TCum^V&u7tF31l;1pU8@ zbxG#_$|o+|WXqKGllB1DpnNXPdYWN&_BdCJ&tP`!x0hXjN|BtHd_7G(OoT_7=$z7TnPcMMU4(|c}N!_ zcE;qFq#hiK9i4;$_%f{F2S*Z(>p_RtB;(6T6Ccu>G#UCl5tPRR-O`>kUFn~1n%3?w zNEU;#-*wMDWqS_6L@G)1g!(0`4ctUe^?uypf<~}Gaux)jmNtL2_(!KMIgKQsbVD<= zM%dT%j|0Dg3u|Eu0_he~c$ZCW8)oahF1kQxWB(^kdgf_cZrSoLvWJ>jkN+uf6Pj ztL(pZ@kILHPX<#Lx;n7)5dvTFSz?9gOaXjTN~7#qb}V|x(njOzncMmPe*2DhA&F(>RKP^Luj05$m=N)#uMVF0IabO3m7t^L&L zxHXnMvh5gl{S9FhnagdFtVHH8NDpab!4Kijytd?G}eN3JfiZ#8sScm1;rYK!+PL2@5ZbPtz-4Hr4H1O~0eRL18lU-EF%dZ#Os2ky*ypALItE!x0 zEa^?W#{$;0z>dbl6F{Csv<{g7z?C3LtkG&l;bS{dMUIN+n-1xS`@U$W{DK(o@N_z2 zn!e;O9uvK5NEP@Z!$T3+VKRkhomA@Ex7+famnPor zL95#uTSIg;+9hPdK`DgeN<{vFI)E$aTf%$>DUC(K%cqASKpaYjrX(1x>?MG@`M)dX zsb1SG$LB5*2TUSA*7)nktI9g1i;B63HeN*R<*)=bGXFeyuK;}kUKD^=ZBMv99v{n) z7X}9t@G=2z<-V4fo;Meka$aDH8|E~x^k(*U2%!-=WYQ^by>1fd_gIEsaf65`@w?u5 zT;ZX>Hwz$;((my*E}-rz zc#mzE3IZw!4W&gZt<7Hr_;k}m^m%R04V?xX)f8~n-FzZi{ic*4 zLxPYkozmJ2oQ(IVTe>k$e3Pzs`8IoKc_npJO@E*Hzh&7MZPYwTE1P>*Y7XS(v9$af zOLj`_V4*sXJ}}>JuNyp%P@cl|?MMq|+CHrt>Z0_QuEL<`2__guoth=B_n(+euHqYr z7DJyyWMCv$gmVM%HjHzuh^8;A@569w&WAoE+s899;mlOhxVa&_6eYlJTirc_Vn#j< zJ<8sN(1pOo7Gl&}8Z+!q_1E;%0x1+T5PSUt;-{l5&%C)f&nQEqTjOEhF}Eai_4nI@ zbr;d7`P!RXZYUs%&2;Jpeis-bGb-mHPy)x=Xsb5w zxs8>md&$N!sa=R4*CBpTQt35dncxQRQd{|i>qKpU7|Nru=;)FCiv6kaYg>&+>*7^d zsMuWHd^^a5{WyE7Lye`9(UBjT1Sk*ib_qfQ;VVHZXbRwUca2p))$^$;L?CY3we^WU6o1#RhAneNd6M66&9ggeWNwSi7-L@gJ53dNB;+8Y0sx*tSjrTIX#4r z<$)cNdG6oV(WtQRFUn| z-i1@bS!I~uUnz#l{sUIVsMf`HL}A1#cDBR5n}8j}9eW#VJBG+be!Vw{6g>T)pjlZk zzlLuv%|;n`n3)(3wf=^I^S{NqJ8xM%$24(;S8=uuTl z8;KvGE;n=c>jO-IA_P2D0}nkN4>P9s#Ys5=^6@|kO6UpkM)f@w-G>o4qG1X@ zH!%YChYZ4aW?RmY&fKB+#_%l;-zb_fm%`bBAeD!+RBb2mnkR96Q|;=S8io!ff9QRg zAXXk39Z!ZzaNg9`!DnQoRWiJ$TlL%qDO$6Iq%Bn2oCK0Y%-lYiQ>zdMy<;7LsM%$>PFd2wx(E9c$-OBh_*7aq!^?SlqA-1v^*j**QaYBkzOutD&Me}2%%$^4>0E1 z<$_>5_Mj@v;7a?>C)}*qA+>5}ohfNPlec5^!0>J>kGo%}yZdA0u$m5?{dXQGd|+@z z^2s?%8~LFO&%{}!_|wdX)4;d;u9cKnI7C|BhE-{K7u z$sUiQ&jiFS(W7Gp{S>Ag2vYrmF`2y8!S%7jebjyzwK#rn%QCS)`ilWL=MxR1X zCsW|{vnf1aZgoAo-u*LldHS-YD@jH3) zURE%zDH?YB`Ox!>34Fa_(sNIlYJb}WJDC4I`{Y^+r@h;WXh-Ugc624~Y(iCgHY}fI z$x1r?j2Lv>!C9dYS1D!bY9jt9wzO?*f1rKnrvMXw3bJ%J%=!)bTMqb*Jb-pcKdJO~ zWIT4*%&OM_AjU$2yuOO6dlx3>*~@5s0mvhaE6q<#q2yg7%P?RGv_ZM9k%6D-&PcfB z@ocl>Q6#(g@t`HZ^*HrrH+ZQ~x<1A+mx4r}N+?}MllDIPy^PwdFgR{i<-zd3x?zDo zZ5SsA_`YgNTwq(j5%8X_{T=Yyq^Ew!t1O_efJYBIdvEvIyBAYI)tbI>fTD6+K=Wfu z<(YbclZuo=4b!UXNM9^4aKov>*5Pl5uQ+PQqs*lYL`MJGS@U@s-q|m0ZbBMhFp=)Y zyR*LU4Vke-!?+W~Pp$H~TDt+b5uD%~!T3keClV4uNjga0Xj`lGN8rJ7ekjKYHs{l);UG!V+w^Zib{ zF!mGr@k7o1e9Cg8uOQ`QZjh#fnqK z{B$-LItgHdGlbbej0}VXoe-Sac?GfQc}yAwF*;JVZ)^X1sIoE9&%8KuYP0|F>fD(_ z)i`$Fzz_V$bg>9u%s!oR6~S?Nv@o7lHoSX9&fziMJ2aLB#oTzK7svbA2K3A<>dlODLxt-O;%>o1@R1}M5F0+)Cy z?3^wi3Y6|KCJr?xuf=g}>Z_+o&==tI5a4#XKwM?19xKd0L|bfjB7SD_P$>0{D9Qy= zQ{V!s1)QQvi37xEtRykOA*-S3-J5T=xzP>kl8t_l&(qT;21DQg@o5GfiN+JwKT3Mf z)0;^%m((e3-kk!p5@QrN1(64j{QUdrcMr#DgSl8bzNV)&EO34?Gb`AJVvU50``(r}HWEgv&6JVnV}i3>;;R=`|K={xPk_2!hECcm6*gZp z3W>O}^K(=a8P6i}Vxo5(bk}`*?(t@wc!g_9N#k`HeZIpE*q4mRpo$bXqQxUe*9zHO z5vBGYuET028;=ZJuAiabxRO_e|Fi2;R-0NeamcbH*?F{l_(V^O=t~<{9bV1c*x%2v zYKzaXlmQ~q#tiOII^7Q@S(1^s$2ntJ>1X)sv8U09R<6Cw^X@#@a;`j2i1wBh;;(+; zf(YlX{@y)oyxH=)xr!?dC zn4j_E8IZ~IV@Xg0>V@)?Gkgfc=`)6eT?-Xyr6P~mkJiJ`b;EMeoB^hTL?~U&Pqk(nyI8?5GH)ZOv_%7{ z<$Q@9G;rF5-JYyexnfy-_w>W%k3B?s#FTE1>bx{1O4X0u8A|+F zutNeTarbbPZ=2jyvqs1Eza5AFpV;rMF(WFVm_I`>qsvG`^03vS&wu#dUm1|$jyI1zg(wP`#E&G5vBFK*VNe z-2w#`^6&4loY7G&tkQqkVGEzrefeoNzVKQp908&{&6F#jWPL)o5V{keg zL+96!=NaB#&gDSkqsJzpNDM1z&Bdj&BSOzNTpH$VCE|6nS`&=4L5;phx$bQrLVcOA z@dYiY?uWwN%aS|2T~{cRey}dl!pnZh9Af#Uu!c`5&&8DHd&EVQN9+NIbklqcod%xn z8nmn_e3SCj)-axx~7HC%_1-Bxs@OO`AylVg%8mQS3> zJj8Gne9b(C3z#SvzVq4~zqW{wDqcVDOP1JAYZCI{@c`mxz%9vK1f29M{i;q2V(f20 zxFHG+iy9zOO)~X|Xb9(CQy&ig5FLS(&{OtPTvnB_#8_8B3PqjBgAVP1f*20DHG9PO zbOZO^IVJwxFz!&3skxJ*5F4=7ge&3NBj##`7XUlM)s$e@KxO#Kh%i_Q~8?nDH1kdC$0>v|__?d>{!nH9E_bYu1@Z&h3K zuh(!AdtG$>M$f?oOtHZ-9`xS+SO;&DC6-LKFp11=%Ayc9dP{K=EN7z8D9 zA0ymkrV-D(X3G!$&HUk95G5I8&00i0(UUk&y&t8T8`RzC<4~EN<_I{D3PWRc_u= zGl9(og2{ndOqPxxz~5Ey`wG!f1bNmeXTZFyf~a3EVqb;D0)s9;Fmfb8p6F~i5m9+eg0*+1e(I*pFd%ZF@DG%68qa8fu95DE~)q6=N-A)sy zodT)wdltJZK_q3FUFVj?coy`@G|TTDSpKnPy!?rW%v9MKYLECogUDOMv|epS2^-fZ zQ~N_a=Nz%E0%5qF&6mm;PUq|{uCM08y&FCK9%ZoRJWn%x-RIy+tPPLKbYNsBX-kfD z9XP+dI#v2=IHAPag?_qgX0RIZ;nSdkN>4p3a)AHWty8~bS1NDu!Hlm3yI6~VWZTmI zc0~J8C(?MUe-&hR)b0G$Q8KgJiqB79mZkL!R-G}I4VjdD;$#Yr)eQ!7aT|C&OK&oC zP&drCF7GtXomm~ImU^e>YOMUi0~oxFG!;g!_uS-;$u*t{k~uLaM$?<-dgfOTUJje| zy6-$+_g%lhUNSz%|8Bvb2_r&5Agtt7nRq@5c@e9|Y7)QLZpR-XNL*)c*#y6hASg%s3T9e5!H9fN!J5l@oV~zRd^BW{B!q1=6+D%Ul-0ES4%>Eoil| zgNV6V>|K>BbNdmhw+_Qa6N6WEgze(HU;H`&+P42IB=X4L`P3?ylLd+sPX#H zIj4x%;@a5#T=zLhUj@lf9L@bD;6d4n)=>}qkT!~Xm%>-JjdX4n9J+S`TA6lI!UL>HRAl!Fnhc$9L?@zEMYrr>^=6!^n{p)7+`w z(irXaD#+ck&bHIuEgAY6&W71&+aQeMZ{}w8QMjR! zCU4i9I)Dy>+leV>#ou4z7uL|6Wtw>gW1IjA zIR3=%j#InQ}e(dAH0V<_dI z#~Bj}F*H%&c9I2FDr{zz?w(8pCJ$Hmp_!3>h6daU97eEFsKaKYb&_0tzHe z|J+~@RT{LIw+o=T%!DZ{$75?$Km*nZKzD;b5g`za7|@K-%IHeKqZTHF=RzK0I)%xS ztGycqF2}`kxHS;xAuMR!SQwX>gY@U z&~io}g(`|0?#6ERyO$Co9t<9iIc+V)mDq{0G8jBeN8S@{u_~OGBm-BvrY`pNvp})Ssj;0K|dYm_XIEo}72v9rG0t<`1 z>OU?3#GO7bm^y&f5pN@iHetp97QW{+N?J@PT|^gD#|SdzinUp45+kREutfhw_>?@8CTovTo7}K6d%-V ztWU-*+nvgJ=}iqu8H)*??}{CoS9~l((u({SNY3-SsLSkikLp0%e##v z9G0QPVkebGvDkFOD1y3$lie-WtEJe!sD>vkkq+IV`FD4&?77Bo176u^oZx?}2<=>` zdG-ad_+_+kEeT#?xZmj|pb%0-PrTz1Vredv;ae6+BE!JII-(W5V=giDxTf;2%sJsF}zHGb=fN|9#TXMd%qrZT8MLPr<2ZlC;BLLEx39nFGFjp_Ly-= z+$P-VMrH47xgo2DDJvzUTX+5l#%p7o*YOel-7R%3{lavSO0ymBQvY{d7zDEX*Lt6i z<9sSw|Nf@RMUAB{BpmGgV%F&;Sf^K3#j>qMtTE0r z%fP@^ds9)}ca6+7XLggX!Ecuj+EUs%j}E?gE`w{_)^V)`S2RIgwWeUu!}PPf((spZGKFTkQ%q3djI)^1Z52SP`{oEzcoz?RPrNCd zbrwE0$n9hU-iQt=^4!mchEZL8SDktTbrWoOli8G3I?cVzy{iY_2AgtjHGWGd-2|{k zUvH-NS)~j2D6J%q?Q2yspww7LzznwghpZ+CVvEBSwh)I`EQB45qw7ywP6Tw3vSfdg7g1EnBfi8Av%CA4r1HMBEuter=)`ECj>H~BW zXagP|{u4XhvF&zlTu=_Ce)%aLW5Dd*vT(rGKlJCataN5^-}BEh%Behw+YLpPDB@p|2v48s~`vo9)%%mn0PCM5wfIBmgd3CIJD$&X4cdS5KFGTw3+3;Kx?~pS3!e{Q3$iY* zNO?+^eUB6ASAo;GbMax8gS&Lile=ND13YT5{`FpB!qacR;V~qK4CnS)fFzeEspLI$1hcbTmAkOI4vnMg*(HG zlaKCftZUpXjrt`s7nIpq2j#E>$mfMw3Pn(q&ixpJ%^#t31@G?gZn8q`(M2IKykKwe zqTZA;GzH<%IE|Am*m{rPdUvZobw66Egp<2wh*!cb#Ief-{fKi%AYtI0d7J}V{{XI19DtsV^VfuZ?ztwm-KGCkJK~DRqY5AtPU@?)-LIRLoGuFEFxHQ zXxTm{G4r{J%q437P#2JW*o&Ox4dFC)wC*SWmo0-X-~W&WnfLfAyf}W{hr7wF=q&Q* zsEtA?5Z?tWk5#dj@H)9m2=CPiSpd(wgZ(do{~*8pT>~fvbbsB3Zq<|w&s=xl(TvuG18oRcF%x~- zFG{Z7@fuHAd9F41Zq0)O*g6BpTyTL)`8W!BFbi8qCGO}(Z(zqH8w3*uZws@5lxVih zEi$+RnRI{SzP#FdyKjkX8$|l`T18(BT3PwyKc?eth3fxc86s#k_9i>|mZ&4%coMzi z{b2lpZ`7Ilh|p&}-xVJ38gdKq?@k}Iz=lvO=XVJMn)IYg#w<6T&D~OI+sNW*8!bJ& z?gaK$vG?^5zfk7$pfN|ZJ?RuYLN;Dn%vJMQZS0<-6>gdYDciSQsCnDe90Rap4%wA@ zFO&W8muOix?WMi}wxlsqMNN^&WjgWhZ)onq4@e8o9YT&E9G@w!y!#K+UzUjaM4i;N zT95oKX*h|%`z*%(mtjAn$2cFb@%P*#dw&rV!To>h*0=%_VE8jFd7H?4|9&A=ToxNh z^R@X`Q=MM<2uW@s%U9uI)~={$Pf~cMFW)EF5u%(Sny8BPM>kn62U-gP5layU9*wa2 z%ibjbE#aZEAJ*}skij}Y&2?z*k93qFg=;FVVQ=9}()Gr3cZaLJ4+&iR()v>6F=EMs z4j-*b`)UJdE%RSs74py=BvDk#c$^N;JKC@sxIRvDBJ1K~29{lTP!1M^D!H1^xdhY| zSIjjz)r9S@qm|@9cUkh2gSPNLK*Q#r(!>PA|3Y3>tuw?E1_cpV@wO4l;DsX;lPf_4 zF@BB<{u#=w1=k40{$(u@-d2*7+=b4xrx)(#Pqy*T!h!aJL-NQnx z@FKRY-74t@)b(qvzE*nps_{{FV|~4aCSjFtdqC|+6Hf`3j?+2sr?7cty-;6|$&zCY zGjEBfTp>1&1~)%UuT*=gpBeTzH2%~rkgByQnB0DjXCJ<7#)~g;$Mg8wE-;fqNUoV7 zx0e#=7xGhYZKs&mM!Dmj-c#s}ARTq9%q719iC}E)LK8obTAJa*t>O_bTG)%>Wc z?Y68S27c1B1)sG!Q9if07%;kt=)w^+xR80*j!F3q=$|7lNVuu@F=*Bk9UO>%L(I@M z(jBtA`X+I&U3NW)g4EZxFX68Ea1Uv5y6Z}`eNSOn0qgIz+OCGoC#Ugj#3u{JL{#=;axLMrWho-)Ro`RaGEx9@_DpKEO$y?3y2 zO^haAJO^a@FtB-ZzklF*qEcI?9i;22AEF09O;c{$#CrR}U;p&$*Z#y=ob0o>ql0!E zPd)@&X!g9hctNPoqGd^xybx5p$j4CW!TWjsgzfRqp&nXV)Bo=k3J?=~Awm<@R`eXx3o#p+m2h1Frc{BllsOH?G?s z|9F_f>y2Z%gik}!Y))=UD^+(cm&MLWPMO%u#*_{dCIF%MTp@!WE-PqOROFY615e%b zGayJuo7QrWUZ}F65!TE+!Oa8)8b=Zrl=>crgw(rpK6n|ra^i5|Cr(PEIgoc=pq&d( z-QR+RJ#+IEB94FFJ1*#7On+6;Z8GrGEigMNKk0<)-N>CeM%E|J&1w-YPmxjiOMS>s z_FH~e(hI+Ew?l=OYsRa{dnjm9D>YU%bZR}gim_rwQb6*#i`UE>N^OTnWyup?^a;sB zC@*!(ul@wH`p_cxrGWBNNX7R{+U#*64d%q(pX>^P3rTe(RS1C26-$|fDyy;$3+lTm zDlY|HCM4ZokZw`V03W z*$@UsVp^0pE!FcK%iFf7>8dy84i>-K=uJAXau#ORzI%AL=NNOKKa;i8jStQ4(oM|H zoapmrE)L|GjqP`A#Y@olM1!gmt*levVUJR7bQHEh2TKDT0 ztHRwk^LsrNu`l-LnNF{vafs->p^to(&yUTlP{Q zMTbi_r(MkLQ3L+rFR_9jh8()HGA*wKQlNjm(T2>YYCdl&XI=;Zgc65>;_E2_Xi{gy z5H&5sSKOe??H!E2kP|jY`0|6Y)H(H`;>`+LomRcCLb-tMaBcWc>IR+M?YPY8nTy7! z8BiUQO}EWJy^M!W&5G7#=#`gp?n5#=P%N5ZUt1hNBsWJINg7>YM{aI>grCQ^t7C3# zmE=&llUV+#^xVbz_#aI?&G@84MKTEDXQhGTsju417aO}p><+bhcwjN4j!#1Fw# zl_o~G5-$8=^d)lO3-_)Z&Z#?>Um%=th~#w0B8HDN@r%4jEq2Su3R^wSb+Q7fuLmPe z1F-U{cZ#_P3lz5>hwucDc=#y8X1uP=Xxz8XG^A@wq6>$b;EeYB=Lc^lXCwGrKi{U< zQ@DEyF*kX#E*z*>|6ogMbV8Ez@P21VSQ68&k#7sSAcbJyuzYI>Gq(3yZ_wjA)lhK3 zmk<$fz1y#9ILkbFYG)@iKCEtR-zxb&S~EoJ#^#v$WOSC$khxlPZuKxh31D|wPr!38 z^qO&uvTAj3vRJIqIf9VjXTRhYB-mnrq{;#dkbK~`O3X{VL-Y{723}{t4w8aJ+>-W! zy9q$tyGqb5UZ-Yp0UWTIVG^^aLQO5#4QrYKXSTs_RTQh@dn;4ru&%HH-q@rjeGjjh4(2VY)^oq5Bc9R_e zgoe@JdCl4fzCb?$YiFQ8b!$pCfb&=}r~3p?b{hk#Nk?9C@kzm*xPa2s?lf*_VPC)-mur z2{89rF!1Mewc1Su6ps@q_kcG8>$Jm7US?BE0Go=`;GF-wx}+AI*b7PW;* zK4w~#>r#+je^PF%2dJK z+A|u9RW)515r^Ussh`Li$wv2_1t@~vL;i=}<#xA(M|x@QbFFC5mv=;9hc%vOVp`P? zf~XF)q<5*J&TRQ$q6Okrh?Kx zQb9F26QC3VB?_K~R>kH}LC1w0|7@=v&3QP-xDcFiMIJ=hd-)y`2qTuuR>{nw?T*h> ztwv`8Cy;&=e8K0Lm>_* zO3~kathJ`5T&UCQ?Kqw*uPByuI~`C|Eog+j{pP!jKY%UQwiR_k3~9+OJ)pht7w zwA=l{Us^Ay{b$S--cuc-!}rzOcqe=abwWSpVg+6maXjJ#)lIjNH7zU1Bn7J9+_`G; zTlOj~DKI$3h0}P*4@9Qx3?9v$dky6_`?H4W(l=jdTE|9V3WipTFg?}ve-D-^_hGUa zIyd_Jn0GGj1M9L=g<%1|@1)z`)GD9FASfo#JYEQpjBwxIUws6-bpmMHu?c?F zP+G3TVoWBa{`6RD7&)kEniyGMSV*+pRq!p>)qOFli^<)ngk)T@N_}K-PA8b($^8=) z^C0jJ0EMwiOA#4qa^WhbA?6c_JLbds>SM6_M?%lI6cM_lqmPqw6>S@1i@`wd*X2z!%!L6c`uAx2*OM+VeWcj8CePG@ul@%#zkjXb<+yyc5->@E7)oXYae{q4= zI@#|t9Hah6RYKm~BFZ3`fYxgrxgACI*OupL_Rl8>#AEoTs$ViavTZm^`2Mn#k^Qx; z-cRj6P4@@94ZUr14-~K=jZd^PhOh5@$#dS0rF|&Zpqfw*nMbw|VOQJI`PYgz7KrF) z?YHlSkA7Zqoc|U4Vq+*jUM9%3MqIz0ClfK3k#N<*r zbe`-{@l{Yjd2PlXo~}CtTlzMThB8zC>y}3U8wsvIpLy3JAK9;dNt7it``MpS=YWc5Sc!#t07Ho>Af0`Bl8Yuw?O&fd8vj5ZPIp z4T%d)gbkFP|6woy5z`Mww|{>h3``#M#&GQNpeH|{sb-ylJfdK?b)>GfDZy+CE)VJB z_FGl^1fNQG-1`H=IH*)_G{j(&4%pFbw(;%x!clwr12tyjTVjY#uO)TKy3861N!eXTr}njee4ADt!0R}5r)-?K5;F0dLQhAzmz(kpm%v+Ugg3%fAP`S9vyxl zd>2Rz|Anj>YvFPVw5GRy1j_nZ5HZBkB&af96mTnN~)>BzpQ7*RF0|PWLzz{9Sj*blLiXTdLQ~L{W!39@t z8ZdIa81b=4NDrmP#g&uXkOILCs>xbmUW{+5d2MpySt8ZrK1t+eG|763FXf~9Ja#~Y?R>0F`soSZup>;!9_p2qTTVZ!}f;W4qLBE+W10g_jcsM zLrQJ(&$XtR0&_uIN50_i`>No5+8S5mW&hs|xzl}BEBTYnT~v2c&&}PU95fWi%YL2T zGRa7w;FK}0ZfF{4jTmJuxNIDXSPTgH{glq#<*&2jOc#^6HALhsrncYvpHPfhStjQ$ zC%PnH-)OCIO}*ETv_>(IApoGXVlFQq>xZ#B-c9u5P!v!vCXdP*`paFej&?UaMXw%Q zktNleXSuhU)NW*clX1BWq^5&NAK~XyO_IiSlVi8KTm}bCZjcx;OZCB?Jmf)Yk?hC&J{&z`A8)8Ik*ld!Ga{|9$QKEw#NWt1*H&V@l z7*{<&06>VO%4Kt$pBe3LzWiI_fh9H?+W#sb9BjG(4XWn#dHzf~Y2k=6TnW*~752#L za`coX0@jJ+!h(9yI_NtQ{Bm&=sRQvE+}I^qbbR%#mW(FX>ZR;#WGv3O~^mb@>P`z%8w=owt`GA$lXgFNw4Gs$w{p42gb4n2WpGbH4At5rpY% zz@Os3PP46ob2f?tS)$aX#Riz)?| zsd-63n_kVYzMcw!opO1Eda2Og3KpCmQi0hgGIKeM{q+w8puCa3fU%Vq%Q{{ZH9;_n zxg*M)9^N$+8+Q+MOW51>5IZhs!9enSIqC8E#~=k_JG?Vu_~M!Y3Un9%vY!w)>4d?w z`)RVfuu;6bY~cIB3|-5?-++u@TwQRxNB}?wQO(j&8+eU-kL8wjX6?A$jmYM@PFUkZ zd2MooX#fW^70;zbQ+tlH>#o1TZaY&v$@Kn%zI8g~&aF5IW`pUA-WPZT3Wj6(J}qSgD_?L1o;Rz zPXrK3HUR*Uw2m;i!>E#IuRdWLvsx7e%f4}!GG|!*6o~8iR@?-qut)JNWJ2OLtv#l6 z0*f9;NxV^obllw$VssJqwl5VewDd!*Hy)7=!Q6i2rfDu_@}@2;tq)BC*^M|O)W`O_ zqE4M8JINPM0Q+?jU99snNVlU`!4@3Vo{y(BvGaSAF=95fq2-)wEaU%8u);%H-UhyW zJBxUCE1bs>NR7c=CLzh(p@Lwx8@!7p>cOT7Ei*Uz(c({pOVcjpeB@}|7lmPyYHZY8WR4SYIntk6DZBJH|FvR6mS>#Y zr$XprHMv50T!;4$b12>Dt+^=AK9|lOr)17!15www60Ca;4px7hw03js|BUC9=U~|t zvYp-J@5bQW)fo@L;DVPn)>z9NDevC@TQjcvVomrk7byC21qhFL`tB&xJeb^V$l;~g`r*MpjHUb3N`>~~ z5{duG#9ux)4*g#%@!SW?IC*+gE1~eKnySvwNHy=FqpUNgI&xeE&D`b-pt;QU#4=W% z#ncKb{EMDRurs{&z=opcfFiE?*vplI>$^Rw$$JeBvJz)nJ~|h49@oQ^Ih^t)&h)IJi;Y(On8vWFx^=VZ&uT zp!Lsz?_$9*@u46AK&_`?>MkQ&DFGtxGdq|LKma}NQ)?=Mr#RR2wbJ|4IDbAJVex;T z;Xwhyvo2Ua8u8e-KWCGatGsi?~Qu#w5l-7SNTWo(}n#L|Bh{L_S6=BihP-bgXPxm9h8g5LOe;5!N(;R<8jJ( +@c Date: 8 January 2009 + +@menu +* Introduction:: +* File Structure:: +* Font Metrics:: +@end menu + + +@node Introduction +@section Introduction + +The goal of this format is to provide a bitmap font format that is simple to +use, compact, and cleanly supports Unicode. + + +@subsection Goals of the GRUB Font Format + +@itemize +@item Simple to read and use. + Since GRUB will only be reading the font files, + we are more concerned with making the code to read the font simple than we + are with writing the font. + +@item Compact storage. + The fonts will generally be stored in a small boot + partition where GRUB is located, and this may be on a removable storage + device such as a CD or USB flash drive where space is more limited than it + is on most hard drives. + +@item Unicode. + GRUB should not have to deal with multiple character + encodings. The font should always use Unicode character codes for simple + internationalization. +@end itemize + +@subsection Why Another Font Format? + +There are many existing bitmap font formats that GRUB could use. However, +there are aspects of these formats that may make them less than suitable for +use in GRUB at this time: + +@table @samp +@item BDF + Inefficient storage; uses ASCII to describe properties and + hexadecimal numbers in ASCII for the bitmap rows. +@item PCF + Many format variations such as byte order and bitmap padding (rows + padded to byte, word, etc.) would result in more complex code to + handle the font format. +@end table + +@node File Structure +@section File Structure + +A file *section* consists of a 4-byte name, a 32-bit big-endian length (not +including the name or length), and then *length* more section-type-specific +bytes. + +The standard file extension for PFF2 font files is ``.pf2``. + + +@subsection Section Types + +@table @samp +@item FILE + *File type ID* (ASCII string). This must be the first section in the file. It has length 4 + and the contents are the four bytes of the ASCII string ``PFF2``. + +@item NAME + *Font name* (ASCII string). This is the full font name including family, + weight, style, and point size. For instance, "Helvetica Bold Italic 14". + +@item FAMI + *Font family name* (ASCII string). For instance, "Helvetica". This should + be included so that intelligent font substitution can take place. + +@item WEIG + *Font weight* (ASCII string). Valid values are ``bold`` and ``normal``. + This should be included so that intelligent font substitution can take + place. + +@item SLAN + *Font slant* (ASCII string). Valid values are ``italic`` and ``normal``. + This should be included so that intelligent font substitution can take + place. + +@item PTSZ + *Font point size* (uint16be). + +@item MAXW + *Maximum character width in pixels* (uint16be). + +@item MAXH + *Maximum character height in pixels* (uint16be). + +@item ASCE + *Ascent in pixels* (uint16be). See `Font Metrics`_ for details. + +@item DESC + *Descent in pixels* (uint16be). See `Font Metrics`_ for details. + +@item CHIX + *Character index.* + The character index begins with a 32-bit big-endian unsigned integer + indicating the total size of the section, not including this size value. + For each character, there is an instance of the following entry structure: + + @itemize + @item **Unicode code point.** (32-bit big-endian integer.) + + @item **Storage flags.** (byte.) + + @itemize + @item Bits 2..0: + + - If equal to 000 binary, then the character data is stored + uncompressed beginning at the offset indicated by the character's + *offset* value. + + - If equal to 001 binary, then the character data is stored within a + compressed character definition block that begins at the offset + within the file indicated by the character's *offset* value. + @end itemize + @item **Offset.** (32-bit big-endian integer.) + + A marker that indicates the remainder of the file is data accessed via + the character index (CHIX) section. When reading this font file, the rest + of the file can be ignored when scanning the sections. The length should + be set to -1 (0xFFFFFFFF). + + Supported data structures: + + Character definition + Each character definition consists of: + + @itemize + @item **Width.** Width of the bitmap in pixels. The bitmap's extents + represent the glyph's bounding box. *uint16be*. + + @item **Height.** Height of the bitmap in pixels. The bitmap's extents + represent the glyph's bounding box. *uint16be*. + + @item **X offset.** The number of pixels to shift the bitmap by + horizontally before drawing the character. *int16be*. + + @item **Y offset.** The number of pixels to shift the bitmap by + vertically before drawing the character. *int16be*. + + @item **Device width.** The number of pixels to advance horizontally from + this character's origin to the origin of the next character. + *int16be*. + + @item **Bitmap data.** This is encoded as a string of bits. It is + organized as a row-major, top-down, left-to-right bitmap. The most + significant bit of each byte is taken to be the leftmost or uppermost + bit in the byte. For the sake of compact storage, rows are not padded + to byte boundaries (i.e., a single byte may contain bits belonging to + multiple rows). The last byte of the bitmap *is* padded with zero + bits in the bits positions to the right of the last used bit if the + bitmap data does not fill the last byte. + + The length of the *bitmap data* field is (*width* * *height* + 7) / 8 + using integer arithmetic, which is equivalent to ceil(*width* * + *height* / 8) using real number arithmetic. + + It remains to be determined whether bitmap fonts usually make all + glyph bitmaps the same height, or if smaller glyphs are stored with + bitmaps having a lesser height. In the latter case, the baseline + would have to be used to calculate the location the bitmap should be + anchored at on screen. + @end itemize + + @end itemize +@end table + +@node Font Metrics +@section Font Metrics + +@itemize +@item Ascent. + The distance from the baseline to the top of most characters. + Note that in some cases characters may extend above the ascent. + +@item Descent. + The distance from the baseline to the bottom of most characters. Note that + in some cases characters may extend below the descent. + +@item Leading. + The amount of space, in pixels, to leave between the descent of one line of + text and the ascent of the next line. This metrics is not specified in the + current file format; instead, the font rendering engine calculates a + reasonable leading value based on the other font metrics. + +@item Horizonal leading. + The amount of space, in pixels, to leave horizontally between the left and + right edges of two adjacent glyphs. The *device width* field determines + the effective leading value that is used to render the font. + +@end itemize +@image{font_char_metrics,,,,.png} + + An illustration of how the various font metrics apply to characters. + + + +@node Graphical Menu Software Design +@chapter Graphical Menu Software Design + +@c By Colin D. Bennett +@c Date: 17 August 2008 + +@menu +* Introduction_2:: +* Startup Sequence:: +* GUI Components:: +* Command Line Window:: +@end menu + +@node Introduction_2 +@section Introduction + +The ``gfxmenu`` module provides a graphical menu interface for GRUB 2. It +functions as an alternative to the menu interface provided by the ``normal`` +module, which uses the grub terminal interface to display a menu on a +character-oriented terminal. + +The graphical menu uses the GRUB video API, which is currently for the VESA +BIOS extensions (VBE) 2.0+. This is supported on the i386-pc platform. +However, the graphical menu itself does not depend on using VBE, so if another +GRUB video driver were implemented, the ``gfxmenu`` graphical menu would work +on the new video driver as well. + + +@node Startup Sequence +@section Startup Sequence + +@itemize +@item grub_enter_normal_mode [normal/main.c] +@item grub_normal_execute [normal/main.c] +@item read_config_file [normal/main.c] +@item (When ``gfxmenu.mod`` is loaded with ``insmod``, it will call ``grub_menu_viewer_register()`` to register itself.) +@item GRUB_MOD_INIT (gfxmenu) [gfxmenu/gfxmenu.c] +@item grub_menu_viewer_register [kern/menu_viewer.c] +@item grub_menu_viewer_show_menu [kern/menu_viewer.c] +@item get_current_menu_viewer() [kern/menu_viewer.c] +@item show_menu() [gfxmenu/gfxmenu.c] +@item grub_gfxmenu_model_new [gfxmenu/model.c] +@item grub_gfxmenu_view_new [gfxmenu/view.c] +@item set_graphics_mode [gfxmenu/view.c] +@item grub_gfxmenu_view_load_theme [gfxmenu/theme_loader.c] +@end itemize + + +@node GUI Components +@section GUI Components + +The graphical menu implements a GUI component system that supports a +container-based layout system. Components can be added to containers, and +containers (which are a type of component) can then be added to other +containers, to form a tree of components. Currently, the root component of +this tree is a *canvas* component, which allows manual layout of its child +components. + +Components (non-container): + +@itemize +@item label +@item image +@item progress_bar +@item circular_progress +@item list (currently hard coded to be a boot menu list) +@end itemize + +Containers: + +@itemize +@item canvas +@item hbox +@item vbox +@end itemize + +The GUI component instances are created by the theme loader in +``gfxmenu/theme_loader.c`` when a theme is loaded. Theme files specify +statements such as ``+vbox@{ +label @{ text="Hello" @} +label@{ text="World" @} @}`` +to add components to the component tree root. By nesting the component +creation statements in the theme file, the instantiated components are nested +the same way. + +When a component is added to a container, that new child is considered *owned* +by the container. Great care should be taken if the caller retains a +reference to the child component, since it will be destroyed if its parent +container is destroyed. A better choice instead of storing a pointer to the +child component is to use the component ID to find the desired component. +Component IDs do not have to be unique (it is often useful to have multiple +components with an ID of "__timeout__", for instance). + +In order to access and use components in the component tree, there are two +functions (defined in ``gfxmenu/gui_util.c``) that are particularly useful: + +@itemize + +@item ``grub_gui_find_by_id (root, id, callback, userdata)``: + + This function ecursively traverses the component tree rooted at *root*, and + for every component that has an ID equal to *id*, calls the function pointed + to by *callback* with the matching component and the void pointer *userdata* + as arguments. The callback function can do whatever is desired to use the + component passed in. + +@item ``grub_gui_iterate_recursively (root, callback, userdata)``: + + This function calls the function pointed to by *callback* for every + component that is a descendant of *root* in the component tree. When the + callback function is called, the component and the void pointer *userdata* + as arguments. The callback function can do whatever is desired to use the + component passed in. +@end itemize + +@node Command Line Window +@section Command Line Window + +The terminal window used to provide command line access within the graphical +menu is managed by ``gfxmenu/view.c``. The ``gfxterm`` terminal is used, and +it has been modified to allow rendering to an offscreen render target to allow +it to be composed into the double buffering system that the graphical menu +view uses. This is bad for performance, however, so it would probably be a +good idea to make it possible to temporarily disable double buffering as long +as the terminal window is visible. There are still unresolved problems that +occur when commands are executed from the terminal window that change the +graphics mode. It's possible that making ``grub_video_restore()`` return to +the graphics mode that was in use before ``grub_video_setup()`` was called +might fix some of the problems. + + +@node Copying This Manual +@appendix Copying This Manual + +@menu +* GNU Free Documentation License:: License for copying this manual. +@end menu + +@include fdl.texi + + +@node Index +@unnumbered Index + +@c Currently, we use only the Concept Index. +@printindex cp + +@bye diff --git a/docs/grub.texi b/docs/grub.texi index 0808ded6b..45baeafe6 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -100,7 +100,6 @@ This edition documents version @value{VERSION}. * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB -* Internals:: Hacking GRUB * Copying This Manual:: Copying This Manual * Index:: @end menu @@ -4374,111 +4373,6 @@ If you are interested in the development of GRUB 2, take a look at @uref{http://www.gnu.org/software/grub/grub.html, the homepage}. -@node Internals -@appendix Hacking GRUB - -@menu -* Getting the source code:: -* Finding your way around:: -@end menu - - -@node Getting the source code -@section Getting the source code - -GRUB is maintained using the @uref{http://bazaar-vcs.org/, Bazaar revision -control system}. To fetch the primary development branch: - -@example -bzr get http://bzr.savannah.gnu.org/r/grub/trunk/grub -@end example - -The GRUB developers maintain several other branches with work in progress. -Of these, the most interesting is the experimental branch, which is a -staging area for new code which we expect to eventually merge into trunk but -which is not yet ready: - -@example -bzr get http://bzr.savannah.gnu.org/r/grub/branches/experimental -@end example - -Once you have used @kbd{bzr get} to fetch an initial copy of a branch, you -can use @kbd{bzr pull} to keep it up to date. If you have modified your -local version, you may need to resolve conflicts when pulling. - - -@node Finding your way around -@section Finding your way around - -Here is a brief map of the GRUB code base. - -GRUB uses Autoconf, but not (yet) Automake. The top-level build rules are -in @file{configure.ac}, @file{Makefile.in}, and @file{conf/*.rmk}. Each -@file{conf/*.rmk} file represents a particular target configuration, and is -processed into GNU Make rules by @file{genmk.rb} (which you only need to -look at if you are extending the build system). If you are adding a new -module which follows an existing pattern, such as a new command or a new -filesystem implementation, it is usually easiest to grep @file{conf/*.rmk} -for an existing example of that pattern to find out where it should be -added. - -Low-level boot code, such as the MBR implementation on PC BIOS systems, is -in the @file{boot/} directory. - -The GRUB kernel is in @file{kern/}. This contains core facilities such as -the device, disk, and file frameworks, environment variable handling, list -processing, and so on. The kernel should contain enough to get up to a -rescue prompt. Header files for kernel facilities, among others, are in -@file{include/}. - -Terminal implementations are in @file{term/}. - -Disk access code is spread across @file{disk/} (for accessing the disk -devices themselves), @file{partmap/} (for interpreting partition table -data), and @file{fs/} (for accessing filesystems). Note that, with the odd -specialised exception, GRUB only contains code to @emph{read} from -filesystems and tries to avoid containing any code to @emph{write} to -filesystems; this lets us confidently assure users that GRUB cannot be -responsible for filesystem corruption. - -PCI and USB bus handling is in @file{bus/}. - -Video handling code is in @file{video/}. The graphical menu system uses -this heavily, but is in a separate directory, @file{gfxmenu/}. - -Most commands are implemented by files in @file{commands/}, with the -following exceptions: - -@itemize -@item -A few core commands live in @file{kern/corecmd.c}. - -@item -Commands related to normal mode live under @file{normal/}. - -@item -Commands that load and boot kernels live under @file{loader/}. - -@item -The @samp{loopback} command is really a disk device, and so lives in -@file{disk/loopback.c}. - -@item -The @samp{gettext} command lives under @file{gettext/}. - -@item -The @samp{loadfont} and @samp{lsfonts} commands live under @file{font/}. - -@item -The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands -live under @file{term/}. - -@item -The @samp{efiemu_*} commands live under @file{efiemu/}. -@end itemize - -There are a few other special-purpose exceptions; grep for them if they -matter to you. From 67e11623a8a14414342a396c3d0dce7f774018cf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 3 Apr 2011 15:34:50 +0200 Subject: [PATCH 0799/1414] * docs/grub.texi (Vendor power-on buttons): Explain how the numbers are obtained. --- ChangeLog | 5 +++++ docs/grub.texi | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/ChangeLog b/ChangeLog index 47bb01e7e..129703971 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-02 Vladimir Serbinenko + + * docs/grub.texi (Vendor power-on buttons): Explain how the numbers + are obtained. + 2011-04-02 Vladimir Serbinenko GRUB developper manual based on existing Internals section and diff --git a/docs/grub.texi b/docs/grub.texi index 45baeafe6..0c59975cd 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -2049,6 +2049,44 @@ model-specific. Values known to the GRUB team are: To take full advantage of this function, install GRUB into the MBR (@pxref{Installing GRUB using grub-install}). +If you have a laptop which has a similar feature and not in the above list +could you figure your address and contribute? +To discover the address do the following: +@itemize +@item boot normally +@item +@example +sudo modprobe nvram +sudo cat /dev/nvram | xxd > normal_button.txt +@end example +@item boot using vendor button +@item +@example +sudo modprobe nvram +sudo cat /dev/nvram | xxd > normal_vendor.txt +@end example +@end itemize + +Then compare these text files and find where a bit was toggled. E.g. in +case of Dell XPS it was: +@example +byte 0x47: 20 --> 28 +@end example +It's a bit number 3 as seen from following table: +@multitable @columnfractions .2 .2 +@item 0 @tab 01 +@item 1 @tab 02 +@item 2 @tab 04 +@item 3 @tab 08 +@item 4 @tab 10 +@item 5 @tab 20 +@item 6 @tab 40 +@item 7 @tab 80 +@end multitable + +0x47 is decimal 71. Linux nvram implementation cuts first 14 bytes of +CMOS. So the real byte address in CMOS is 71+14=85 +So complete address is 85:3 @node Images @chapter GRUB image files From 09ceb9a5923c65b1fc6d9f39a5b64f0e2c2373e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 3 Apr 2011 15:37:24 +0200 Subject: [PATCH 0800/1414] * util/grub-install.in: Add a recommendation to use --recheck before reporting bugs. --- ChangeLog | 5 +++++ util/grub-install.in | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 129703971..54a6d6333 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-02 Vladimir Serbinenko + + * util/grub-install.in: Add a recommendation to use --recheck before + reporting bugs. + 2011-04-02 Vladimir Serbinenko * docs/grub.texi (Vendor power-on buttons): Explain how the numbers diff --git a/util/grub-install.in b/util/grub-install.in index 4e78dfadb..ff8bea87c 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -467,7 +467,8 @@ fi fs_module="`"$grub_probe" --device-map="${device_map}" --target=fs --device "${grub_device}"`" if test "x$fs_module" = x ; then echo "Auto-detection of a filesystem of ${grub_device} failed." 1>&2 - echo "Please report this together with the output of \"$grub_probe --device-map=\"${device_map}\" --target=fs -v ${grubdir}\" to " 1>&2 + echo "Try with --recheck." 1>&2 + echo "If the problem persists please report this together with the output of \"$grub_probe --device-map=\"${device_map}\" --target=fs -v ${grubdir}\" to " 1>&2 exit 1 fi From 829ea451a4b26418d1f413eab57a39620cecd95b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 3 Apr 2011 15:45:20 +0200 Subject: [PATCH 0801/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_read): Don't close on failed seek as it breaks open fd reusage. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 54a6d6333..88a8a7f69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-02 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_read): Don't close + on failed seek as it breaks open fd reusage. + 2011-04-02 Vladimir Serbinenko * util/grub-install.in: Add a recommendation to use --recheck before diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index d5b0439fb..50e5a34ad 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -876,7 +876,6 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) { grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device); - close (fd); return grub_errno; } From 6f332153941293db9cb28ecb4cbe323f94134d82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 3 Apr 2011 15:57:44 +0200 Subject: [PATCH 0802/1414] * grub-core/disk/lvm.c (grub_lvm_scan_device): Print errors on the end of function to allow further scanning for LVMs. --- ChangeLog | 5 +++++ grub-core/disk/lvm.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 88a8a7f69..fc6dee2ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-02 Vladimir Serbinenko + + * grub-core/disk/lvm.c (grub_lvm_scan_device): Print errors on the end + of function to allow further scanning for LVMs. + 2011-04-02 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_read): Don't close diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 5a79063da..6b6417f38 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -838,6 +838,7 @@ grub_lvm_scan_device (const char *name) grub_disk_close (disk); if (grub_errno == GRUB_ERR_OUT_OF_RANGE) grub_errno = GRUB_ERR_NONE; + grub_print_error (); return 0; } From 850e937329ab9da72cca06efeb1c10ec2e996a42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 3 Apr 2011 16:28:14 +0200 Subject: [PATCH 0803/1414] Increase LVM implementation robustness in order not to crash on configurations like pvmove. Previously code assumed that in some places only lvs or only pvs are used whereas it seems that they are used interchangeably. * grub-core/disk/lvm.c (read_node): New function. (read_lv): Use read_node. (grub_lvm_scan_device): Use only first mirror on pvmove'd lvs. Match volumes only at the end when all lvs are found. Take both pvs (first) and lvs (second) into account. * include/grub/lvm.h (grub_lvm_segment): Merge fields stripe_* and mirror_* into node_*. All users updated. (grub_lvm_stripe): Merge this ... (grub_lvm_mirror): ... and this ... (grub_lvm_node): ... into this. All users updated. --- ChangeLog | 18 ++++++ grub-core/disk/lvm.c | 144 ++++++++++++++++++++++++------------------- include/grub/lvm.h | 15 ++--- 3 files changed, 103 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index fc6dee2ce..667daad65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2011-04-02 Vladimir Serbinenko + + Increase LVM implementation robustness in order not to crash on + configurations like pvmove. Previously code assumed that in some places + only lvs or only pvs are used whereas it seems that they are used + interchangeably. + + * grub-core/disk/lvm.c (read_node): New function. + (read_lv): Use read_node. + (grub_lvm_scan_device): Use only first mirror on pvmove'd lvs. + Match volumes only at the end when all lvs are found. Take both + pvs (first) and lvs (second) into account. + * include/grub/lvm.h (grub_lvm_segment): Merge fields stripe_* and + mirror_* into node_*. All users updated. + (grub_lvm_stripe): Merge this ... + (grub_lvm_mirror): ... and this ... + (grub_lvm_node): ... into this. All users updated. + 2011-04-02 Vladimir Serbinenko * grub-core/disk/lvm.c (grub_lvm_scan_device): Print errors on the end diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 6b6417f38..00c6d8f9b 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -165,6 +165,31 @@ grub_lvm_close (grub_disk_t disk __attribute ((unused))) return; } +static grub_err_t +read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, + grub_size_t size, char *buf); + +static grub_err_t +read_node (const struct grub_lvm_node *node, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + /* Check whether we actually know the physical volume we want to + read from. */ + if (node->pv) + { + if (node->pv->disk) + return grub_disk_read (node->pv->disk, sector + node->pv->start, 0, + size << GRUB_DISK_SECTOR_BITS, buf); + else + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "physical volume %s not found", node->pv->name); + + } + if (node->lv) + return read_lv (node->lv, sector, size, buf); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown node '%s'", node->name); +} + static grub_err_t read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, grub_size_t size, char *buf) @@ -172,7 +197,7 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, grub_err_t err = 0; struct grub_lvm_vg *vg = lv->vg; struct grub_lvm_segment *seg = lv->segments; - struct grub_lvm_pv *pv; + struct grub_lvm_node *node; grub_uint64_t offset; grub_uint64_t extent; unsigned int i; @@ -200,17 +225,17 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, switch (seg->type) { case GRUB_LVM_STRIPED: - if (seg->stripe_count == 1) + if (seg->node_count == 1) { /* This segment is linear, so that's easy. We just need to find out the offset in the physical volume and read SIZE bytes from that. */ - struct grub_lvm_stripe *stripe = seg->stripes; + struct grub_lvm_node *stripe = seg->nodes; grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ - pv = stripe->pv; + node = stripe; seg_offset = ((grub_uint64_t) stripe->start - * (grub_uint64_t) vg->extent_size) + pv->start; + * (grub_uint64_t) vg->extent_size); offset = sector - ((grub_uint64_t) seg->start_extent * (grub_uint64_t) vg->extent_size) + seg_offset; @@ -219,7 +244,7 @@ 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_stripe *stripe = seg->stripes; + struct grub_lvm_node *stripe = seg->nodes; grub_uint32_t a, b; grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ unsigned int stripenr; @@ -228,42 +253,29 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, * (grub_uint64_t) vg->extent_size); a = grub_divmod64 (offset, seg->stripe_size, NULL); - grub_divmod64 (a, seg->stripe_count, &stripenr); + grub_divmod64 (a, seg->node_count, &stripenr); - a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL); + a = grub_divmod64 (offset, seg->stripe_size * seg->node_count, NULL); grub_divmod64 (offset, seg->stripe_size, &b); offset = a * seg->stripe_size + b; stripe += stripenr; - pv = stripe->pv; + node = stripe; seg_offset = ((grub_uint64_t) stripe->start - * (grub_uint64_t) vg->extent_size) + pv->start; + * (grub_uint64_t) vg->extent_size); offset += seg_offset; } - /* Check whether we actually know the physical volume we want to - read from. */ - if (pv->disk) - err = grub_disk_read (pv->disk, offset, 0, - size << GRUB_DISK_SECTOR_BITS, buf); - else - err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "physical volume %s not found", pv->name); - - return err; + return read_node (node, offset, size, buf); case GRUB_LVM_MIRROR: i = 0; while (1) { - if (!seg->mirrors[i].lv) - err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume '%s'", - seg->mirrors[i].lvname); - else - err = read_lv (seg->mirrors[i].lv, sector, size, buf); + err = read_node (&seg->nodes[i], sector, size, buf); if (!err) return err; - if (++i >= seg->mirror_count) + if (++i >= seg->node_count) return err; grub_errno = GRUB_ERR_NONE; } @@ -544,6 +556,7 @@ grub_lvm_scan_device (const char *name) int skip_lv = 0; struct grub_lvm_lv *lv; struct grub_lvm_segment *seg; + int is_pvmove; while (grub_isspace (*p)) p++; @@ -567,6 +580,7 @@ grub_lvm_scan_device (const char *name) lv->size = 0; lv->visible = grub_lvm_check_flag (p, "status", "VISIBLE"); + is_pvmove = grub_lvm_check_flag (p, "status", "PVMOVE"); lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); if (p == NULL) @@ -618,10 +632,10 @@ grub_lvm_scan_device (const char *name) if (grub_memcmp (p, "striped\"", sizeof ("striped\"") - 1) == 0) { - struct grub_lvm_stripe *stripe; + struct grub_lvm_node *stripe; seg->type = GRUB_LVM_STRIPED; - seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); + seg->node_count = grub_lvm_getvalue (&p, "stripe_count = "); if (p == NULL) { #ifdef GRUB_UTIL @@ -630,12 +644,12 @@ grub_lvm_scan_device (const char *name) goto lvs_segment_fail; } - if (seg->stripe_count != 1) + if (seg->node_count != 1) seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); - seg->stripes = grub_malloc (sizeof (*stripe) - * seg->stripe_count); - stripe = seg->stripes; + seg->nodes = grub_zalloc (sizeof (*stripe) + * seg->node_count); + stripe = seg->nodes; p = grub_strstr (p, "stripes = ["); if (p == NULL) @@ -647,10 +661,8 @@ grub_lvm_scan_device (const char *name) } p += sizeof("stripes = [") - 1; - for (j = 0; j < seg->stripe_count; j++) + for (j = 0; j < seg->node_count; j++) { - char *pvname; - p = grub_strchr (p, '"'); if (p == NULL) continue; @@ -660,24 +672,12 @@ grub_lvm_scan_device (const char *name) s = q - p; - pvname = grub_malloc (s + 1); - if (pvname == NULL) + stripe->name = grub_malloc (s + 1); + if (stripe->name == NULL) goto lvs_segment_fail2; - grub_memcpy (pvname, p, s); - pvname[s] = '\0'; - - if (vg->pvs) - for (pv = vg->pvs; pv; pv = pv->next) - { - if (! grub_strcmp (pvname, pv->name)) - { - stripe->pv = pv; - break; - } - } - - grub_free(pvname); + grub_memcpy (stripe->name, p, s); + stripe->name[s] = '\0'; stripe->start = grub_lvm_getvalue (&p, ","); if (p == NULL) @@ -690,7 +690,7 @@ grub_lvm_scan_device (const char *name) == 0) { seg->type = GRUB_LVM_MIRROR; - seg->mirror_count = grub_lvm_getvalue (&p, "mirror_count = "); + seg->node_count = grub_lvm_getvalue (&p, "mirror_count = "); if (p == NULL) { #ifdef GRUB_UTIL @@ -699,8 +699,8 @@ grub_lvm_scan_device (const char *name) goto lvs_segment_fail; } - seg->mirrors = grub_zalloc (sizeof (seg->mirrors[0]) - * seg->mirror_count); + seg->nodes = grub_zalloc (sizeof (seg->nodes[0]) + * seg->node_count); p = grub_strstr (p, "mirrors = ["); if (p == NULL) @@ -712,7 +712,7 @@ grub_lvm_scan_device (const char *name) } p += sizeof("mirrors = [") - 1; - for (j = 0; j < seg->mirror_count; j++) + for (j = 0; j < seg->node_count; j++) { char *lvname; @@ -731,9 +731,12 @@ grub_lvm_scan_device (const char *name) grub_memcpy (lvname, p, s); lvname[s] = '\0'; - seg->mirrors[j].lvname = lvname; + seg->nodes[j].name = lvname; p = q + 1; } + /* Only first (original) is ok with in progress pvmove. */ + if (is_pvmove) + seg->node_count = 1; } else { @@ -755,7 +758,7 @@ grub_lvm_scan_device (const char *name) continue; lvs_segment_fail2: - grub_free (seg->stripes); + grub_free (seg->nodes); lvs_segment_fail: goto fail4; } @@ -786,18 +789,31 @@ grub_lvm_scan_device (const char *name) } } - /* Match mirrors */ + /* Match lvs. */ { struct grub_lvm_lv *lv1; struct grub_lvm_lv *lv2; for (lv1 = vg->lvs; lv1; lv1 = lv1->next) for (i = 0; i < lv1->segment_count; i++) - if (lv1->segments[i].type == GRUB_LVM_MIRROR) - for (j = 0; j < lv1->segments[i].mirror_count; j++) - for (lv2 = vg->lvs; lv2; lv2 = lv2->next) - if (grub_strcmp (lv2->name + grub_strlen (vg->name) + 1, - lv1->segments[i].mirrors[j].lvname) == 0) - lv1->segments[i].mirrors[j].lv = lv2; + for (j = 0; j < lv1->segments[i].node_count; j++) + { + if (vg->pvs) + for (pv = vg->pvs; pv; pv = pv->next) + { + if (! grub_strcmp (pv->name, + lv1->segments[i].nodes[j].name)) + { + lv1->segments[i].nodes[j].pv = pv; + break; + } + } + if (lv1->segments[i].nodes[j].pv == NULL) + for (lv2 = vg->lvs; lv2; lv2 = lv2->next) + if (grub_strcmp (lv2->name + grub_strlen (vg->name) + 1, + lv1->segments[i].nodes[j].name) == 0) + lv1->segments[i].nodes[j].lv = lv2; + } + } vg->next = vg_list; diff --git a/include/grub/lvm.h b/include/grub/lvm.h index 220517183..b962dfd6c 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -60,21 +60,16 @@ struct grub_lvm_segment { unsigned int extent_count; enum { GRUB_LVM_STRIPED, GRUB_LVM_MIRROR } type; - unsigned int mirror_count; - struct grub_lvm_mirror *mirrors; + unsigned int node_count; + struct grub_lvm_node *nodes; - unsigned int stripe_count; unsigned int stripe_size; - struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */ }; -struct grub_lvm_stripe { - int start; +struct grub_lvm_node { + grub_disk_addr_t start; + char *name; struct grub_lvm_pv *pv; -}; - -struct grub_lvm_mirror { - char *lvname; struct grub_lvm_lv *lv; }; From 6ac14e6cef8b3dc675fc09239b2101dcc4393a18 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Apr 2011 09:34:58 +0200 Subject: [PATCH 0804/1414] Fix EFI compilation --- grub-core/disk/efi/efidisk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 20fea956f..1bf764f10 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -537,11 +537,11 @@ grub_efidisk_open (const char *name, struct grub_disk *disk) grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n", m, (unsigned long long) m->last_block, m->block_size); disk->total_sectors = m->last_block; - if (m->blocksize & (m->blocksize - 1) || !m->blocksize) + if (m->block_size & (m->block_size - 1) || !m->block_size) return grub_error (GRUB_ERR_IO, "invalid sector size %d", - m->blocksize); + m->block_size); for (disk->log_sector_size = 0; - (1 << disk->log_sector_size) < m->blocksize; + (1U << disk->log_sector_size) < m->block_size; disk->log_sector_size++); disk->data = d; From b38a4983949bbf66a7ecdae3423b2401ce2e635f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Apr 2011 14:40:15 +0200 Subject: [PATCH 0805/1414] 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 0806/1414] 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 246c23696a24dd3e971a9b29b7ee25c905d6ba63 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Apr 2011 12:25:33 +0200 Subject: [PATCH 0807/1414] Ignore docs/stamp-1 and docs/version-dev.texi --- .bzrignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.bzrignore b/.bzrignore index a3e6f9dd2..55cbdaeeb 100644 --- a/.bzrignore +++ b/.bzrignore @@ -133,3 +133,5 @@ grub-core/gnulib/wctype.h grub-core/rs_decoder.S widthspec.bin widthspec.h +docs/stamp-1 +docs/version-dev.texi From a562b47916eef29b39ed23115b7bf9af6e3bd179 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Apr 2011 12:29:49 +0200 Subject: [PATCH 0808/1414] * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Detect spares and report them as not RAID members since they are useless for GRUB. * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/mdraid1x_linux.c | 5 ++++- grub-core/disk/mdraid_linux.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 667daad65..81ba177d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-06 Vladimir Serbinenko + + * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Detect spares + and report them as not RAID members since they are useless for GRUB. + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. + 2011-04-02 Vladimir Serbinenko Increase LVM implementation robustness in order not to crash on diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index 1d08abf5b..e30878365 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -200,11 +200,14 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, if (grub_le_to_cpu32 (real_sb->dev_number) >= grub_le_to_cpu32 (real_sb->max_dev)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + return grub_error (GRUB_ERR_OUT_OF_RANGE, "spares aren't implemented"); array->index = grub_le_to_cpu16 (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]); + if (array->index >= array->total_devs) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "spares aren't implemented"); array->uuid_len = 16; array->uuid = grub_malloc (16); if (!array->uuid) diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index 7aa48fd7a..06d3498a8 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -202,7 +202,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, "unsupported RAID level: %d", level); if (grub_le_to_cpu32 (sb.this_disk.number) == 0xffff || grub_le_to_cpu32 (sb.this_disk.number) == 0xfffe) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + return grub_error (GRUB_ERR_OUT_OF_RANGE, "spares aren't implemented"); array->name = NULL; From 665900a3892d554c7bcafdfefcff027da35ad709 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Apr 2011 12:33:46 +0200 Subject: [PATCH 0809/1414] * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Let a bit more space for older compilers. (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. --- ChangeLog | 6 ++++++ include/grub/offsets.h | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81ba177d5..a657807bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-06 Vladimir Serbinenko + + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Let a bit more + space for older compilers. + (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. + 2011-04-06 Vladimir Serbinenko * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Detect spares diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 817372b69..31deb5031 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -38,9 +38,9 @@ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x1c /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xca4 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xcd0 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x70c +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x730 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE From adf594cc44418f7d3e7801b677c73ed93b848129 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Apr 2011 13:00:18 +0200 Subject: [PATCH 0810/1414] Output errors if theme loading failed. * grub-core/gfxmenu/gfxmenu.c (grub_gfxmenu_try): Move the call to grub_gfxterm_fullscreen on error paths to ... * grub-core/normal/menu.c (menu_init): ...here. Wait after showing theme loading error. --- ChangeLog | 9 ++++++++ grub-core/gfxmenu/gfxmenu.c | 24 +++------------------- grub-core/normal/menu.c | 41 ++++++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index a657807bd..891853f71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-06 Vladimir Serbinenko + + Output errors if theme loading failed. + + * grub-core/gfxmenu/gfxmenu.c (grub_gfxmenu_try): Move the call to + grub_gfxterm_fullscreen on error paths to ... + * grub-core/normal/menu.c (menu_init): ...here. Wait after showing + theme loading error. + 2011-04-06 Vladimir Serbinenko * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Let a bit more diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c index 76d83c44b..564a87634 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/grub-core/gfxmenu/gfxmenu.c @@ -56,30 +56,15 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) theme_path = grub_env_get ("theme"); if (! theme_path) - { - grub_error_push (); - grub_gfxterm_fullscreen (); - grub_error_pop (); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified"); - } + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified"); instance = grub_zalloc (sizeof (*instance)); if (!instance) - { - grub_error_push (); - grub_gfxterm_fullscreen (); - grub_error_pop (); - return grub_errno; - } + return grub_errno; err = grub_video_get_info (&mode_info); if (err) - { - grub_error_push (); - grub_gfxterm_fullscreen (); - grub_error_pop (); - return err; - } + return err; if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0 || cached_view->screen.width != mode_info.width @@ -94,9 +79,6 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) if (! cached_view) { grub_free (instance); - grub_error_push (); - grub_gfxterm_fullscreen (); - grub_error_pop (); return grub_errno; } diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index e62482122..bfcdd0ac5 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ @@ -345,18 +346,44 @@ static void menu_init (int entry, grub_menu_t menu, int nested) { struct grub_term_output *term; + int gfxmenu = 0; + + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (term->name, "gfxterm") == 0) + { + if (grub_env_get ("theme")) + { + if (!grub_gfxmenu_try_hook) + { + grub_dl_load ("gfxmenu"); + grub_print_error (); + } + if (grub_gfxmenu_try_hook) + { + grub_err_t err; + err = grub_gfxmenu_try_hook (entry, menu, nested); + if(!err) + { + gfxmenu = 1; + break; + } + } + else + grub_error (GRUB_ERR_BAD_MODULE, "no gfxmenu found"); + grub_print_error (); + grub_wait_after_message (); + } + grub_errno = GRUB_ERR_NONE; + grub_gfxterm_fullscreen (); + break; + } FOR_ACTIVE_TERM_OUTPUTS(term) { grub_err_t err; - if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0) - { - err = grub_gfxmenu_try_hook (entry, menu, nested); - if(!err) - continue; - grub_errno = GRUB_ERR_NONE; - } + if (grub_strcmp (term->name, "gfxterm") == 0 && gfxmenu) + break; err = grub_menu_try_text (term, entry, menu, nested); if(!err) From 2a961775e6ef522a47eaf898806d2f5de785e46e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Apr 2011 13:18:11 +0200 Subject: [PATCH 0811/1414] * util/grub.d/00_header.in: Don't use LANG unless unifont is available. --- ChangeLog | 4 ++++ util/grub.d/00_header.in | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 891853f71..bc9318701 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-06 Vladimir Serbinenko + + * util/grub.d/00_header.in: Don't use LANG unless unifont is available. + 2011-04-06 Vladimir Serbinenko Output errors if theme loading failed. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 420b3f32c..9da1511f5 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -132,6 +132,19 @@ if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT_PATH}"` ; then set gfxmode=${GRUB_GFXMODE} load_video insmod gfxterm +EOF + +# Gettext variables and module +if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then + prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) | sed -e "s/^/ /" + cat << EOF + set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) + set lang=${grub_lang} + insmod gettext +EOF +fi + +cat < Date: Wed, 6 Apr 2011 14:01:12 +0200 Subject: [PATCH 0812/1414] * include/grub/fs.h (grub_dirhook_info): Use unsigned for 1-bit fields. --- ChangeLog | 4 ++++ include/grub/fs.h | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc9318701..84fcc5627 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-06 Vladimir Serbinenko + + * include/grub/fs.h (grub_dirhook_info): Use unsigned for 1-bit fields. + 2011-04-06 Vladimir Serbinenko * util/grub.d/00_header.in: Don't use LANG unless unifont is available. diff --git a/include/grub/fs.h b/include/grub/fs.h index 994eb8080..2c39332a9 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -31,9 +31,9 @@ struct grub_file; struct grub_dirhook_info { - int dir:1; - int mtimeset:1; - int case_insensitive:1; + unsigned dir:1; + unsigned mtimeset:1; + unsigned case_insensitive:1; grub_int32_t mtime; }; From 7755f66e64f52e4c551c477dcdfd4f4a9fdd8f74 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Apr 2011 14:04:52 +0200 Subject: [PATCH 0813/1414] * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align): Add few useful grub_dprintf's. --- ChangeLog | 5 +++++ grub-core/lib/relocator.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 84fcc5627..b110a9803 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-06 Vladimir Serbinenko + + * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align): Add few + useful grub_dprintf's. + 2011-04-06 Vladimir Serbinenko * include/grub/fs.h (grub_dirhook_info): Use unsigned for 1-bit fields. diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 940b9133b..3642de9dc 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -1416,11 +1416,17 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, break; } + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + if (chunk->src < chunk->target) rel->relocators_size += grub_relocator_backward_size; if (chunk->src > chunk->target) rel->relocators_size += grub_relocator_forward_size; + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + chunk->size = size; chunk->next = rel->chunks; rel->chunks = chunk; From b5ebecfabc1037532c18b42372218d45b237f192 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 6 Apr 2011 14:21:34 +0200 Subject: [PATCH 0814/1414] * grub-core/video/fb/video_fb.c (grub_video_fb_setup): Silence older gcc warning. --- ChangeLog | 5 +++++ grub-core/video/fb/video_fb.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b110a9803..e495fbf9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-06 Andrey + + * grub-core/video/fb/video_fb.c (grub_video_fb_setup): Silence older + gcc warning. + 2011-04-06 Vladimir Serbinenko * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align): Add few diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c index 768b63328..2226d6583 100644 --- a/grub-core/video/fb/video_fb.c +++ b/grub-core/video/fb/video_fb.c @@ -1445,13 +1445,16 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 0)) { + /* It was much nicer with the cast directly at function call but + some older gcc versions don't accept it properly.*/ + void *tmp = (void *) page0_ptr; mode_info->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target, &framebuffer.back_target, *mode_info, - (void *) page0_ptr); + tmp); if (!err) { From b0bfc5937d6232c01dbb44f7ad3135eb5aa07ff8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 10:31:32 +0100 Subject: [PATCH 0815/1414] fix header comment --- util/grub-mount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index 7f0ad0d0f..c1c7ecad8 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -1,4 +1,4 @@ -/* grub-fstest.c - debug tool for filesystem driver */ +/* grub-mount.c - FUSE driver for filesystems that GRUB understands */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. From 9aa6fcc17e7b7d6e1712a0cc400c39b44a6e6a72 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 10:38:41 +0100 Subject: [PATCH 0816/1414] fix duplicate --enable-grub-mkfont option; this should be --enable-grub-fuse instead --- configure.ac | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index b71aea910..12ac0e917 100644 --- a/configure.ac +++ b/configure.ac @@ -856,11 +856,11 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) -AC_ARG_ENABLE([grub-mkfont], - [AS_HELP_STRING([--enable-grub-mkfont], - [build and install the `grub-mkfont' utility (default=guessed)])]) -if test x"$enable_grub_mkfont" = xno ; then - grub_mkfont_excuse="explicitly disabled" +AC_ARG_ENABLE([grub-fuse], + [AS_HELP_STRING([--enable-grub-fuse], + [build and install the `grub-fuse' utility (default=guessed)])]) +if test x"$enable_grub_fuse" = xno ; then + grub_fuse_excuse="explicitly disabled" fi if test x"$grub_fuse_excuse" = x ; then From 897e62079e0bab32f089a44b791116493d34ef45 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 10:43:12 +0100 Subject: [PATCH 0817/1414] rename grub-fuse to grub-mount throughout configuration --- Makefile.util.def | 2 +- configure.ac | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 3009ff76a..cd37d0d65 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -224,7 +224,7 @@ program = { ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)' '-lfuse'; - condition = COND_GRUB_FUSE; + condition = COND_GRUB_MOUNT; }; program = { diff --git a/configure.ac b/configure.ac index 12ac0e917..d1eaa0c84 100644 --- a/configure.ac +++ b/configure.ac @@ -856,36 +856,36 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) -AC_ARG_ENABLE([grub-fuse], - [AS_HELP_STRING([--enable-grub-fuse], - [build and install the `grub-fuse' utility (default=guessed)])]) -if test x"$enable_grub_fuse" = xno ; then - grub_fuse_excuse="explicitly disabled" +AC_ARG_ENABLE([grub-mount], + [AS_HELP_STRING([--enable-grub-mount], + [build and install the `grub-mount' utility (default=guessed)])]) +if test x"$enable_grub_mount" = xno ; then + grub_mount_excuse="explicitly disabled" fi -if test x"$grub_fuse_excuse" = x ; then +if test x"$grub_mount_excuse" = x ; then AC_CHECK_LIB([fuse], [fuse_main_real], [], - [grub_fuse_excuse="need FUSE library"]) + [grub_mount_excuse="need FUSE library"]) fi -if test x"$grub_fuse_excuse" = x ; then +if test x"$grub_mount_excuse" = x ; then # Check for fuse headers. SAVED_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" AC_CHECK_HEADERS([fuse/fuse.h], [], - [grub_fuse_excuse=["need FUSE headers"]]) + [grub_mount_excuse=["need FUSE headers"]]) CPPFLAGS="$SAVED_CPPFLAGS" fi -if test x"$enable_grub_fuse" = xyes && test x"$grub_fuse_excuse" != x ; then +if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled]) fi -if test x"$grub_fuse_excuse" = x ; then -enable_grub_fuse=yes +if test x"$grub_mount_excuse" = x ; then +enable_grub_mount=yes else -enable_grub_fuse=no +enable_grub_mount=no fi -AC_SUBST([enable_grub_fuse]) +AC_SUBST([enable_grub_mount]) AC_ARG_ENABLE([device-mapper], [AS_HELP_STRING([--enable-device-mapper], @@ -983,7 +983,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) -AM_CONDITIONAL([COND_GRUB_FUSE], [test x$enable_grub_fuse = xyes]) +AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) @@ -1059,10 +1059,10 @@ echo grub-mkfont: Yes else echo grub-mkfont: No "($grub_mkfont_excuse)" fi -if [ x"$grub_fuse_excuse" = x ]; then +if [ x"$grub_mount_excuse" = x ]; then echo grub-mount: Yes else -echo grub-mount: No "($grub_fuse_excuse)" +echo grub-mount: No "($grub_mount_excuse)" fi echo "*******************************************************" ] From 72a89a54e170ccccf0dd6bd83aaba16692a19ebc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 11:44:44 +0200 Subject: [PATCH 0818/1414] * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Add missing const attribute and use grub_isdigit. --- ChangeLog | 5 +++++ grub-core/kern/emu/getroot.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e495fbf9a..1c4bbb5ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Add missing + const attribute and use grub_isdigit. + 2011-04-06 Andrey * grub-core/video/fb/video_fb.c (grub_video_fb_setup): Silence older diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index ae066d2f8..8f65d92c5 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -808,10 +808,10 @@ grub_util_get_grub_dev (const char *os_dev) if (mdadm_name) { char *newname; - char *q; + const char *q; - for (q = os_dev + strlen (os_dev) - 1; q >= os_dev && isdigit (*q); - q--); + for (q = os_dev + strlen (os_dev) - 1; q >= os_dev + && grub_isdigit (*q); q--); if (q >= os_dev && *q == 'p') { From 478182a83841c912996558900469d34832f8bd2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 11:49:38 +0200 Subject: [PATCH 0819/1414] * grub-core/kern/emu/hostdisk.c (open_device): Sync on close and not on open. (grub_util_biosdisk_close): Likewise. --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 38 ++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c4bbb5ab..a9aaa81c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (open_device): Sync on close and not + on open. + (grub_util_biosdisk_close): Likewise. + 2011-04-08 Vladimir Serbinenko * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Add missing diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 50e5a34ad..7b034e06b 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -664,7 +664,17 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { free (data->dev); if (data->fd != -1) - close (data->fd); + { + if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) + { + fsync (data->fd); +#ifdef __linux__ + ioctl (data->fd, BLKFLSBUF, 0); +#endif + } + + close (data->fd); + } /* Open the partition. */ grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); @@ -675,10 +685,6 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) return -1; } - /* Flush the buffer cache to the physical disk. - XXX: This also empties the buffer cache. */ - ioctl (fd, BLKFLSBUF, 0); - data->dev = xstrdup (dev); data->access_mode = (flags & O_ACCMODE); data->fd = fd; @@ -716,7 +722,16 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { free (data->dev); if (data->fd != -1) - close (data->fd); + { + if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) + { + fsync (data->fd); +#ifdef __linux__ + ioctl (data->fd, BLKFLSBUF, 0); +#endif + } + close (data->fd); + } fd = open (map[disk->id].device, flags); if (fd >= 0) @@ -932,7 +947,16 @@ grub_util_biosdisk_close (struct grub_disk *disk) free (data->dev); if (data->fd != -1) - close (data->fd); + { + if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) + { + fsync (data->fd); +#ifdef __linux__ + ioctl (data->fd, BLKFLSBUF, 0); +#endif + } + close (data->fd); + } free (data); } From 6d1fa41fb413050d4c7fe6c9b224c655e53b4917 Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Fri, 8 Apr 2011 11:53:17 +0200 Subject: [PATCH 0820/1414] * util/grub-mkconfig.in: Ignore emacsen backup. --- ChangeLog | 4 ++++ util/grub-mkconfig.in | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index a9aaa81c1..cce7aa483 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-08 Martin Zuther + + * util/grub-mkconfig.in: Ignore emacsen backup. + 2011-04-08 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (open_device): Sync on close and not diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index b041a38d7..afc66f886 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -280,6 +280,8 @@ for i in ${grub_mkconfig_dir}/* ; do case "$i" in # emacsen backup files. FIXME: support other editors *~) ;; + # emacsen autosave files. FIXME: support other editors + \#*\#) ;; *) if grub_file_is_not_garbage "$i" && test -x "$i" ; then echo From 3c0e3f142abf1f336eccc8fbe27e44062b7bcdfc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 12:06:55 +0200 Subject: [PATCH 0821/1414] * grub-core/disk/raid.c [GRUB_UTIL]: Add missing include. --- ChangeLog | 4 ++++ grub-core/disk/raid.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index cce7aa483..9c2b6a959 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/disk/raid.c [GRUB_UTIL]: Addmissing include. + 2011-04-08 Martin Zuther * util/grub-mkconfig.in: Ignore emacsen backup. diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index c89ca62a1..ac2b9fefe 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -23,6 +23,9 @@ #include #include #include +#ifdef GRUB_UTIL +#include +#endif /* Linked list of RAID arrays. */ static struct grub_raid_array *array_list; From f7148863eb5ae162281d8ff79500dfad77974d08 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 12:12:02 +0200 Subject: [PATCH 0822/1414] * grub-core/normal/menu.c: Add missing include. --- ChangeLog | 6 +++++- grub-core/normal/menu.c | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9c2b6a959..7b247ca81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ 2011-04-08 Vladimir Serbinenko - * grub-core/disk/raid.c [GRUB_UTIL]: Addmissing include. + * grub-core/normal/menu.c: Add missing include. + +2011-04-08 Vladimir Serbinenko + + * grub-core/disk/raid.c [GRUB_UTIL]: Add missing include. 2011-04-08 Martin Zuther diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index bfcdd0ac5..5844cb2f0 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ From 947aa4f886767d0da7a00418672ded6cc4fb52e2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 12:13:44 +0200 Subject: [PATCH 0823/1414] * grub-core/Makefile.am: Properly escape parenthesis in sed expressions. Fixes Estonian locale. Reported by: Leho Kraav. --- ChangeLog | 6 ++++++ grub-core/Makefile.am | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b247ca81..fd5cadae5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/Makefile.am: Properly escape parenthesis in sed expressions. + Fixes Estonian locale. + Reported by: Leho Kraav. + 2011-04-08 Vladimir Serbinenko * grub-core/normal/menu.c: Add missing include. diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 94f7f3ffe..9e0ca7cc3 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -200,8 +200,8 @@ noinst_DATA += kernel_syms.lst kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_FUNC *\([a-zA-Z0-9_]*\)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_VAR *\([a-zA-Z0-9_]*\)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ | sort -u >$@ rm -f kernel_syms.input CLEANFILES += kernel_syms.lst From f387685926dc0dedfa8eace8a76955c845e25a84 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 11:45:10 +0100 Subject: [PATCH 0824/1414] remove trailing full stop, for consistency with other pages --- docs/man/grub-mount.h2m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m index 73e7246a3..8d168982d 100644 --- a/docs/man/grub-mount.h2m +++ b/docs/man/grub-mount.h2m @@ -1,2 +1,2 @@ [NAME] -grub-mount \- export GRUB filesystem with FUSE. +grub-mount \- export GRUB filesystem with FUSE From cb180fdf06a03ad159b83915572ea60f32073053 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 13:18:27 +0200 Subject: [PATCH 0825/1414] revert last revision. It's ineffective --- ChangeLog | 6 ------ grub-core/Makefile.am | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd5cadae5..7b247ca81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,3 @@ -2011-04-08 Vladimir Serbinenko - - * grub-core/Makefile.am: Properly escape parenthesis in sed expressions. - Fixes Estonian locale. - Reported by: Leho Kraav. - 2011-04-08 Vladimir Serbinenko * grub-core/normal/menu.c: Add missing include. diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 9e0ca7cc3..94f7f3ffe 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -200,8 +200,8 @@ noinst_DATA += kernel_syms.lst kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *\([a-zA-Z0-9_]*\)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ - -e '/EXPORT_VAR *\([a-zA-Z0-9_]*\)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ | sort -u >$@ rm -f kernel_syms.input CLEANFILES += kernel_syms.lst From 18dd6b472d1ef7799d83c0bd7df823dc8f45133d Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Fri, 8 Apr 2011 13:57:56 +0200 Subject: [PATCH 0826/1414] * autogen.sh: Ensure that collate and ctype locale is C. * conf/Makefile.common: Likeiwise. Also-By: Colin Watson --- ChangeLog | 6 ++++++ autogen.sh | 4 ++++ conf/Makefile.common | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7b247ca81..1820e3306 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-08 Vladimir Serbinenko +2011-04-08 Colin Watson + + * autogen.sh: Ensure that collate and ctype locale is C. + * conf/Makefile.common: Likeiwise. + 2011-04-08 Vladimir Serbinenko * grub-core/normal/menu.c: Add missing include. diff --git a/autogen.sh b/autogen.sh index 96b1e33e2..d14707aad 100755 --- a/autogen.sh +++ b/autogen.sh @@ -2,6 +2,10 @@ set -e +export LC_CTYPE=C +export LC_COLLATE=C +unset LC_ALL + autogen --version >/dev/null || exit 1 echo "Importing unicode..." diff --git a/conf/Makefile.common b/conf/Makefile.common index 32ca76d08..5aa13cdd6 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -2,6 +2,10 @@ CFLAGS_PLATFORM= +export LC_COLLATE := C +export LC_CTYPE := C +unexport LC_ALL + # Platform specific options if COND_i386_pc CFLAGS_PLATFORM += -mrtd -mregparm=3 From 4ed4ce5820f74eb1f908ba8cef90aba743ce3bd9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 13:59:07 +0200 Subject: [PATCH 0827/1414] correct Changelog spelling --- ChangeLog | 2 +- grub-core/loader/i386/multiboot_mbi.c | 2 +- include/grub/efiemu/efiemu.h | 5 ++--- include/grub/util/raid.h | 2 +- util/grub-setup.c | 10 +++++++++- util/raid.c | 13 +++---------- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1820e3306..e8b2bf0e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ 2011-04-08 Colin Watson * autogen.sh: Ensure that collate and ctype locale is C. - * conf/Makefile.common: Likeiwise. + * conf/Makefile.common: Likewise. 2011-04-08 Vladimir Serbinenko diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 14db50bcd..bef534296 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -435,7 +435,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) bufsize = grub_multiboot_get_mbi_size (); err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, - 0, 0xffffffff - bufsize, + 0x10000, 0x100000 - bufsize, bufsize, 4, GRUB_RELOCATOR_PREFERENCE_NONE); if (err) diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index 8eee98b61..9cedc3226 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -21,6 +21,7 @@ #include #include +#include #define GRUB_EFIEMU_PAGESIZE 4096 @@ -227,9 +228,7 @@ grub_efiemu_finish_boot_services (grub_efi_uintn_t *memory_map_size, grub_efi_uint32_t *descriptor_version); grub_err_t -grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)); +grub_efiemu_mmap_iterate (grub_memory_hook_t hook); int grub_efiemu_sizeof_uintn_t (void); grub_err_t grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper); diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h index 67020bb86..4da5eaaa8 100644 --- a/include/grub/util/raid.h +++ b/include/grub/util/raid.h @@ -21,7 +21,7 @@ #define GRUB_RAID_UTIL_HEADER 1 #ifdef __linux__ -char** grub_util_raid_getmembers (char *name); +char** grub_util_raid_getmembers (const char *name); #endif #endif /* ! GRUB_RAID_UTIL_HEADER */ diff --git a/util/grub-setup.c b/util/grub-setup.c index c1f2a1f5e..ed2d63fdd 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -973,7 +973,15 @@ main (int argc, char *argv[]) char **devicelist; int i; - devicelist = grub_util_raid_getmembers (dest_dev); + if (arguments.device[0] == '/') + devicelist = grub_util_raid_getmembers (arguments.device); + else + { + char *devname; + devname = xasprintf ("/dev/%s", dest_dev); + devicelist = grub_util_raid_getmembers (dest_dev); + free (devname); + } for (i = 0; devicelist[i]; i++) { diff --git a/util/raid.c b/util/raid.c index dac19a935..a6aa5f95e 100644 --- a/util/raid.c +++ b/util/raid.c @@ -36,25 +36,18 @@ #include char ** -grub_util_raid_getmembers (char *name) +grub_util_raid_getmembers (const char *name) { int fd, ret, i, j; - char *devname; char **devicelist; mdu_version_t version; mdu_array_info_t info; mdu_disk_info_t disk; - devname = xmalloc (strlen (name) + 6); - strcpy (devname, "/dev/"); - strcpy (devname+5, name); - - fd = open (devname, O_RDONLY); + fd = open (name, O_RDONLY); if (fd == -1) - grub_util_error ("can't open %s: %s", devname, strerror (errno)); - - free (devname); + grub_util_error ("can't open %s: %s", name, strerror (errno)); ret = ioctl (fd, RAID_VERSION, &version); if (ret != 0) From 7a3d6cd97bd2f047ce93a6dab1c3094cd0d2eaf8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:02:27 +0200 Subject: [PATCH 0828/1414] * include/grub/efiemu/efiemu.h: Use grub_memory_hook_t type. --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index e8b2bf0e7..df08adb93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-08 Vladimir Serbinenko + + * include/grub/efiemu/efiemu.h: Use grub_memory_hook_t type. + 2011-04-08 Vladimir Serbinenko 2011-04-08 Colin Watson From 10a7a86703946b5f09cff96206a793a6beb449ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:04:24 +0200 Subject: [PATCH 0829/1414] * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): Place mbi on low memory for better compatibility. --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index df08adb93..a0ed27b06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): + Place mbi on low memory for better compatibility. + 2011-04-08 Vladimir Serbinenko * include/grub/efiemu/efiemu.h: Use grub_memory_hook_t type. From 2e335e901cd0f45e9610c6441154f9d7a415b1d4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:08:55 +0200 Subject: [PATCH 0830/1414] * include/grub/util/raid.h (grub_util_raid_getmembers): Make argument const. * util/grub-setup.c (main): Reuse md device name if available. * util/raid.c (grub_util_raid_getmembers): Receive device name and not GRUB name as argument. Based on patch by: Florian Wagner . --- ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index a0ed27b06..fdce6dfe0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-08 Vladimir Serbinenko + + * include/grub/util/raid.h (grub_util_raid_getmembers): Make argument + const. + * util/grub-setup.c (main): Reuse md device name if available. + * util/raid.c (grub_util_raid_getmembers): Receive device name and + not GRUB name as argument. + Based on patch by: Florian Wagner . + 2011-04-08 Vladimir Serbinenko * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): From 6a6f80587b06170180b899877c54299f5a1c5af5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:25:44 +0200 Subject: [PATCH 0831/1414] * grub-core/normal/term.c (print_ucs4_terminal): Don't try to put the word on new line if it's too long anyway. Fixes a hang. --- ChangeLog | 5 +++++ grub-core/normal/term.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fdce6dfe0..1b9d768ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/normal/term.c (print_ucs4_terminal): Don't try to put the + word on new line if it's too long anyway. Fixes a hang. + 2011-04-08 Vladimir Serbinenko * include/grub/util/raid.h (grub_util_raid_getmembers): Make argument diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index a1aa3d783..9c4b491f5 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -552,7 +552,7 @@ print_ucs4_terminal (const grub_uint32_t * str, if (line_width > max_width && last_space > line_start) ptr = last_space; else if (line_width > max_width - && line_start == str && startwidth != 0) + && line_start == str && line_width - lastspacewidth < max_width - 5) { ptr = str; lastspacewidth = startwidth; From 34c09785b674cab9df9be9bd2a6e992fafb67c4b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:28:19 +0200 Subject: [PATCH 0832/1414] * grub-core/commands/probe.c (options): Argument to set isn't optional. (GRUB_MOD_INIT): DEVICE isn't optional. --- ChangeLog | 5 +++++ grub-core/commands/probe.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b9d768ce..2bcc1b66b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/commands/probe.c (options): Argument to set isn't optional. + (GRUB_MOD_INIT): DEVICE isn't optional. + 2011-04-08 Vladimir Serbinenko * grub-core/normal/term.c (print_ucs4_terminal): Don't try to put the diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index abe84895d..3ace596d8 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -34,7 +34,7 @@ static const struct grub_arg_option options[] = { - {"set", 's', GRUB_ARG_OPTION_OPTIONAL, + {"set", 's', 0, N_("Set a variable to return value."), "VAR", ARG_TYPE_STRING}, {"driver", 'd', 0, N_("Determine driver."), 0, 0}, {"partmap", 'p', 0, N_("Determine partition map type."), 0, 0}, @@ -150,7 +150,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (probe) { - cmd = grub_register_extcmd ("probe", grub_cmd_probe, 0, N_("[DEVICE]"), + cmd = grub_register_extcmd ("probe", grub_cmd_probe, 0, N_("DEVICE"), N_("Retrieve device info."), options); } From 7c2e4909c3cf1a2b23ac096e48269e1e7f694fab Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:32:41 +0200 Subject: [PATCH 0833/1414] * grub-core/lib/legacy_parse.c (legacy_commands): Find doesn't set root on legacy. --- ChangeLog | 5 +++++ grub-core/lib/legacy_parse.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2bcc1b66b..70101ef17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/lib/legacy_parse.c (legacy_commands): Find doesn't set + root on legacy. + 2011-04-08 Vladimir Serbinenko * grub-core/commands/probe.c (options): Argument to set isn't optional. diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index fb1a52bf8..024849055 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -116,7 +116,7 @@ static struct legacy_command legacy_commands[] = " immediately starts over using the NUM entry (same numbering as the" " `default' command). This obviously won't help if the machine" " was rebooted by a kernel that GRUB loaded."}, - {"find", "search -sf '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILENAME", + {"find", "search -f '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILENAME", "Search for the filename FILENAME in all of partitions and print the list of" " the devices which contain the file."}, /* FIXME: fstest unsupported. */ From d7a565e962b541b8a5ccb2719253a884b2c2b422 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 14:37:13 +0200 Subject: [PATCH 0834/1414] * grub-core/normal/menu_entry.c (run): Use grub_memcpy rather than grub_strcpy since the lines aren't necessarily 0-terminated. --- ChangeLog | 5 +++++ grub-core/normal/menu_entry.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 70101ef17..7621dc3fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * grub-core/normal/menu_entry.c (run): Use grub_memcpy rather than + grub_strcpy since the lines aren't necessarily 0-terminated. + 2011-04-08 Vladimir Serbinenko * grub-core/lib/legacy_parse.c (legacy_commands): Find doesn't set diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index a675ff005..30af2c1dc 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1185,7 +1185,7 @@ run (struct screen *screen) size = 0; for (i = 0; i < screen->num_lines; i++) { - grub_strcpy (source + size, screen->lines[i].buf); + grub_memcpy (source + size, screen->lines[i].buf, screen->lines[i].len); size += screen->lines[i].len; source[size++] = '\n'; } From 2c58372857c7482217006ff9a056915d47bd14a1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 8 Apr 2011 14:01:51 +0100 Subject: [PATCH 0835/1414] * docs/grub-dev.texi: Fix spelling of "developer" throughout. * grub-core/fs/i386/pc/pxe.c (parse_dhcp_vendor): Fix spelling of "development". --- ChangeLog | 6 ++++++ docs/grub-dev.texi | 10 +++++----- grub-core/fs/i386/pc/pxe.c | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7621dc3fb..bc44fb078 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-08 Colin Watson + + * docs/grub-dev.texi: Fix spelling of "developer" throughout. + * grub-core/fs/i386/pc/pxe.c (parse_dhcp_vendor): Fix spelling of + "development". + 2011-04-08 Vladimir Serbinenko * grub-core/normal/menu_entry.c (run): Use grub_memcpy rather than diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi index f1bfd294b..7c4e3d258 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -3,7 +3,7 @@ @c %**start of header @setfilename grub-dev.info @include version-dev.texi -@settitle GNU GRUB Developpers Manual @value{VERSION} +@settitle GNU GRUB Developers Manual @value{VERSION} @c Unify all our little indices for now. @syncodeindex fn cp @syncodeindex vr cp @@ -17,7 +17,7 @@ @finalout @copying -This developper manual is for GNU GRUB (version @value{VERSION}, +This developer manual is for GNU GRUB (version @value{VERSION}, @value{UPDATED}). Copyright @copyright{} 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011 Free Software Foundation, Inc. @@ -39,7 +39,7 @@ Invariant Sections. @titlepage @sp 10 -@title the GNU GRUB developper manual +@title the GNU GRUB developer manual @subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. @author Yoshinori K. Okuji @author Colin D Bennett @@ -61,9 +61,9 @@ Invariant Sections. @ifnottex @node Top -@top GNU GRUB developper manual +@top GNU GRUB developer manual -This is the developper documentation of GNU GRUB, the GRand Unified Bootloader, +This is the developer documentation of GNU GRUB, the GRand Unified Bootloader, a flexible and powerful boot loader program for a wide range of architectures. diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index a3b055f3d..c800ea2ad 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -481,7 +481,7 @@ parse_dhcp_vendor (void *vend, int limit) break; /* If you need any other options please contact GRUB - developpement team. */ + development team. */ } ptr += taglength; From 1ec652f4c46b34e833e4c5068176531e54db7ac3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Apr 2011 16:00:23 +0200 Subject: [PATCH 0836/1414] * util/grub-mkimage.c (main): Handle special naming of yeeloong directory. --- ChangeLog | 5 +++++ util/grub-mkimage.c | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc44fb078..569060ec8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-08 Vladimir Serbinenko + + * util/grub-mkimage.c (main): Handle special naming of yeeloong + directory. + 2011-04-08 Colin Watson * docs/grub-dev.texi: Fix spelling of "developer" throughout. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 876e9c9b2..70c5ef6a9 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1588,9 +1588,19 @@ main (int argc, char *argv[]) + 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; + if (strncmp (image_target->name, "mipsel-yeeloong", + last - image_target->name) == 0) + { + memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), "mips-yeeloong", + sizeof ("mips-yeeloong")); + } + else + { + memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->name, + last - image_target->name); + *(dir + sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name)) + = 0; + } } generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, From 2cf09e3258991b0b1a4d5645d6deaff5ca27ed09 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 9 Apr 2011 03:10:59 +0100 Subject: [PATCH 0837/1414] * docs/grub-dev.texi: Replace MoinMoin syntax with Texinfo syntax throughout. --- ChangeLog | 5 + docs/grub-dev.texi | 339 +++++++++++++++++++++++---------------------- 2 files changed, 178 insertions(+), 166 deletions(-) diff --git a/ChangeLog b/ChangeLog index 569060ec8..0494fa2c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-09 Colin Watson + + * docs/grub-dev.texi: Replace MoinMoin syntax with Texinfo syntax + throughout. + 2011-04-08 Vladimir Serbinenko * util/grub-mkimage.c (main): Handle special naming of yeeloong diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi index 7c4e3d258..a7ab6f71a 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -115,7 +115,7 @@ local version, you may need to resolve conflicts when pulling. @chapter Coding style @c By YoshinoriOkuji, VesaJääskeläinen and ColinBennett -Basically we follow the [http://www.gnu.org/prep/standards_toc.html GNU Coding Standards]. We define additional conventions for GRUB here. +Basically we follow the @uref{http://www.gnu.org/prep/standards_toc.html, GNU Coding Standards}. We define additional conventions for GRUB here. @menu * Naming Conventions:: @@ -167,7 +167,7 @@ If a macro is global, its name must be prefixed with GRUB_ and must consist of o @node Comments @section Comments -All comments shall be C-style comments, of the form `/*` … `*/`. +All comments shall be C-style comments, of the form @samp{/* @dots{} */}. Comments shall be placed only on a line be themselves. They shall not be placed together with code, variable declarations, or other non-comment entities. A comment should be placed immediately preceding the entity it describes. @@ -207,7 +207,7 @@ Unacceptable: * It is long. */ @end example -The opening `/*` and closing `*/` should be placed together on a line with text. +The opening @samp{/*} and closing @samp{*/} should be placed together on a line with text. @node Finding your way around @chapter Finding your way around @@ -320,7 +320,7 @@ anymore. For developers it is recommended always to use the newest development version of GRUB 2. If development takes a long period of time, please remember to keep in sync with newest developments regularly so it is much easier to integrate your change in the future. GRUB 2 is being developed on SVN repository. Please check Savannah's GRUB project page for details how to get newest BZR: -[http://savannah.gnu.org/bzr/?group=grub GRUB 2 BZR Repository] +@uref{http://savannah.gnu.org/bzr/?group=grub, GRUB 2 BZR Repository} @item Compile it and try it out. @@ -368,7 +368,7 @@ what it changes and so on. Please be prepared to receive even discouraging comments about your patch. There is usually at least something that needs to be improved in every patch. -Please use unified diff to make your patch (good match of arguments for diff is ''-pruN''). +Please use unified diff to make your patch (good match of arguments for diff is @samp{-pruN}). @item Respond to received feedback. @@ -419,7 +419,7 @@ project: @enumerate @item You need to create your own account on Savannah. -@item You can submit ''Request for Inclusion'' from ''My Groups'' on Savannah. +@item You can submit ``Request for Inclusion'' from ``My Groups'' on Savannah. @end enumerate Then, one of the admins can approve your request, and you will be a member. @@ -427,7 +427,7 @@ If you don't want to use the Savannah interface to submit a request, you can simply notify the admins by email or something else, alternatively. But you still need to create an account beforehand. -NOTE: we sometimes receive a ''Request for Inclusion'' from an unknown person. +NOTE: we sometimes receive a ``Request for Inclusion'' from an unknown person. In this case, the request would be just discarded, since it is too dangerous to allow a stranger to be a member, which automatically gives him a commit right to the repository, both for a legal reason and for a technical reason. @@ -448,13 +448,13 @@ function does not provide handling of the exception it must return back to it's calling function and so on, until exception is handled. If exception is not handled before prompt is displayed, error message will be shown to user. -Exception information is stored on ''grub_errno'' global variable. If -''grub_errno'' variable contains value ''GRUB_ERR_NONE'', there is no active -exception and application can continue normal processing. When grub_errno has +Exception information is stored on @code{grub_errno} global variable. If +@code{grub_errno} variable contains value @code{GRUB_ERR_NONE}, there is no active +exception and application can continue normal processing. When @code{grub_errno} has other value, it is required that application code either handles this error or -returns instantly to caller. If function is with return type ''grub_err_t'' is -about to return ''GRUB_ERR_NONE'', it should not set ''grub_errno'' to that -value. Only set ''grub_errno'' in cases where there is error situation. +returns instantly to caller. If function is with return type @code{grub_err_t} is +about to return @code{GRUB_ERR_NONE}, it should not set @code{grub_errno} to that +value. Only set @code{grub_errno} in cases where there is error situation. Simple exception forwarder. @example @@ -478,11 +478,11 @@ forwarding_example (void) @end example Error reporting has two components, the actual error code (of type -''grub_err_t'') and textual message that will be displayed to user. List of -valid error codes is listed in header file ''include/grub/err.h''. Textual +@code{grub_err_t}) and textual message that will be displayed to user. List of +valid error codes is listed in header file @file{include/grub/err.h}. Textual error message can contain any textual data. At time of writing, error message can contain up to 256 characters (including terminating NUL). To ease error -reporting there is a helper function ''grub_error'' that allows easier +reporting there is a helper function @code{grub_error} that allows easier formatting of error messages and should be used instead of writing directly to global variables. @@ -499,11 +499,11 @@ failing_example () @end example If there is a special reason that error code does not need to be taken account, -''grub_errno'' can be zeroed back to ''GRUB_ERR_NONE''. In cases like this all +@code{grub_errno} can be zeroed back to @code{GRUB_ERR_NONE}. In cases like this all previous error codes should have been handled correctly. This makes sure that there are no unhandled exceptions. -Example of zeroing ''grub_errno''. +Example of zeroing @code{grub_errno}. @example grub_err_t probe_example () @@ -539,8 +539,8 @@ Some times there is a need to continue processing even if there is a error state in application. In situations like this, there is a needed to save old error state and then call other functions that might fail. To aid in this, there is a error stack implemented. Error state can be pushed to error stack -by calling function ''grub_error_push ()''. When processing has been completed, -''grub_error_pop ()'' can be used to pop error state from stack. Error stack +by calling function @code{grub_error_push ()}. When processing has been completed, +@code{grub_error_pop ()} can be used to pop error state from stack. Error stack contains predefined amount of error stack items. Error stack is proteced for overflow and marks these situations so overflow error does not get unseen. If there is no space available to store error message, it is simply discarded @@ -644,7 +644,7 @@ grub_video_setup (unsigned int width, unsigned int height, unsigned int mode_typ @end example @item Description: -Driver will use information provided to it to select best possible video mode and switch to it. Supported values for ''mode_type'' are ''GRUB_VIDEO_MODE_TYPE_INDEX_COLOR'' for index color modes, ''GRUB_VIDEO_MODE_TYPE_RGB'' for direct RGB color modes and ''GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED'' for double buffering. When requesting RGB mode, highest bits per pixel mode will be selected. When requesting Index color mode, mode with highest number of colors will be selected. If all parameters are specified as zero, video adapter will try to figure out best possible mode and initialize it, platform specific differences are allowed here. If there is no mode matching request, error X will be returned. If there are no problems, function returns ''GRUB_ERR_NONE''. +Driver will use information provided to it to select best possible video mode and switch to it. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED} for double buffering. When requesting RGB mode, highest bits per pixel mode will be selected. When requesting Index color mode, mode with highest number of colors will be selected. If all parameters are specified as zero, video adapter will try to figure out best possible mode and initialize it, platform specific differences are allowed here. If there is no mode matching request, error X will be returned. If there are no problems, function returns @code{GRUB_ERR_NONE}. This function also performs following task upon succesful mode switch. Active rendering target is changed to screen and viewport is maximized to allow whole screen to be used when performing graphics operations. In RGB modes, emulated palette get's 16 entries containing default values for VGA palette, other colors are defined as black. When switching to Indexed Color mode, driver may set default VGA palette to screen if the video card allows the operation. @@ -712,7 +712,7 @@ struct grub_video_mode_info @end example @item Description: -Software developer can use this function to query properties of active rendering taget. Information provided here can be used by other parts of GRUB, like image loaders to convert loaded images to correct screen format to allow more optimized blitters to be used. If there there is no configured video driver with active screen, error ''GRUB_ERR_BAD_DEVICE'' is returned, otherwise ''mode_info'' is filled with valid information and ''GRUB_ERR_NONE'' is returned. +Software developer can use this function to query properties of active rendering taget. Information provided here can be used by other parts of GRUB, like image loaders to convert loaded images to correct screen format to allow more optimized blitters to be used. If there there is no configured video driver with active screen, error @code{GRUB_ERR_BAD_DEVICE} is returned, otherwise @code{mode_info} is filled with valid information and @code{GRUB_ERR_NONE} is returned. @end itemize @subsection grub_video_get_blit_format @@ -740,7 +740,7 @@ enum grub_video_blit_format @end example @item Description: -Used to query how data could be optimized to suit specified video mode. Returns exact video format type, or a generic one if there is no definition for the type. For generic formats, use ''grub_video_get_info'' to query video color coding settings. +Used to query how data could be optimized to suit specified video mode. Returns exact video format type, or a generic one if there is no definition for the type. For generic formats, use @code{grub_video_get_info} to query video color coding settings. @end itemize @subsection grub_video_set_palette @@ -762,7 +762,7 @@ struct grub_video_palette_data @end example @item Description: -Used to setup indexed color palettes. If mode is RGB mode, colors will be set to emulated palette data. In Indexed Color modes, palettes will be set to hardware. Color values will be converted to suit requirements of the video mode. ''start'' will tell what hardware color index (or emulated color index) will be set to according information in first indice of ''palette_data'', after that both hardware color index and ''palette_data'' index will be incremented until ''count'' number of colors have been set. +Used to setup indexed color palettes. If mode is RGB mode, colors will be set to emulated palette data. In Indexed Color modes, palettes will be set to hardware. Color values will be converted to suit requirements of the video mode. @code{start} will tell what hardware color index (or emulated color index) will be set to according information in first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been set. @end itemize @subsection grub_video_get_palette @@ -784,7 +784,7 @@ struct grub_video_palette_data @end example @item Description: -Used to query indexed color palettes. If mode is RGB mode, colors will be copied from emulated palette data. In Indexed Color modes, palettes will be read from hardware. Color values will be converted to suit structure format. ''start'' will tell what hardware color index (or emulated color index) will be used as a source for first indice of ''palette_data'', after that both hardware color index and ''palette_data'' index will be incremented until ''count'' number of colors have been read. +Used to query indexed color palettes. If mode is RGB mode, colors will be copied from emulated palette data. In Indexed Color modes, palettes will be read from hardware. Color values will be converted to suit structure format. @code{start} will tell what hardware color index (or emulated color index) will be used as a source for first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been read. @end itemize @subsection grub_video_set_viewport @@ -797,7 +797,7 @@ grub_video_set_viewport (unsigned int x, unsigned int y, unsigned int width, uns @end example @item Description: -Used to specify viewport where draw commands are performed. When viewport is set, all draw commands coordinates relate to those specified by ''x'' and ''y''. If draw commands try to draw over viewport, they are clipped. If developer requests larger than possible viewport, width and height will be clamped to fit screen. If ''x'' and ''y'' are out of bounds, all functions drawing to screen will not be displayed. In order to maximize viewport, use grub_video_get_info to query actual screen dimensions and provide that information to this function. +Used to specify viewport where draw commands are performed. When viewport is set, all draw commands coordinates relate to those specified by @code{x} and @code{y}. If draw commands try to draw over viewport, they are clipped. If developer requests larger than possible viewport, width and height will be clamped to fit screen. If @code{x} and @code{y} are out of bounds, all functions drawing to screen will not be displayed. In order to maximize viewport, use @code{grub_video_get_info} to query actual screen dimensions and provide that information to this function. @end itemize @subsection grub_video_get_viewport @@ -823,7 +823,7 @@ grub_video_map_color (grub_uint32_t color_name); @end example @item Description: -Map color can be used to support color themes in GRUB. There will be collection of color names that can be used to query actual screen mapped color data. Examples could be ''GRUB_COLOR_CONSOLE_BACKGROUND'', ''GRUB_COLOR_CONSOLE_TEXT''. The actual color defines are not specified at this point. +Map color can be used to support color themes in GRUB. There will be collection of color names that can be used to query actual screen mapped color data. Examples could be @code{GRUB_COLOR_CONSOLE_BACKGROUND}, @code{GRUB_COLOR_CONSOLE_TEXT}. The actual color defines are not specified at this point. @end itemize @subsection grub_video_map_rgb @@ -862,7 +862,7 @@ grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red, grub_uint8_ @end example @item Description: -Unmap color value from ''color'' to color channels in ''red'', ''green'', ''blue'' and ''alpha''. Values will be in range 0-255. Active rendering target will be used for color domain. In case alpha information is not available in rendering target, it is assumed to be opaque (having value 255). +Unmap color value from @code{color} to color channels in @code{red}, @code{green}, @code{blue} and @code{alpha}. Values will be in range 0-255. Active rendering target will be used for color domain. In case alpha information is not available in rendering target, it is assumed to be opaque (having value 255). @end itemize @subsection grub_video_fill_rect @@ -877,7 +877,7 @@ grub_video_fill_rect (grub_video_color_t color, int x, int y, unsigned int width Fill specified area limited by given coordinates within specified viewport. Negative coordinates are accepted in order to allow easy moving of rectangle within viewport. If coordinates are negative, area of the rectangle will be shrinken to follow size limits of the viewport. -Software developer should use either ''grub_video_map_color'', ''grub_video_map_rgb'' or ''grub_video_map_rgba'' to map requested color to ''color'' parameter. +Software developer should use either @code{grub_video_map_color}, @code{grub_video_map_rgb} or @code{grub_video_map_rgba} to map requested color to @code{color} parameter. @end itemize @subsection grub_video_blit_glyph @@ -895,7 +895,7 @@ struct grub_font_glyph @{ @end example @item Description: -Used to blit glyph to viewport in specified coodinates. If glyph is at edge of viewport, pixels outside of viewport will be clipped out. Software developer should use either ''grub_video_map_rgb'' or ''grub_video_map_rgba'' to map requested color to ''color'' parameter. +Used to blit glyph to viewport in specified coodinates. If glyph is at edge of viewport, pixels outside of viewport will be clipped out. Software developer should use either @code{grub_video_map_rgb} or @code{grub_video_map_rgba} to map requested color to @code{color} parameter. @end itemize @subsection grub_video_blit_bitmap @@ -920,9 +920,9 @@ enum grub_video_blit_operators @end example @item Description: -Used to blit bitmap to viewport in specified coordinates. If part of bitmap is outside of viewport region, it will be clipped out. Offsets affect bitmap position where data will be copied from. Negative values for both viewport coordinates and bitmap offset coordinates are allowed. If data is looked out of bounds of bitmap, color value will be assumed to be transparent. If viewport coordinates are negative, area of the blitted rectangle will be shrinken to follow size limits of the viewport and bitmap. Blitting operator ''oper'' specifies should source pixel replace data in screen or blend with pixel alpha value. +Used to blit bitmap to viewport in specified coordinates. If part of bitmap is outside of viewport region, it will be clipped out. Offsets affect bitmap position where data will be copied from. Negative values for both viewport coordinates and bitmap offset coordinates are allowed. If data is looked out of bounds of bitmap, color value will be assumed to be transparent. If viewport coordinates are negative, area of the blitted rectangle will be shrinken to follow size limits of the viewport and bitmap. Blitting operator @code{oper} specifies should source pixel replace data in screen or blend with pixel alpha value. -Software developer should use ''grub_video_bitmap_create'' or ''grub_video_bitmap_load'' to create or load bitmap data. +Software developer should use @code{grub_video_bitmap_create} or @code{grub_video_bitmap_load} to create or load bitmap data. @end itemize @subsection grub_video_blit_render_target @@ -946,7 +946,7 @@ enum grub_video_blit_operators @end example @item Description: -Used to blit source render target to viewport in specified coordinates. If part of source render target is outside of viewport region, it will be clipped out. If blitting operator is specified and source contains alpha values, resulting pixel color components will be calculated using formula ((src_color * src_alpha) + (dst_color * (255 - src_alpha)) / 255, if target buffer has alpha, it will be set to src_alpha. Offsets affect render target position where data will be copied from. If data is looked out of bounds of render target, color value will be assumed to be transparent. Blitting operator ''oper'' specifies should source pixel replace data in screen or blend with pixel alpha value. +Used to blit source render target to viewport in specified coordinates. If part of source render target is outside of viewport region, it will be clipped out. If blitting operator is specified and source contains alpha values, resulting pixel color components will be calculated using formula ((src_color * src_alpha) + (dst_color * (255 - src_alpha)) / 255, if target buffer has alpha, it will be set to src_alpha. Offsets affect render target position where data will be copied from. If data is looked out of bounds of render target, color value will be assumed to be transparent. Blitting operator @code{oper} specifies should source pixel replace data in screen or blend with pixel alpha value. @end itemize @subsection grub_video_scroll @@ -990,7 +990,7 @@ struct grub_video_render_target @{ @end example @item Description: -Driver will use information provided to it to create best fitting render target. ''mode_type'' will be used to guide on selecting what features are wanted for render target. Supported values for ''mode_type'' are ''GRUB_VIDEO_MODE_TYPE_INDEX_COLOR'' for index color modes, ''GRUB_VIDEO_MODE_TYPE_RGB'' for direct RGB color modes and ''GRUB_VIDEO_MODE_TYPE_ALPHA'' for alpha component. +Driver will use information provided to it to create best fitting render target. @code{mode_type} will be used to guide on selecting what features are wanted for render target. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_ALPHA} for alpha component. @end itemize @subsection grub_video_delete_render_target @@ -1003,7 +1003,7 @@ grub_video_delete_render_target (struct grub_video_render_target *target); @end example @item Description: -Used to delete previously created render target. If ''target'' contains ''NULL'' pointer, nothing will be done. If render target is correctly destroyed, GRUB_ERR_NONE is returned. +Used to delete previously created render target. If @code{target} contains @code{NULL} pointer, nothing will be done. If render target is correctly destroyed, GRUB_ERR_NONE is returned. @end itemize @subsection grub_video_set_active_render_target @@ -1016,7 +1016,7 @@ grub_video_set_active_render_target (struct grub_video_render_target *target); @end example @item Description: -Set's active render target. If this comand is successful all drawing commands will be done to specified ''target''. There is also special values for target, ''GRUB_VIDEO_RENDER_TARGET_DISPLAY'' used to reference screen's front buffer, ''GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER'' used to reference screen's front buffer (alias for ''GRUB_VIDEO_RENDER_TARGET_DISPLAY'') and ''GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER'' used to reference back buffer (if double buffering is enabled). If render target is correclty switched GRUB_ERR_NONE is returned. In no any event shall there be non drawable active render target. +Set's active render target. If this comand is successful all drawing commands will be done to specified @code{target}. There is also special values for target, @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY} used to reference screen's front buffer, @code{GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER} used to reference screen's front buffer (alias for @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY}) and @code{GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER} used to reference back buffer (if double buffering is enabled). If render target is correclty switched GRUB_ERR_NONE is returned. In no any event shall there be non drawable active render target. @end itemize @subsection grub_video_get_active_render_target @@ -1029,7 +1029,7 @@ grub_video_get_active_render_target (struct grub_video_render_target **target); @end example @item Description: -Returns currently active render target. It returns value in ''target'' that can be subsequently issued back to ''grub_video_set_active_render_target''. +Returns currently active render target. It returns value in @code{target} that can be subsequently issued back to @code{grub_video_set_active_render_target}. @end itemize @node Example usage of Video API @@ -1082,7 +1082,7 @@ grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap, unsigned @item Description: -Creates a new bitmap with given dimensions and blitting format. Allocated bitmap data can then be modified freely and finally blitted with ''grub_video_blit_bitmap'' to rendering target. +Creates a new bitmap with given dimensions and blitting format. Allocated bitmap data can then be modified freely and finally blitted with @code{grub_video_blit_bitmap} to rendering target. @end itemize @subsection grub_video_bitmap_destroy @@ -1094,7 +1094,7 @@ grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap); @item Description: -When bitmap is no longer needed, it can be freed from memory using this command. ''bitmap'' is previously allocated bitmap with ''grub_video_bitmap_create'' or loaded with ''grub_video_bitmap_load''. +When bitmap is no longer needed, it can be freed from memory using this command. @code{bitmap} is previously allocated bitmap with @code{grub_video_bitmap_create} or loaded with @code{grub_video_bitmap_load}. @end itemize @subsection grub_video_bitmap_load @@ -1106,7 +1106,7 @@ grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, const char @item Description: -Tries to load given bitmap (''filename'') using registered bitmap loaders. In case bitmap format is not recognized or supported error ''GRUB_ERR_BAD_FILE_TYPE'' is returned. +Tries to load given bitmap (@code{filename}) using registered bitmap loaders. In case bitmap format is not recognized or supported error @code{GRUB_ERR_BAD_FILE_TYPE} is returned. @end itemize @subsection grub_video_bitmap_get_width @@ -1142,7 +1142,7 @@ void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, struct g @item Description: -Returns bitmap format details in form of ''grub_video_mode_info''. +Returns bitmap format details in form of @code{grub_video_mode_info}. @end itemize @subsection grub_video_bitmap_get_data @@ -1181,20 +1181,20 @@ use, compact, and cleanly supports Unicode. @itemize @item Simple to read and use. - Since GRUB will only be reading the font files, - we are more concerned with making the code to read the font simple than we - are with writing the font. +Since GRUB will only be reading the font files, +we are more concerned with making the code to read the font simple than we +are with writing the font. @item Compact storage. - The fonts will generally be stored in a small boot - partition where GRUB is located, and this may be on a removable storage - device such as a CD or USB flash drive where space is more limited than it - is on most hard drives. +The fonts will generally be stored in a small boot +partition where GRUB is located, and this may be on a removable storage +device such as a CD or USB flash drive where space is more limited than it +is on most hard drives. @item Unicode. - GRUB should not have to deal with multiple character - encodings. The font should always use Unicode character codes for simple - internationalization. +GRUB should not have to deal with multiple character +encodings. The font should always use Unicode character codes for simple +internationalization. @end itemize @subsection Why Another Font Format? @@ -1205,136 +1205,143 @@ use in GRUB at this time: @table @samp @item BDF - Inefficient storage; uses ASCII to describe properties and - hexadecimal numbers in ASCII for the bitmap rows. +Inefficient storage; uses ASCII to describe properties and +hexadecimal numbers in ASCII for the bitmap rows. @item PCF - Many format variations such as byte order and bitmap padding (rows - padded to byte, word, etc.) would result in more complex code to - handle the font format. +Many format variations such as byte order and bitmap padding (rows +padded to byte, word, etc.) would result in more complex code to +handle the font format. @end table @node File Structure @section File Structure -A file *section* consists of a 4-byte name, a 32-bit big-endian length (not -including the name or length), and then *length* more section-type-specific +A file @strong{section} consists of a 4-byte name, a 32-bit big-endian length (not +including the name or length), and then @var{length} more section-type-specific bytes. -The standard file extension for PFF2 font files is ``.pf2``. +The standard file extension for PFF2 font files is @file{.pf2}. @subsection Section Types @table @samp @item FILE - *File type ID* (ASCII string). This must be the first section in the file. It has length 4 - and the contents are the four bytes of the ASCII string ``PFF2``. +@strong{File type ID} (ASCII string). This must be the first section in the file. It has length 4 +and the contents are the four bytes of the ASCII string @samp{PFF2}. @item NAME - *Font name* (ASCII string). This is the full font name including family, - weight, style, and point size. For instance, "Helvetica Bold Italic 14". +@strong{Font name} (ASCII string). This is the full font name including family, +weight, style, and point size. For instance, "Helvetica Bold Italic 14". @item FAMI - *Font family name* (ASCII string). For instance, "Helvetica". This should - be included so that intelligent font substitution can take place. +@strong{Font family name} (ASCII string). For instance, "Helvetica". This should +be included so that intelligent font substitution can take place. @item WEIG - *Font weight* (ASCII string). Valid values are ``bold`` and ``normal``. - This should be included so that intelligent font substitution can take - place. +@strong{Font weight} (ASCII string). Valid values are @samp{bold} and @samp{normal}. +This should be included so that intelligent font substitution can take +place. @item SLAN - *Font slant* (ASCII string). Valid values are ``italic`` and ``normal``. - This should be included so that intelligent font substitution can take - place. +@strong{Font slant} (ASCII string). Valid values are @samp{italic} and @samp{normal}. +This should be included so that intelligent font substitution can take +place. @item PTSZ - *Font point size* (uint16be). +@strong{Font point size} (uint16be). @item MAXW - *Maximum character width in pixels* (uint16be). +@strong{Maximum character width in pixels} (uint16be). @item MAXH - *Maximum character height in pixels* (uint16be). +@strong{Maximum character height in pixels} (uint16be). @item ASCE - *Ascent in pixels* (uint16be). See `Font Metrics`_ for details. +@strong{Ascent in pixels} (uint16be). @xref{Font Metrics}, for details. @item DESC - *Descent in pixels* (uint16be). See `Font Metrics`_ for details. +@strong{Descent in pixels} (uint16be). @xref{Font Metrics}, for details. @item CHIX - *Character index.* - The character index begins with a 32-bit big-endian unsigned integer - indicating the total size of the section, not including this size value. - For each character, there is an instance of the following entry structure: +@strong{Character index.} +The character index begins with a 32-bit big-endian unsigned integer +indicating the total size of the section, not including this size value. +For each character, there is an instance of the following entry structure: - @itemize - @item **Unicode code point.** (32-bit big-endian integer.) +@itemize +@item @strong{Unicode code point.} (32-bit big-endian integer.) - @item **Storage flags.** (byte.) +@item @strong{Storage flags.} (byte.) - @itemize - @item Bits 2..0: +@itemize +@item Bits 2..0: - - If equal to 000 binary, then the character data is stored - uncompressed beginning at the offset indicated by the character's - *offset* value. +If equal to 000 binary, then the character data is stored +uncompressed beginning at the offset indicated by the character's +@strong{offset} value. - - If equal to 001 binary, then the character data is stored within a - compressed character definition block that begins at the offset - within the file indicated by the character's *offset* value. - @end itemize - @item **Offset.** (32-bit big-endian integer.) +If equal to 001 binary, then the character data is stored within a +compressed character definition block that begins at the offset +within the file indicated by the character's @strong{offset} value. +@end itemize - A marker that indicates the remainder of the file is data accessed via - the character index (CHIX) section. When reading this font file, the rest - of the file can be ignored when scanning the sections. The length should - be set to -1 (0xFFFFFFFF). +@item @strong{Offset.} (32-bit big-endian integer.) - Supported data structures: +A marker that indicates the remainder of the file is data accessed via +the character index (CHIX) section. When reading this font file, the rest +of the file can be ignored when scanning the sections. The length should +be set to -1 (0xFFFFFFFF). - Character definition - Each character definition consists of: +Supported data structures: - @itemize - @item **Width.** Width of the bitmap in pixels. The bitmap's extents - represent the glyph's bounding box. *uint16be*. +Character definition +Each character definition consists of: - @item **Height.** Height of the bitmap in pixels. The bitmap's extents - represent the glyph's bounding box. *uint16be*. +@itemize +@item @strong{Width.} +Width of the bitmap in pixels. The bitmap's extents +represent the glyph's bounding box. @code{uint16be}. - @item **X offset.** The number of pixels to shift the bitmap by - horizontally before drawing the character. *int16be*. +@item @strong{Height.} +Height of the bitmap in pixels. The bitmap's extents +represent the glyph's bounding box. @code{uint16be}. - @item **Y offset.** The number of pixels to shift the bitmap by - vertically before drawing the character. *int16be*. +@item @strong{X offset.} +The number of pixels to shift the bitmap by +horizontally before drawing the character. @code{int16be}. - @item **Device width.** The number of pixels to advance horizontally from - this character's origin to the origin of the next character. - *int16be*. +@item @strong{Y offset.} +The number of pixels to shift the bitmap by +vertically before drawing the character. @code{int16be}. - @item **Bitmap data.** This is encoded as a string of bits. It is - organized as a row-major, top-down, left-to-right bitmap. The most - significant bit of each byte is taken to be the leftmost or uppermost - bit in the byte. For the sake of compact storage, rows are not padded - to byte boundaries (i.e., a single byte may contain bits belonging to - multiple rows). The last byte of the bitmap *is* padded with zero - bits in the bits positions to the right of the last used bit if the - bitmap data does not fill the last byte. +@item @strong{Device width.} +The number of pixels to advance horizontally from +this character's origin to the origin of the next character. +@code{int16be}. + +@item @strong{Bitmap data.} +This is encoded as a string of bits. It is +organized as a row-major, top-down, left-to-right bitmap. The most +significant bit of each byte is taken to be the leftmost or uppermost +bit in the byte. For the sake of compact storage, rows are not padded +to byte boundaries (i.e., a single byte may contain bits belonging to +multiple rows). The last byte of the bitmap @strong{is} padded with zero +bits in the bits positions to the right of the last used bit if the +bitmap data does not fill the last byte. - The length of the *bitmap data* field is (*width* * *height* + 7) / 8 - using integer arithmetic, which is equivalent to ceil(*width* * - *height* / 8) using real number arithmetic. +The length of the @strong{bitmap data} field is (@var{width} * @var{height} + 7) / 8 +using integer arithmetic, which is equivalent to ceil(@var{width} * +@var{height} / 8) using real number arithmetic. - It remains to be determined whether bitmap fonts usually make all - glyph bitmaps the same height, or if smaller glyphs are stored with - bitmaps having a lesser height. In the latter case, the baseline - would have to be used to calculate the location the bitmap should be - anchored at on screen. - @end itemize +It remains to be determined whether bitmap fonts usually make all +glyph bitmaps the same height, or if smaller glyphs are stored with +bitmaps having a lesser height. In the latter case, the baseline +would have to be used to calculate the location the bitmap should be +anchored at on screen. +@end itemize - @end itemize +@end itemize @end table @node Font Metrics @@ -1342,28 +1349,28 @@ The standard file extension for PFF2 font files is ``.pf2``. @itemize @item Ascent. - The distance from the baseline to the top of most characters. - Note that in some cases characters may extend above the ascent. +The distance from the baseline to the top of most characters. +Note that in some cases characters may extend above the ascent. @item Descent. - The distance from the baseline to the bottom of most characters. Note that - in some cases characters may extend below the descent. +The distance from the baseline to the bottom of most characters. Note that +in some cases characters may extend below the descent. @item Leading. - The amount of space, in pixels, to leave between the descent of one line of - text and the ascent of the next line. This metrics is not specified in the - current file format; instead, the font rendering engine calculates a - reasonable leading value based on the other font metrics. +The amount of space, in pixels, to leave between the descent of one line of +text and the ascent of the next line. This metrics is not specified in the +current file format; instead, the font rendering engine calculates a +reasonable leading value based on the other font metrics. @item Horizonal leading. - The amount of space, in pixels, to leave horizontally between the left and - right edges of two adjacent glyphs. The *device width* field determines - the effective leading value that is used to render the font. +The amount of space, in pixels, to leave horizontally between the left and +right edges of two adjacent glyphs. The @strong{device width} field determines +the effective leading value that is used to render the font. @end itemize @image{font_char_metrics,,,,.png} - An illustration of how the various font metrics apply to characters. +An illustration of how the various font metrics apply to characters. @@ -1383,15 +1390,15 @@ The standard file extension for PFF2 font files is ``.pf2``. @node Introduction_2 @section Introduction -The ``gfxmenu`` module provides a graphical menu interface for GRUB 2. It -functions as an alternative to the menu interface provided by the ``normal`` +The @samp{gfxmenu} module provides a graphical menu interface for GRUB 2. It +functions as an alternative to the menu interface provided by the @samp{normal} module, which uses the grub terminal interface to display a menu on a character-oriented terminal. The graphical menu uses the GRUB video API, which is currently for the VESA BIOS extensions (VBE) 2.0+. This is supported on the i386-pc platform. However, the graphical menu itself does not depend on using VBE, so if another -GRUB video driver were implemented, the ``gfxmenu`` graphical menu would work +GRUB video driver were implemented, the @samp{gfxmenu} graphical menu would work on the new video driver as well. @@ -1402,7 +1409,7 @@ on the new video driver as well. @item grub_enter_normal_mode [normal/main.c] @item grub_normal_execute [normal/main.c] @item read_config_file [normal/main.c] -@item (When ``gfxmenu.mod`` is loaded with ``insmod``, it will call ``grub_menu_viewer_register()`` to register itself.) +@item (When @file{gfxmenu.mod} is loaded with @command{insmod}, it will call @code{grub_menu_viewer_register()} to register itself.) @item GRUB_MOD_INIT (gfxmenu) [gfxmenu/gfxmenu.c] @item grub_menu_viewer_register [kern/menu_viewer.c] @item grub_menu_viewer_show_menu [kern/menu_viewer.c] @@ -1422,7 +1429,7 @@ The graphical menu implements a GUI component system that supports a container-based layout system. Components can be added to containers, and containers (which are a type of component) can then be added to other containers, to form a tree of components. Currently, the root component of -this tree is a *canvas* component, which allows manual layout of its child +this tree is a @samp{canvas} component, which allows manual layout of its child components. Components (non-container): @@ -1444,13 +1451,13 @@ Containers: @end itemize The GUI component instances are created by the theme loader in -``gfxmenu/theme_loader.c`` when a theme is loaded. Theme files specify -statements such as ``+vbox@{ +label @{ text="Hello" @} +label@{ text="World" @} @}`` +@file{gfxmenu/theme_loader.c} when a theme is loaded. Theme files specify +statements such as @samp{+vbox@{ +label @{ text="Hello" @} +label@{ text="World" @} @}} to add components to the component tree root. By nesting the component creation statements in the theme file, the instantiated components are nested the same way. -When a component is added to a container, that new child is considered *owned* +When a component is added to a container, that new child is considered @strong{owned} by the container. Great care should be taken if the caller retains a reference to the child component, since it will be destroyed if its parent container is destroyed. A better choice instead of storing a pointer to the @@ -1459,40 +1466,40 @@ Component IDs do not have to be unique (it is often useful to have multiple components with an ID of "__timeout__", for instance). In order to access and use components in the component tree, there are two -functions (defined in ``gfxmenu/gui_util.c``) that are particularly useful: +functions (defined in @file{gfxmenu/gui_util.c}) that are particularly useful: @itemize -@item ``grub_gui_find_by_id (root, id, callback, userdata)``: +@item @code{grub_gui_find_by_id (root, id, callback, userdata)}: - This function ecursively traverses the component tree rooted at *root*, and - for every component that has an ID equal to *id*, calls the function pointed - to by *callback* with the matching component and the void pointer *userdata* - as arguments. The callback function can do whatever is desired to use the - component passed in. +This function ecursively traverses the component tree rooted at @var{root}, and +for every component that has an ID equal to @var{id}, calls the function pointed +to by @var{callback} with the matching component and the void pointer @var{userdata} +as arguments. The callback function can do whatever is desired to use the +component passed in. -@item ``grub_gui_iterate_recursively (root, callback, userdata)``: +@item @code{grub_gui_iterate_recursively (root, callback, userdata)}: - This function calls the function pointed to by *callback* for every - component that is a descendant of *root* in the component tree. When the - callback function is called, the component and the void pointer *userdata* - as arguments. The callback function can do whatever is desired to use the - component passed in. +This function calls the function pointed to by @var{callback} for every +component that is a descendant of @var{root} in the component tree. When the +callback function is called, the component and the void pointer @var{userdata} +as arguments. The callback function can do whatever is desired to use the +component passed in. @end itemize @node Command Line Window @section Command Line Window The terminal window used to provide command line access within the graphical -menu is managed by ``gfxmenu/view.c``. The ``gfxterm`` terminal is used, and +menu is managed by @file{gfxmenu/view.c}. The @samp{gfxterm} terminal is used, and it has been modified to allow rendering to an offscreen render target to allow it to be composed into the double buffering system that the graphical menu view uses. This is bad for performance, however, so it would probably be a good idea to make it possible to temporarily disable double buffering as long as the terminal window is visible. There are still unresolved problems that occur when commands are executed from the terminal window that change the -graphics mode. It's possible that making ``grub_video_restore()`` return to -the graphics mode that was in use before ``grub_video_setup()`` was called +graphics mode. It's possible that making @code{grub_video_restore()} return to +the graphics mode that was in use before @code{grub_video_setup()} was called might fix some of the problems. From 536ce85a8dc2fafbe6694b8664eb9c77b7d1d08e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 9 Apr 2011 03:39:47 +0100 Subject: [PATCH 0838/1414] * docs/grub-dev.texi (Finding your way around): Update for 1.99 build system. (Getting started): GRUB is developed in Bazaar now, not Subversion. (Comment): Fix typo. (Getting started): General copy-editing. (Typical Development Experience): Likewise. (Error Handling): Likewise. (Video API): Likewise. --- ChangeLog | 12 +++++ docs/grub-dev.texi | 117 +++++++++++++++++++++++++-------------------- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0494fa2c3..4c46f8996 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-04-09 Colin Watson + + * docs/grub-dev.texi (Finding your way around): Update for 1.99 + build system. + (Getting started): GRUB is developed in Bazaar now, not Subversion. + + (Comment): Fix typo. + (Getting started): General copy-editing. + (Typical Development Experience): Likewise. + (Error Handling): Likewise. + (Video API): Likewise. + 2011-04-09 Colin Watson * docs/grub-dev.texi: Replace MoinMoin syntax with Texinfo syntax diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi index a7ab6f71a..a45b8b198 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -169,7 +169,7 @@ If a macro is global, its name must be prefixed with GRUB_ and must consist of o All comments shall be C-style comments, of the form @samp{/* @dots{} */}. -Comments shall be placed only on a line be themselves. They shall not be placed together with code, variable declarations, or other non-comment entities. A comment should be placed immediately preceding the entity it describes. +Comments shall be placed only on a line by themselves. They shall not be placed together with code, variable declarations, or other non-comment entities. A comment should be placed immediately preceding the entity it describes. Acceptable: @example @@ -214,74 +214,85 @@ The opening @samp{/*} and closing @samp{*/} should be placed together on a line Here is a brief map of the GRUB code base. -GRUB uses Autoconf, but not (yet) Automake. The top-level build rules are -in @file{configure.ac}, @file{Makefile.in}, and @file{conf/*.rmk}. Each -@file{conf/*.rmk} file represents a particular target configuration, and is -processed into GNU Make rules by @file{genmk.rb} (which you only need to +GRUB uses Autoconf and Automake, with most of the Automake input generated +by AutoGen. The top-level build rules are in @file{configure.ac}, +@file{grub-core/Makefile.core.def}, and @file{Makefile.util.def}. Each +block in a @file{*.def} file represents a build target, and specifies the +source files used to build it on various platforms. The @file{*.def} files +are processed into AutoGen input by @file{gentpl.py} (which you only need to look at if you are extending the build system). If you are adding a new module which follows an existing pattern, such as a new command or a new -filesystem implementation, it is usually easiest to grep @file{conf/*.rmk} -for an existing example of that pattern to find out where it should be -added. +filesystem implementation, it is usually easiest to grep +@file{grub-core/Makefile.core.def} and @file{Makefile.util.def} for an +existing example of that pattern to find out where it should be added. + +In general, code that may be run at boot time is in a subdirectory of +@file{grub-core}, while code that is only run from within a full operating +system is in a subdirectory of the top level. Low-level boot code, such as the MBR implementation on PC BIOS systems, is -in the @file{boot/} directory. +in the @file{grub-core/boot/} directory. -The GRUB kernel is in @file{kern/}. This contains core facilities such as -the device, disk, and file frameworks, environment variable handling, list -processing, and so on. The kernel should contain enough to get up to a -rescue prompt. Header files for kernel facilities, among others, are in -@file{include/}. +The GRUB kernel is in @file{grub-core/kern/}. This contains core facilities +such as the device, disk, and file frameworks, environment variable +handling, list processing, and so on. The kernel should contain enough to +get up to a rescue prompt. Header files for kernel facilities, among +others, are in @file{include/}. -Terminal implementations are in @file{term/}. +Terminal implementations are in @file{grub-core/term/}. -Disk access code is spread across @file{disk/} (for accessing the disk -devices themselves), @file{partmap/} (for interpreting partition table -data), and @file{fs/} (for accessing filesystems). Note that, with the odd -specialised exception, GRUB only contains code to @emph{read} from -filesystems and tries to avoid containing any code to @emph{write} to -filesystems; this lets us confidently assure users that GRUB cannot be -responsible for filesystem corruption. +Disk access code is spread across @file{grub-core/disk/} (for accessing the +disk devices themselves), @file{grub-core/partmap/} (for interpreting +partition table data), and @file{grub-core/fs/} (for accessing filesystems). +Note that, with the odd specialised exception, GRUB only contains code to +@emph{read} from filesystems and tries to avoid containing any code to +@emph{write} to filesystems; this lets us confidently assure users that GRUB +cannot be responsible for filesystem corruption. -PCI and USB bus handling is in @file{bus/}. +PCI and USB bus handling is in @file{grub-core/bus/}. -Video handling code is in @file{video/}. The graphical menu system uses -this heavily, but is in a separate directory, @file{gfxmenu/}. +Video handling code is in @file{grub-core/video/}. The graphical menu +system uses this heavily, but is in a separate directory, +@file{grub-core/gfxmenu/}. -Most commands are implemented by files in @file{commands/}, with the -following exceptions: +Most commands are implemented by files in @file{grub-core/commands/}, with +the following exceptions: @itemize @item -A few core commands live in @file{kern/corecmd.c}. +A few core commands live in @file{grub-core/kern/corecmd.c}. @item -Commands related to normal mode live under @file{normal/}. +Commands related to normal mode live under @file{grub-core/normal/}. @item -Commands that load and boot kernels live under @file{loader/}. +Commands that load and boot kernels live under @file{grub-core/loader/}. @item The @samp{loopback} command is really a disk device, and so lives in -@file{disk/loopback.c}. +@file{grub-core/disk/loopback.c}. @item -The @samp{gettext} command lives under @file{gettext/}. +The @samp{gettext} command lives under @file{grub-core/gettext/}. @item -The @samp{loadfont} and @samp{lsfonts} commands live under @file{font/}. +The @samp{loadfont} and @samp{lsfonts} commands live under +@file{grub-core/font/}. @item The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands -live under @file{term/}. +live under @file{grub-core/term/}. @item -The @samp{efiemu_*} commands live under @file{efiemu/}. +The @samp{efiemu_*} commands live under @file{grub-core/efiemu/}. @end itemize There are a few other special-purpose exceptions; grep for them if they matter to you. +Utility programs meant to be run from a full operating system are in +@file{util/}. + @node Contributing Changes @chapter Contributing changes @c By YoshinoriOkuji, VesaJääskeläinen, ColinWatson @@ -317,10 +328,10 @@ anymore. @itemize @item Always use latest GRUB 2 source code. So get that first. -For developers it is recommended always to use the newest development version of GRUB 2. If development takes a long period of time, please remember to keep in sync with newest developments regularly so it is much easier to integrate your change in the future. GRUB 2 is being developed on SVN repository. +For developers it is recommended always to use the newest development version of GRUB 2. If development takes a long period of time, please remember to keep in sync with newest developments regularly so it is much easier to integrate your change in the future. GRUB 2 is being developed in a Bazaar (bzr) repository. -Please check Savannah's GRUB project page for details how to get newest BZR: -@uref{http://savannah.gnu.org/bzr/?group=grub, GRUB 2 BZR Repository} +Please check Savannah's GRUB project page for details how to get newest bzr: +@uref{http://savannah.gnu.org/bzr/?group=grub, GRUB 2 bzr Repository} @item Compile it and try it out. @@ -342,7 +353,7 @@ be free to develop it. If you have not so far announced your idea on grub-devel mailing list, please do it now. This is to make sure you are not wasting your time working on the solution that will not be integrated to GRUB 2 code base. -You might want to study our coding style before starting to development so you +You might want to study our coding style before starting development so you do not need to change much of the code when your patch is being reviewed. (see @ref{Coding style}) @@ -357,11 +368,11 @@ discuss it beforehand on grub-devel mailing list. @item Test your change. -Test that your change works properly. Try it out couple of times. Preferably on different systems. And try to find problems from it. +Test that your change works properly. Try it out a couple of times, preferably on different systems, and try to find problems with it. @item Publish your change. -When you are happy with your change. First make sure it is compilable with +When you are happy with your change, first make sure it is compilable with latest development version of GRUB 2. After that please send a patch to grub-devel for review. Please describe in your email why you made the change, what it changes and so on. Please be prepared to receive even discouraging @@ -379,15 +390,15 @@ for copyright agreement, process can take some time and is mandatory in order to get your changes integrated. If you are not on grub-devel to respond to questions, most likely your patch -will not be accepted. Also if there comes problems from your changes later on, -it would be preferably that you also fix the problem. So stay around +will not be accepted. Also if problems arise from your changes later on, +it would be preferable that you also fix the problem. So stay around for a while. @item Your patch is accepted. -Good job! Your patch will no be integrated to GRUB 2 main line and if it didn't break a thing it will be publically available when next release will be done. +Good job! Your patch will now be integrated into GRUB 2 mainline, and if it didn't break anything it will be publicly available in the next release. -Now you are welcomed to do further improvements :) +Now you are welcome to do further improvements :) @end itemize @node Typical Developer Experience @@ -400,7 +411,7 @@ The typical experience for a developer in this project is the following: @item You show some result in the mailing list or the IRC. @item You are getting to be known to other developers. @item You accumulate significant amount of contribution, so copyright assignment is processed. -@item You are free to check in your changes by your own, legally speaking. +@item You are free to check in your changes on your own, legally speaking. @end enumerate At this point, it is rather annoying that you ought to ask somebody else every @@ -444,7 +455,7 @@ doesn't direcly support exceptions, exception handling behavior is emulated in software. When exception is raised, function must return to calling function. If calling -function does not provide handling of the exception it must return back to it's +function does not provide handling of the exception it must return back to its calling function and so on, until exception is handled. If exception is not handled before prompt is displayed, error message will be shown to user. @@ -541,11 +552,11 @@ error state and then call other functions that might fail. To aid in this, there is a error stack implemented. Error state can be pushed to error stack by calling function @code{grub_error_push ()}. When processing has been completed, @code{grub_error_pop ()} can be used to pop error state from stack. Error stack -contains predefined amount of error stack items. Error stack is proteced for +contains predefined amount of error stack items. Error stack is protected for overflow and marks these situations so overflow error does not get unseen. If there is no space available to store error message, it is simply discarded and overflow will be marked as happened. When overflow happens, it most likely -will corrupt error stack consistency as for pushed error there is no matching +will corrupt error stack consistency as for pushed error there is no matching pop, but overflow message will be shown to inform user about the situation. Overflow message will be shown at time when prompt is about to be drawn. @@ -646,7 +657,7 @@ grub_video_setup (unsigned int width, unsigned int height, unsigned int mode_typ Driver will use information provided to it to select best possible video mode and switch to it. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED} for double buffering. When requesting RGB mode, highest bits per pixel mode will be selected. When requesting Index color mode, mode with highest number of colors will be selected. If all parameters are specified as zero, video adapter will try to figure out best possible mode and initialize it, platform specific differences are allowed here. If there is no mode matching request, error X will be returned. If there are no problems, function returns @code{GRUB_ERR_NONE}. -This function also performs following task upon succesful mode switch. Active rendering target is changed to screen and viewport is maximized to allow whole screen to be used when performing graphics operations. In RGB modes, emulated palette get's 16 entries containing default values for VGA palette, other colors are defined as black. When switching to Indexed Color mode, driver may set default VGA palette to screen if the video card allows the operation. +This function also performs following task upon succesful mode switch. Active rendering target is changed to screen and viewport is maximized to allow whole screen to be used when performing graphics operations. In RGB modes, emulated palette gets 16 entries containing default values for VGA palette, other colors are defined as black. When switching to Indexed Color mode, driver may set default VGA palette to screen if the video card allows the operation. @end itemize @@ -836,7 +847,7 @@ grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue); @end example @item Description: -Map RGB values to compatible screen color data. Values are excepted to be in range 0-255 and in RGB modes they will be converted to screen color data. In index color modes, index color palette will be searched for specified color and then index is returned. +Map RGB values to compatible screen color data. Values are expected to be in range 0-255 and in RGB modes they will be converted to screen color data. In index color modes, index color palette will be searched for specified color and then index is returned. @end itemize @subsection grub_video_map_rgba @@ -849,7 +860,7 @@ grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue, gr @end example @item Description: -Map RGBA values to compatible screen color data. Values are excepted to be in range 0-255. In RGBA modes they will be converted to screen color data. In index color modes, index color palette will be searched for best matching color and it's index is returned. +Map RGBA values to compatible screen color data. Values are expected to be in range 0-255. In RGBA modes they will be converted to screen color data. In index color modes, index color palette will be searched for best matching color and its index is returned. @end itemize @subsection grub_video_unmap_color @@ -1016,7 +1027,7 @@ grub_video_set_active_render_target (struct grub_video_render_target *target); @end example @item Description: -Set's active render target. If this comand is successful all drawing commands will be done to specified @code{target}. There is also special values for target, @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY} used to reference screen's front buffer, @code{GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER} used to reference screen's front buffer (alias for @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY}) and @code{GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER} used to reference back buffer (if double buffering is enabled). If render target is correclty switched GRUB_ERR_NONE is returned. In no any event shall there be non drawable active render target. +Sets active render target. If this comand is successful all drawing commands will be done to specified @code{target}. There is also special values for target, @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY} used to reference screen's front buffer, @code{GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER} used to reference screen's front buffer (alias for @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY}) and @code{GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER} used to reference back buffer (if double buffering is enabled). If render target is correclty switched GRUB_ERR_NONE is returned. In no any event shall there be non drawable active render target. @end itemize @subsection grub_video_get_active_render_target From 099821e9e4d55abe11054380068decda0cec4a17 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 9 Apr 2011 21:55:50 +0200 Subject: [PATCH 0839/1414] Fix RAID1/duplicated chunk size calculation --- grub-core/fs/btrfs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ac90c055a..7632d535c 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -664,13 +664,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, case GRUB_BTRFS_CHUNK_TYPE_RAID1: /* FIXME: Use redundancy. */ { - grub_uint32_t stripe_length; - stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - NULL); stripen = 0; stripe_offset = off; - csize = stripe_length - off; + csize = grub_le_to_cpu64 (chunk->size) - off; redundancy = 2; break; } From 277f955bf115a516fa464fec3e92f919c48f05bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Apr 2011 11:57:19 +0200 Subject: [PATCH 0840/1414] * grub-core/boot/mips/yeeloong/fwstart.S: Fix address to error message. Remove now unused string. --- ChangeLog | 5 +++++ grub-core/boot/mips/yeeloong/fwstart.S | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c46f8996..1bb8cf278 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-10 Vladimir Serbinenko + + * grub-core/boot/mips/yeeloong/fwstart.S: Fix address to error message. + Remove now unused string. + 2011-04-09 Colin Watson * docs/grub-dev.texi (Finding your way around): Update for 1.99 diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index 425458401..e2aa79759 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -120,7 +120,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) @@ -379,7 +379,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 8b8a81fa6a600c743ef0a34122f127671a5a5bfc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Apr 2011 13:56:23 +0200 Subject: [PATCH 0841/1414] Dynamically count the number of lines for the lower banner. * grub-core/normal/menu_entry.c (per_term_screen): New member num_entries. (print_down): Use num_entries. (update_screen): Likewise. (grub_menu_entry_run): Set num_entries. * grub-core/normal/menu_text.c (menu_viewer_data): New member num_entries. (grub_print_message_indented): Move real part to ... (grub_print_message_indented_real): ... here. Additional argument dry_run. (draw_border): Additional argument num_entries. (print_message): Additional argument dry_run. (print_entries): Receive menu viewer data. (grub_menu_init_page): New argment num_entries. (menu_text_set_chosen_entry): Use num_entries. (grub_menu_try_text): Likewise. * grub-core/normal/term.c (print_ucs4_terminal): New argument dry_run. All users updated. (grub_ucs4_count_lines): New function. * include/grub/term.h (grub_term_cursor_x): Moved from here .. * grub-core/normal/menu_text.c (grub_term_cursor_x): ... to here. * include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): Removed. (grub_term_border_height): Likewise. (grub_term_num_entries): Likewise. --- ChangeLog | 29 +++++++ grub-core/normal/menu_entry.c | 20 ++--- grub-core/normal/menu_text.c | 145 +++++++++++++++++++++------------- grub-core/normal/term.c | 136 +++++++++++++++++++------------ include/grub/normal.h | 7 +- include/grub/term.h | 26 ------ 6 files changed, 225 insertions(+), 138 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1bb8cf278..3f4913ec1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2011-04-10 Vladimir Serbinenko + + Dynamically count the number of lines for the lower banner. + + * grub-core/normal/menu_entry.c (per_term_screen): New member + num_entries. + (print_down): Use num_entries. + (update_screen): Likewise. + (grub_menu_entry_run): Set num_entries. + * grub-core/normal/menu_text.c (menu_viewer_data): New member + num_entries. + (grub_print_message_indented): Move real part to ... + (grub_print_message_indented_real): ... here. Additional argument + dry_run. + (draw_border): Additional argument num_entries. + (print_message): Additional argument dry_run. + (print_entries): Receive menu viewer data. + (grub_menu_init_page): New argment num_entries. + (menu_text_set_chosen_entry): Use num_entries. + (grub_menu_try_text): Likewise. + * grub-core/normal/term.c (print_ucs4_terminal): New argument dry_run. + All users updated. + (grub_ucs4_count_lines): New function. + * include/grub/term.h (grub_term_cursor_x): Moved from here .. + * grub-core/normal/menu_text.c (grub_term_cursor_x): ... to here. + * include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): Removed. + (grub_term_border_height): Likewise. + (grub_term_num_entries): Likewise. + 2011-04-10 Vladimir Serbinenko * grub-core/boot/mips/yeeloong/fwstart.S: Fix address to error message. diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index 30af2c1dc..dc5ab528f 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -52,6 +52,8 @@ struct per_term_screen int x; /* The Y coordinate. */ int y; + /* Number of entries. */ + int num_entries; }; struct screen @@ -188,7 +190,7 @@ print_down (int flag, struct per_term_screen *term_screen) grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term_screen->term), GRUB_TERM_TOP_BORDER_Y - + grub_term_num_entries (term_screen->term)); + + term_screen->num_entries); if (flag) grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term); @@ -209,13 +211,12 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, struct line *linep; /* Check if scrolling is necessary. */ - if (term_screen->y < 0 || term_screen->y - >= grub_term_num_entries (term_screen->term)) + if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries) { if (term_screen->y < 0) term_screen->y = 0; else - term_screen->y = grub_term_num_entries (term_screen->term) - 1; + term_screen->y = term_screen->num_entries - 1; region_start = 0; region_column = 0; @@ -251,7 +252,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, for (column = 0; column <= linep->len - && y < grub_term_num_entries (term_screen->term); + && y < term_screen->num_entries; column += grub_term_entry_width (term_screen->term), y++) { if (y < 0) @@ -272,7 +273,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, print_line (linep, column, 0, y, term_screen); } - if (y == grub_term_num_entries (term_screen->term)) + if (y == term_screen->num_entries) { if (column <= linep->len || i + 1 < screen->num_lines) down_flag = 1; @@ -282,11 +283,11 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, i++; if (mode == ALL_LINES && i == screen->num_lines) - for (; y < grub_term_num_entries (term_screen->term); y++) + for (; y < term_screen->num_entries; y++) print_empty_line (y, term_screen); } - while (y < grub_term_num_entries (term_screen->term)); + while (y < term_screen->num_entries); /* Draw up and down arrows. */ if (up) @@ -1290,7 +1291,8 @@ grub_menu_entry_run (grub_menu_entry_t entry) } /* Draw the screen. */ for (i = 0; i < screen->nterms; i++) - grub_menu_init_page (0, 1, screen->terms[i].term); + grub_menu_init_page (0, 1, &screen->terms[i].num_entries, + screen->terms[i].term); update_screen_all (screen, 0, 0, 1, 1, ALL_LINES); for (i = 0; i < screen->nterms; i++) grub_term_setcursor (screen->terms[i].term, 1); diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c index fc4a89196..93f0492bc 100644 --- a/grub-core/normal/menu_text.c +++ b/grub-core/normal/menu_text.c @@ -34,10 +34,19 @@ static grub_uint8_t grub_color_menu_highlight; struct menu_viewer_data { int first, offset; + /* The number of entries shown at a time. */ + int num_entries; grub_menu_t menu; struct grub_term_output *term; }; +static inline int +grub_term_cursor_x (struct grub_term_output *term) +{ + return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) + - GRUB_TERM_MARGIN - 1); +} + grub_ssize_t grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, struct grub_term_output *term) @@ -53,30 +62,45 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, return width; } -void -grub_print_message_indented (const char *msg, int margin_left, int margin_right, - struct grub_term_output *term) +static int +grub_print_message_indented_real (const char *msg, int margin_left, + int margin_right, + struct grub_term_output *term, int dry_run) { grub_uint32_t *unicode_msg; grub_uint32_t *last_position; int msg_len; + int ret = 0; msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position); if (msg_len < 0) { - return; + return 0; } - grub_print_ucs4 (unicode_msg, last_position, margin_left, margin_right, term); + if (dry_run) + ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left, + margin_right, term); + else + grub_print_ucs4 (unicode_msg, last_position, margin_left, + margin_right, term); grub_free (unicode_msg); + + return ret; } +void +grub_print_message_indented (const char *msg, int margin_left, int margin_right, + struct grub_term_output *term) +{ + grub_print_message_indented_real (msg, margin_left, margin_right, term, 0); +} static void -draw_border (struct grub_term_output *term) +draw_border (struct grub_term_output *term, int num_entries) { unsigned i; @@ -88,7 +112,7 @@ draw_border (struct grub_term_output *term) grub_putcode (GRUB_UNICODE_HLINE, term); grub_putcode (GRUB_UNICODE_CORNER_UR, term); - for (i = 0; i < (unsigned) grub_term_num_entries (term); i++) + for (i = 0; i < (unsigned) num_entries; i++) { grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1); grub_putcode (GRUB_UNICODE_VLINE, term); @@ -99,7 +123,7 @@ draw_border (struct grub_term_output *term) } grub_term_gotoxy (term, GRUB_TERM_MARGIN, - GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1); + GRUB_TERM_TOP_BORDER_Y + num_entries + 1); grub_putcode (GRUB_UNICODE_CORNER_LL, term); for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++) grub_putcode (GRUB_UNICODE_HLINE, term); @@ -108,22 +132,27 @@ draw_border (struct grub_term_output *term) grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); grub_term_gotoxy (term, GRUB_TERM_MARGIN, - (GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + (GRUB_TERM_TOP_BORDER_Y + num_entries + GRUB_TERM_MARGIN + 1)); } -static void -print_message (int nested, int edit, struct grub_term_output *term) +static int +print_message (int nested, int edit, struct grub_term_output *term, int dry_run) { + int ret = 0; grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); if (edit) { - grub_putcode ('\n', term); - grub_print_message_indented (_("Minimum Emacs-like screen editing is \ + if(dry_run) + ret++; + else + grub_putcode ('\n', term); + ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \ supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \ command-line or ESC to discard edits and return to the GRUB menu."), - STANDARD_MARGIN, STANDARD_MARGIN, term); + STANDARD_MARGIN, STANDARD_MARGIN, + term, dry_run); } else { @@ -134,30 +163,34 @@ command-line or ESC to discard edits and return to the GRUB menu."), msg_translated = grub_xasprintf (msg, GRUB_UNICODE_UPARROW, GRUB_UNICODE_DOWNARROW); if (!msg_translated) - return; - grub_putcode ('\n', term); - grub_print_message_indented (msg_translated, STANDARD_MARGIN, - STANDARD_MARGIN, term); + return 0; + if(dry_run) + ret++; + else + grub_putcode ('\n', term); + ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN, + STANDARD_MARGIN, term, dry_run); grub_free (msg_translated); if (nested) { - grub_print_message_indented + ret += grub_print_message_indented_real (_("Press enter to boot the selected OS, " "\'e\' to edit the commands before booting " "or \'c\' for a command-line. ESC to return previous menu.\n"), - STANDARD_MARGIN, STANDARD_MARGIN, term); + STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); } else { - grub_print_message_indented + ret += grub_print_message_indented_real (_("Press enter to boot the selected OS, " "\'e\' to edit the commands before booting " "or \'c\' for a command-line.\n"), - STANDARD_MARGIN, STANDARD_MARGIN, term); + STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); } } + return ret; } static void @@ -256,52 +289,56 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, } static void -print_entries (grub_menu_t menu, int first, int offset, - struct grub_term_output *term) +print_entries (grub_menu_t menu, const struct menu_viewer_data *data) { grub_menu_entry_t e; int i; - grub_term_gotoxy (term, - GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term), + grub_term_gotoxy (data->term, + GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (data->term), GRUB_TERM_FIRST_ENTRY_Y); - if (first) - grub_putcode (GRUB_UNICODE_UPARROW, term); + if (data->first) + grub_putcode (GRUB_UNICODE_UPARROW, data->term); else - grub_putcode (' ', term); + grub_putcode (' ', data->term); - e = grub_menu_get_entry (menu, first); + e = grub_menu_get_entry (menu, data->first); - for (i = 0; i < grub_term_num_entries (term); i++) + for (i = 0; i < data->num_entries; i++) { - print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term); + print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, data->offset == i, + e, data->term); if (e) e = e->next; } - grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X - + grub_term_border_width (term), - GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)); + grub_term_gotoxy (data->term, GRUB_TERM_LEFT_BORDER_X + + grub_term_border_width (data->term), + GRUB_TERM_TOP_BORDER_Y + data->num_entries); if (e) - grub_putcode (GRUB_UNICODE_DOWNARROW, term); + grub_putcode (GRUB_UNICODE_DOWNARROW, data->term); else - grub_putcode (' ', term); + grub_putcode (' ', data->term); - grub_term_gotoxy (term, grub_term_cursor_x (term), - GRUB_TERM_FIRST_ENTRY_Y + offset); + grub_term_gotoxy (data->term, grub_term_cursor_x (data->term), + GRUB_TERM_FIRST_ENTRY_Y + data->offset); } /* Initialize the screen. If NESTED is non-zero, assume that this menu is run from another menu or a command-line. If EDIT is non-zero, show a message for the menu entry editor. */ void -grub_menu_init_page (int nested, int edit, +grub_menu_init_page (int nested, int edit, int *num_entries, struct grub_term_output *term) { grub_uint8_t old_color_normal, old_color_highlight; + /* 3 lines for timeout message and bottom margin. 2 lines for the border. */ + *num_entries = grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y + - (print_message (nested, edit, term, 1) + 3) - 2; + grub_term_getcolor (term, &old_color_normal, &old_color_highlight); /* By default, use the same colors for the menu. */ @@ -316,9 +353,9 @@ grub_menu_init_page (int nested, int edit, grub_normal_init_page (term); grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight); - draw_border (term); + draw_border (term, *num_entries); grub_term_setcolor (term, old_color_normal, old_color_highlight); - print_message (nested, edit, term); + print_message (nested, edit, term, 0); } static void @@ -359,10 +396,10 @@ menu_text_set_chosen_entry (int entry, void *dataptr) int complete_redraw = 0; data->offset = entry - data->first; - if (data->offset > grub_term_num_entries (data->term) - 1) + if (data->offset > data->num_entries - 1) { - data->first = entry - (grub_term_num_entries (data->term) - 1); - data->offset = grub_term_num_entries (data->term) - 1; + data->first = entry - (data->num_entries - 1); + data->offset = data->num_entries - 1; complete_redraw = 1; } if (data->offset < 0) @@ -372,7 +409,7 @@ menu_text_set_chosen_entry (int entry, void *dataptr) complete_redraw = 1; } if (complete_redraw) - print_entries (data->menu, data->first, data->offset, data->term); + print_entries (data->menu, data); else { print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0, @@ -436,15 +473,17 @@ grub_menu_try_text (struct grub_term_output *term, data->offset = entry; data->first = 0; - if (data->offset > grub_term_num_entries (data->term) - 1) - { - data->first = data->offset - (grub_term_num_entries (data->term) - 1); - data->offset = grub_term_num_entries (data->term) - 1; - } grub_term_setcursor (data->term, 0); - grub_menu_init_page (nested, 0, data->term); - print_entries (menu, data->first, data->offset, data->term); + grub_menu_init_page (nested, 0, &data->num_entries, data->term); + + if (data->offset > data->num_entries - 1) + { + data->first = data->offset - (data->num_entries - 1); + data->offset = data->num_entries - 1; + } + + print_entries (menu, data); grub_term_refresh (data->term); grub_menu_register_viewer (instance); diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index 9c4b491f5..a8b9e6683 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -515,14 +515,16 @@ print_ucs4_terminal (const grub_uint32_t * str, const grub_uint32_t * last_position, int margin_left, int margin_right, struct grub_term_output *term, - struct term_state *state) + struct term_state *state, + int dry_run) { const grub_uint32_t *ptr; - grub_ssize_t startwidth = get_startwidth (term, margin_left); + grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left); grub_ssize_t line_width = startwidth; grub_ssize_t lastspacewidth = 0; grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right); const grub_uint32_t *line_start = str, *last_space = str - 1; + int lines = 0; for (ptr = str; ptr < last_position; ptr++) { @@ -560,50 +562,59 @@ print_ucs4_terminal (const grub_uint32_t * str, else lastspacewidth = line_width - last_width; - for (ptr2 = line_start; ptr2 < ptr; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term); - } + lines++; - grub_print_spaces (term, margin_right); - grub_putcode ('\n', term); - if (state && ++state->num_lines - >= (grub_ssize_t) grub_term_height (term) - 2) + if (!dry_run) { - state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') - ? ptr + 1 : ptr; - state->backlog_len = last_position - state->backlog_ucs4; - return 1; + for (ptr2 = line_start; ptr2 < ptr; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } + + grub_print_spaces (term, margin_right); + grub_putcode ('\n', term); + if (state && ++state->num_lines + >= (grub_ssize_t) grub_term_height (term) - 2) + { + state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') + ? ptr + 1 : ptr; + state->backlog_len = last_position - state->backlog_ucs4; + return 1; + } } line_width -= lastspacewidth; - grub_print_spaces (term, margin_left); + if (!dry_run) + grub_print_spaces (term, margin_left); if (ptr == last_space || *ptr == '\n') ptr++; line_start = ptr; } } - { - const grub_uint32_t *ptr2; - for (ptr2 = line_start; ptr2 < last_position; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term); - } - } - return 0; + if (line_start < last_position) + lines++; + if (!dry_run) + { + const grub_uint32_t *ptr2; + for (ptr2 = line_start; ptr2 < last_position; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + && grub_unicode_get_comb_type (*ptr2) + != GRUB_UNICODE_COMB_NONE) + continue; + putcode_real (*ptr2, term); + } + } + return dry_run ? lines : 0; } static struct term_state * @@ -672,7 +683,7 @@ print_backlog (struct grub_term_output *term, int ret; ret = print_ucs4_terminal (state->backlog_ucs4, state->backlog_ucs4 + state->backlog_len, - margin_left, margin_right, term, state); + margin_left, margin_right, term, state, 0); if (!ret) { grub_free (state->free); @@ -706,15 +717,19 @@ static int print_ucs4_real (const grub_uint32_t * str, const grub_uint32_t * last_position, int margin_left, int margin_right, - struct grub_term_output *term, int backlog) + struct grub_term_output *term, int backlog, + int dry_run) { struct term_state *state = NULL; - if (backlog) - state = find_term_state (term); + if (!dry_run) + { + if (backlog) + state = find_term_state (term); - if (((term->getxy (term) >> 8) & 0xff) < margin_left) - grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff)); + if (((term->getxy (term) >> 8) & 0xff) < margin_left) + grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff)); + } if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS @@ -743,16 +758,30 @@ print_ucs4_real (const grub_uint32_t * str, grub_print_error (); return 0; } - ret = put_glyphs_terminal (visual, visual_len, margin_left, margin_right, - term, state); - if (!ret) - grub_free (visual); + if (dry_run) + { + struct grub_unicode_glyph *vptr; + ret = 0; + for (vptr = visual; vptr < visual + visual_len; vptr++) + if (vptr->base == '\n') + ret++; + if (visual_len && visual[visual_len - 1].base != '\n') + ret++; + grub_free (visual); + } else - state->free = visual; + { + ret = put_glyphs_terminal (visual, visual_len, margin_left, + margin_right, term, state); + if (!ret) + grub_free (visual); + else + state->free = visual; + } return ret; } return print_ucs4_terminal (str, last_position, margin_left, margin_right, - term, state); + term, state, dry_run); } void @@ -762,9 +791,18 @@ grub_print_ucs4 (const grub_uint32_t * str, struct grub_term_output *term) { print_ucs4_real (str, last_position, margin_left, margin_right, - term, 0); + term, 0, 0); } +int +grub_ucs4_count_lines (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term) +{ + return print_ucs4_real (str, last_position, margin_left, margin_right, + term, 0, 1); +} void grub_xputs_normal (const char *str) @@ -813,7 +851,7 @@ grub_xputs_normal (const char *str) { int cur; cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0, - term, grub_more); + term, grub_more, 0); if (cur) backlog = 1; } diff --git a/include/grub/normal.h b/include/grub/normal.h index 3b99e073a..08c14d209 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -51,7 +51,7 @@ extern int grub_normal_exit_level; /* Defined in `main.c'. */ void grub_enter_normal_mode (const char *config); void grub_normal_execute (const char *config, int nested, int batch); -void grub_menu_init_page (int nested, int edit, +void grub_menu_init_page (int nested, int edit, int *num_entries, struct grub_term_output *term); void grub_normal_init_page (struct grub_term_output *term); char *grub_file_getline (grub_file_t file); @@ -80,6 +80,11 @@ grub_print_ucs4 (const grub_uint32_t * str, const grub_uint32_t * last_position, int margin_left, int margin_right, struct grub_term_output *term); +int +grub_ucs4_count_lines (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); grub_ssize_t grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position, struct grub_term_output *term); diff --git a/include/grub/term.h b/include/grub/term.h index dbcb2f52c..726c84dbf 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -140,9 +140,6 @@ grub_term_color_state; /* The X position of the left border. */ #define GRUB_TERM_LEFT_BORDER_X GRUB_TERM_MARGIN -/* The number of lines of messages at the bottom. */ -#define GRUB_TERM_MESSAGE_HEIGHT 8 - /* The Y position of the first entry. */ #define GRUB_TERM_FIRST_ENTRY_Y (GRUB_TERM_TOP_BORDER_Y + 1) @@ -339,29 +336,6 @@ grub_term_entry_width (struct grub_term_output *term) return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1; } -/* The height of the border. */ - -static inline unsigned -grub_term_border_height (struct grub_term_output *term) -{ - return grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y - - GRUB_TERM_MESSAGE_HEIGHT; -} - -/* The number of entries shown at a time. */ -static inline int -grub_term_num_entries (struct grub_term_output *term) -{ - return grub_term_border_height (term) - 2; -} - -static inline int -grub_term_cursor_x (struct grub_term_output *term) -{ - return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) - - GRUB_TERM_MARGIN - 1); -} - static inline grub_uint16_t grub_term_getxy (struct grub_term_output *term) { From 088cdb65eb49582b71fa3ef2065406a37e5f1672 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 10 Apr 2011 15:25:52 +0200 Subject: [PATCH 0842/1414] * grub-core/gnulib/argp-parse.c (__argp_input): Don't crash if pstate is NULL. --- ChangeLog | 5 +++++ grub-core/gnulib/argp-parse.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3f4913ec1..b5ca76ac6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-10 Colin Watson + + * grub-core/gnulib/argp-parse.c (__argp_input): Don't crash if pstate + is NULL. + 2011-04-10 Vladimir Serbinenko Dynamically count the number of lines for the lower banner. diff --git a/grub-core/gnulib/argp-parse.c b/grub-core/gnulib/argp-parse.c index a1cbf884e..9c054653c 100644 --- a/grub-core/gnulib/argp-parse.c +++ b/grub-core/gnulib/argp-parse.c @@ -935,7 +935,7 @@ weak_alias (__argp_parse, argp_parse) void * __argp_input (const struct argp *argp, const struct argp_state *state) { - if (state) + if (state && state->pstate) { struct group *group; struct parser *parser = state->pstate; From cbac5b1eceb008ec6a97f22a88318c1afd17a343 Mon Sep 17 00:00:00 2001 From: Alexander Kurtz Date: Sun, 10 Apr 2011 15:30:45 +0200 Subject: [PATCH 0843/1414] * util/grub-mkconfig_lib.in: Add missing quotes. --- ChangeLog | 4 ++ util/grub-mkconfig_lib.in | 86 +++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5ca76ac6..c86adedb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-10 Alexander Kurtz + + * util/grub-mkconfig_lib.in: Add missing quotes. + 2011-04-10 Colin Watson * grub-core/gnulib/argp-parse.c (__argp_input): Don't crash if pstate diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 628ea34d4..2c5fd8c6f 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -16,19 +16,19 @@ transform="@program_transform_name@" -prefix=@prefix@ -exec_prefix=@exec_prefix@ -datarootdir=@datarootdir@ -datadir=@datadir@ -bindir=@bindir@ -sbindir=@sbindir@ -pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" +datadir="@datadir@" +bindir="@bindir@" +sbindir="@sbindir@" +pkgdatadir="${datadir}/`echo "@PACKAGE_TARNAME@" | sed "${transform}"`" if test "x$grub_probe" = x; then - grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` + grub_probe="${sbindir}/`echo grub-probe | sed "${transform}"`" fi if test "x$grub_mkrelpath" = x; then - grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` + grub_mkrelpath="${bindir}/`echo grub-mkrelpath | sed "${transform}"`" fi if $(which gettext >/dev/null 2>/dev/null) ; then @@ -44,20 +44,20 @@ grub_warn () make_system_path_relative_to_its_root () { - ${grub_mkrelpath} $1 + "${grub_mkrelpath}" "$1" } is_path_readable_by_grub () { - path=$1 + path="$1" # abort if path doesn't exist - if test -e $path ; then : ;else + if test -e "$path" ; then : ;else return 1 fi # abort if file is in a filesystem we can't read - if ${grub_probe} -t fs $path > /dev/null 2>&1 ; then : ; else + if "${grub_probe}" -t fs "$path" > /dev/null 2>&1 ; then : ; else return 1 fi @@ -72,24 +72,24 @@ is_path_readable_by_grub () convert_system_path_to_grub_path () { - path=$1 + path="$1" grub_warn "convert_system_path_to_grub_path() is deprecated. Use prepare_grub_to_access_device() instead." # abort if GRUB can't access the path - if is_path_readable_by_grub ${path} ; then : ; else + if is_path_readable_by_grub "${path}" ; then : ; else return 1 fi - if drive=`${grub_probe} -t drive $path` ; then : ; else + if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else return 1 fi - if relative_path=`make_system_path_relative_to_its_root $path` ; then : ; else + if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else return 1 fi - echo ${drive}${relative_path} + echo "${drive}${relative_path}" } save_default_entry () @@ -103,15 +103,15 @@ EOF prepare_grub_to_access_device () { - device=$1 + device="$1" # Abstraction modules aren't auto-loaded. - abstraction="`${grub_probe} --device ${device} --target=abstraction`" + abstraction="`"${grub_probe}" --device "${device}" --target=abstraction`" for module in ${abstraction} ; do echo "insmod ${module}" done - partmap="`${grub_probe} --device ${device} --target=partmap`" + partmap="`"${grub_probe}" --device "${device}" --target=partmap`" for module in ${partmap} ; do case "${module}" in netbsd | openbsd) @@ -121,15 +121,15 @@ prepare_grub_to_access_device () esac done - fs="`${grub_probe} --device ${device} --target=fs`" + fs="`"${grub_probe}" --device "${device}" --target=fs`" for module in ${fs} ; do echo "insmod ${module}" done # If there's a filesystem UUID that GRUB is capable of identifying, use it; # otherwise set root as per value in device.map. - echo "set root='`${grub_probe} --device ${device} --target=drive`'" - if fs_uuid="`${grub_probe} --device ${device} --target=fs_uuid 2> /dev/null`" ; then + echo "set root='`"${grub_probe}" --device "${device}" --target=drive`'" + if fs_uuid="`"${grub_probe}" --device "${device}" --target=fs_uuid 2> /dev/null`" ; then echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" fi } @@ -149,21 +149,21 @@ grub_file_is_not_garbage () version_test_numeric () { - local a=$1 - local cmp=$2 - local b=$3 + local a="$1" + local cmp="$2" + local b="$3" if [ "$a" = "$b" ] ; then - case $cmp in + case "$cmp" in ge|eq|le) return 0 ;; gt|lt) return 1 ;; esac fi if [ "$cmp" = "lt" ] ; then - c=$a - a=$b - b=$c + c="$a" + a="$b" + b="$c" fi - if (echo $a ; echo $b) | sort -n | head -n 1 | grep -qx $b ; then + if (echo "$a" ; echo "$b") | sort -n | head -n 1 | grep -qx "$b" ; then return 0 else return 1 @@ -172,25 +172,25 @@ version_test_numeric () version_test_gt () { - local a=`echo $1 | sed -e "s/[^-]*-//"` - local b=`echo $2 | sed -e "s/[^-]*-//"` + local a="`echo "$1" | sed -e "s/[^-]*-//"`" + local b="`echo "$2" | sed -e "s/[^-]*-//"`" local cmp=gt if [ "x$b" = "x" ] ; then return 0 fi - case $a:$b in + case "$a:$b" in *.old:*.old) ;; - *.old:*) a=`echo -n $a | sed -e s/\.old$//` ; cmp=gt ;; - *:*.old) b=`echo -n $b | sed -e s/\.old$//` ; cmp=ge ;; + *.old:*) a="`echo -n "$a" | sed -e 's/\.old$//'`" ; cmp=gt ;; + *:*.old) b="`echo -n "$b" | sed -e 's/\.old$//'`" ; cmp=ge ;; esac - version_test_numeric $a $cmp $b - return $? + version_test_numeric "$a" "$cmp" "$b" + return "$?" } version_find_latest () { local a="" - for i in $@ ; do + for i in "$@" ; do if version_test_gt "$i" "$a" ; then a="$i" fi @@ -202,7 +202,7 @@ version_find_latest () # printf; so this turns ' into \'. Note that you must use the output of # this function in a printf format string. gettext_quoted () { - $gettext "$@" | sed "s/'/'\\\\\\\\''/g" + "$gettext" "$@" | sed "s/'/'\\\\\\\\''/g" } # Run the first argument through gettext_quoted, and then pass that and all @@ -215,9 +215,9 @@ gettext_printf () { } uses_abstraction () { - device=$1 + device="$1" - abstraction="`${grub_probe} --device ${device} --target=abstraction`" + abstraction="`"${grub_probe}" --device "${device}" --target=abstraction`" for module in ${abstraction}; do if test "x${module}" = "x$2"; then return 0 From 5ca1a64de674ccc1f03f91ed7a2115140c1f2826 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Apr 2011 16:08:58 +0200 Subject: [PATCH 0844/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_data): New member is_disk. (grub_util_biosdisk_open): Don't apply ioctl on non-disk devices. (open_device) Likewise. (grub_util_biosdisk_close): Likewise. Reported by: Mark Korenberger. --- ChangeLog | 9 +++++++++ grub-core/kern/emu/hostdisk.c | 12 +++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c86adedb0..a7e73f461 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-10 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_data): New member + is_disk. + (grub_util_biosdisk_open): Don't apply ioctl on non-disk devices. + (open_device) Likewise. + (grub_util_biosdisk_close): Likewise. + Reported by: Mark Korenberger. + 2011-04-10 Alexander Kurtz * util/grub-mkconfig_lib.in: Add missing quotes. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 7b034e06b..f01e21aa0 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -138,6 +138,7 @@ struct grub_util_biosdisk_data char *dev; int access_mode; int fd; + int is_disk; }; #ifdef __linux__ @@ -239,6 +240,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) data->dev = NULL; data->access_mode = 0; data->fd = -1; + data->is_disk = 0; /* Get the size. */ #if defined(__MINGW32__) @@ -279,6 +281,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) close (fd); goto fail; } + data->is_disk = 1; # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (ioctl (fd, DIOCGMEDIASIZE, &nr)) @@ -669,7 +672,8 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { fsync (data->fd); #ifdef __linux__ - ioctl (data->fd, BLKFLSBUF, 0); + if (data->is_disk) + ioctl (data->fd, BLKFLSBUF, 0); #endif } @@ -727,7 +731,8 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { fsync (data->fd); #ifdef __linux__ - ioctl (data->fd, BLKFLSBUF, 0); + if (data->is_disk) + ioctl (data->fd, BLKFLSBUF, 0); #endif } close (data->fd); @@ -952,7 +957,8 @@ grub_util_biosdisk_close (struct grub_disk *disk) { fsync (data->fd); #ifdef __linux__ - ioctl (data->fd, BLKFLSBUF, 0); + if (data->is_disk) + ioctl (data->fd, BLKFLSBUF, 0); #endif } close (data->fd); From 335bda1e57c9c5a7325d00817f990e658152161c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Apr 2011 16:12:31 +0200 Subject: [PATCH 0845/1414] * grub-core/boot/mips/yeeloong/fwstart.S (no_cs5536): Put back improperly removed string. --- ChangeLog | 5 +++++ grub-core/boot/mips/yeeloong/fwstart.S | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index a7e73f461..65f42dd6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-10 Vladimir Serbinenko + + * grub-core/boot/mips/yeeloong/fwstart.S (no_cs5536): Put back + improperly removed string. + 2011-04-10 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_data): New member diff --git a/grub-core/boot/mips/yeeloong/fwstart.S b/grub-core/boot/mips/yeeloong/fwstart.S index e2aa79759..9e81df192 100644 --- a/grub-core/boot/mips/yeeloong/fwstart.S +++ b/grub-core/boot/mips/yeeloong/fwstart.S @@ -379,6 +379,7 @@ 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 b01abe3e1679ed31a03a3203e3b9127c847e8d1a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Apr 2011 16:44:11 +0200 Subject: [PATCH 0846/1414] * grub-core/loader/mips/linux.c (grub_cmd_initrd): Use correct limits rather than trying to put initrd way too high. Reported by: Ryan Lortie --- ChangeLog | 6 ++++++ grub-core/loader/mips/linux.c | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65f42dd6a..f3050ef73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-10 Vladimir Serbinenko + + * grub-core/loader/mips/linux.c (grub_cmd_initrd): Use correct limits + rather than trying to put initrd way too high. + Reported by: Ryan Lortie + 2011-04-10 Vladimir Serbinenko * grub-core/boot/mips/yeeloong/fwstart.S (no_cs5536): Put back diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 6ae2a9321..9accfc270 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -379,8 +379,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_align (relocator, &ch, - target_addr + linux_size + 0x10000, - (0xffffffff - size) + 1, + (target_addr & 0x1fffffff) + + linux_size + 0x10000, + (0x10000000 - size), size, 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE); From 5b3633002b9fb95c830a4c339c64a25fa43013ea Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 10 Apr 2011 21:41:55 +0100 Subject: [PATCH 0847/1414] Make grub-mount exit non-zero if opening the device or filesystem fails. Translate GRUB error codes into OS error codes for FUSE. --- util/grub-mount.c | 132 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 41 deletions(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index c1c7ecad8..efada771a 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -44,6 +44,8 @@ #include "argp.h" static char *root = NULL; +grub_device_t dev = NULL; +grub_fs_t fs = NULL; static char **images = NULL; static char *debug_str = NULL; static char **fuse_args = NULL; @@ -62,13 +64,61 @@ execute_command (char *name, int n, char **args) return (cmd->func) (cmd, n, args); } +/* Translate GRUB error numbers into OS error numbers. Print any unexpected + errors. */ +static int +translate_error (void) +{ + int ret; + + switch (grub_errno) + { + case GRUB_ERR_NONE: + ret = 0; + break; + + case GRUB_ERR_OUT_OF_MEMORY: + grub_print_error (); + ret = -ENOMEM; + break; + + case GRUB_ERR_BAD_FILE_TYPE: + /* This could also be EISDIR. Take a guess. */ + ret = -ENOTDIR; + break; + + case GRUB_ERR_FILE_NOT_FOUND: + ret = -ENOENT; + break; + + case GRUB_ERR_FILE_READ_ERROR: + case GRUB_ERR_READ_ERROR: + case GRUB_ERR_IO: + grub_print_error (); + ret = -EIO; + break; + + case GRUB_ERR_SYMLINK_LOOP: + ret = -ELOOP; + break; + + default: + grub_print_error (); + ret = -EINVAL; + break; + } + + /* Any previous errors were handled. */ + grub_errno = GRUB_ERR_NONE; + + return ret; +} + static int fuse_getattr (const char *path, struct stat *st) { char *filename, *pathname, *path2; const char *pathname_t; - grub_fs_t fs; - grub_device_t dev; struct grub_dirhook_info file_info; int file_exists = 0; @@ -104,16 +154,6 @@ fuse_getattr (const char *path, struct stat *st) } file_exists = 0; - dev = grub_device_open (0); - if (! dev) - return -1; - - fs = grub_fs_probe (dev); - if (! fs) - { - grub_device_close (dev); - return -1; - } pathname_t = grub_strchr (path, ')'); if (! pathname_t) @@ -143,10 +183,12 @@ fuse_getattr (const char *path, struct stat *st) /* It's the whole device. */ (fs->dir) (dev, path2, find_file); - grub_device_close (dev); grub_free (path2); if (!file_exists) - return -1; + { + grub_errno = GRUB_ERR_NONE; + return -ENOENT; + } st->st_dev = 0; st->st_ino = 0; st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); @@ -158,10 +200,7 @@ fuse_getattr (const char *path, struct stat *st) grub_file_t file; file = grub_file_open (path); if (! file) - { - grub_print_error (); - return -1; - } + return translate_error (); st->st_size = file->size; grub_file_close (file); } @@ -171,6 +210,7 @@ fuse_getattr (const char *path, struct stat *st) st->st_blocks = (st->st_size + 511) >> 9; st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset ? file_info.mtime : 0; + grub_errno = GRUB_ERR_NONE; return 0; } @@ -190,13 +230,11 @@ fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused))) grub_file_t file; file = grub_file_open (path); if (! file) - { - grub_print_error (); - return -1; - } + return translate_error (); files[first_fd++] = file; fi->fh = first_fd; files[first_fd++] = file; + grub_errno = GRUB_ERR_NONE; return 0; } @@ -205,13 +243,21 @@ fuse_read (const char *path, char *buf, size_t sz, off_t off, struct fuse_file_info *fi) { grub_file_t file = files[fi->fh]; + grub_ssize_t size; if (off > file->size) - return -1; + return -EINVAL; file->offset = off; - return grub_file_read (file, buf, sz); + size = grub_file_read (file, buf, sz); + if (size < 0) + return translate_error (); + else + { + grub_errno = GRUB_ERR_NONE; + return size; + } } static int @@ -219,6 +265,7 @@ fuse_release (const char *path, struct fuse_file_info *fi) { grub_file_close (files[fi->fh]); files[fi->fh] = NULL; + grub_errno = GRUB_ERR_NONE; return 0; } @@ -227,8 +274,6 @@ fuse_readdir (const char *path, void *buf, fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) { char *pathname; - grub_fs_t fs; - grub_device_t dev; auto int call_fill (const char *filename, const struct grub_dirhook_info *info); @@ -238,19 +283,6 @@ fuse_readdir (const char *path, void *buf, return 0; } - dev = grub_device_open (0); - if (! dev) - { - return 1; - } - - fs = grub_fs_probe (dev); - if (! fs) - { - grub_device_close (dev); - return 1; - } - pathname = xstrdup (path); /* Remove trailing '/'. */ @@ -259,8 +291,8 @@ fuse_readdir (const char *path, void *buf, pathname[grub_strlen (pathname) - 1] = 0; (fs->dir) (dev, pathname, call_fill); - grub_device_close (dev); free (pathname); + grub_errno = GRUB_ERR_NONE; return 0; } @@ -273,7 +305,7 @@ struct fuse_operations grub_opers = { .read = fuse_read }; -static void +static grub_err_t fuse_init (void) { int i; @@ -310,6 +342,17 @@ fuse_init (void) grub_mdraid1x_init (); grub_lvm_init (); + dev = grub_device_open (0); + if (! dev) + return grub_errno; + + fs = grub_fs_probe (dev); + if (! fs) + { + grub_device_close (dev); + return grub_errno; + } + fuse_main (fuse_argc, fuse_args, &grub_opers, NULL); for (i = 0; i < num_disks; i++) @@ -328,6 +371,8 @@ fuse_init (void) grub_free (loop_name); } + + return GRUB_ERR_NONE; } static struct argp_option options[] = { @@ -447,6 +492,11 @@ main (int argc, char *argv[]) /* Do it. */ fuse_init (); + if (grub_errno) + { + grub_print_error (); + return 1; + } /* Free resources. */ grub_fini_all (); From 4ac93e6c4f8137a32a9591caf9cf7e2af234c12b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 10 Apr 2011 22:12:23 +0100 Subject: [PATCH 0848/1414] add grub-mount to .bzrignore --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 0cbb3f17f..d4d5987ec 100644 --- a/.bzrignore +++ b/.bzrignore @@ -44,6 +44,7 @@ grub-kbdcomp grub-macho2img grub-menulst2cfg grub-mk* +grub-mount grub-pbkdf2 grub-pe2elf grub-probe From 9ee8d94faa182cb25eac7b5a15e29e122fe7fbc2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:38:42 +0200 Subject: [PATCH 0849/1414] * grub-core/kern/file.c (grub_file_open): Don't take into account the parenthesis in the middle of the filename. --- ChangeLog | 5 +++++ grub-core/kern/file.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f3050ef73..46f683cb6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-11 Vladimir Serbinenko + + * grub-core/kern/file.c (grub_file_open): Don't take into account the + parenthesis in the middle of the filename. + 2011-04-10 Vladimir Serbinenko * grub-core/loader/mips/linux.c (grub_cmd_initrd): Use correct limits diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index c93fbf737..9d5a51c48 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -68,7 +68,7 @@ grub_file_open (const char *name) goto fail; /* Get the file part of NAME. */ - file_name = grub_strchr (name, ')'); + file_name = (name[0] == '(') ? grub_strchr (name, ')') : NULL; if (file_name) file_name++; else From af869a4ab9755cdc3fbbcaf639b88b386bbe395d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:40:53 +0200 Subject: [PATCH 0850/1414] * util/grub-fstest.c (read_file): Report GRUB error if file opening failed. --- ChangeLog | 5 +++++ util/grub-fstest.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 46f683cb6..cbb77c14c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-11 Vladimir Serbinenko + + * util/grub-fstest.c (read_file): Report GRUB error if file opening + failed. + 2011-04-11 Vladimir Serbinenko * grub-core/kern/file.c (grub_file_open): Don't take into account the diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 2fcde4ab0..51c1a3a52 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -111,7 +111,8 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) file = grub_file_open (pathname); if (!file) { - grub_util_error (_("cannot open file %s"), pathname); + grub_util_error (_("cannot open file %s:%s"), pathname, + grub_errmsg); return; } From 8a3bc88ea740221ae56afdd1545327f45280f112 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:41:59 +0200 Subject: [PATCH 0851/1414] * util/grub-fstest.c (cmd_cmp): Check that sizes match. --- ChangeLog | 4 ++++ util/grub-fstest.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index cbb77c14c..dbcbb9651 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-11 Vladimir Serbinenko + + * util/grub-fstest.c (cmd_cmp): Check that sizes match. + 2011-04-11 Vladimir Serbinenko * util/grub-fstest.c (read_file): Report GRUB error if file opening diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 51c1a3a52..293bdf74a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -222,6 +222,14 @@ cmd_cmp (char *src, char *dest) grub_util_error (_("seek error")); read_file (src, cmp_hook); + + { + grub_uint64_t pre; + pre = ftell (ff); + fseek (ff, 0, SEEK_END); + if (pre != ftell (ff)) + grub_util_error (_("unexpected end of file")); + } fclose (ff); } From e8980227e8e3df225dfecd9bb98d5ea515d7b041 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:49:26 +0200 Subject: [PATCH 0852/1414] Remove stale comment about redundancy --- grub-core/fs/btrfs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7632d535c..16aa0742a 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -662,7 +662,6 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, } case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: case GRUB_BTRFS_CHUNK_TYPE_RAID1: - /* FIXME: Use redundancy. */ { stripen = 0; stripe_offset = off; @@ -686,7 +685,6 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, break; } case GRUB_BTRFS_CHUNK_TYPE_RAID10: - /* FIXME: Use redundancy. */ { grub_uint64_t middle, high; grub_uint32_t low; From ec25b87d2904ef8ea1417bb0e61397c008e1b7f1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:50:22 +0200 Subject: [PATCH 0853/1414] Add dprintfs to report chunk lookups --- grub-core/fs/btrfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 16aa0742a..fb7469b67 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -589,6 +589,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, struct grub_btrfs_key key_out; int challoc = 0; grub_device_t dev; + grub_dprintf ("btrfs", "searching for laddr %" PRIxGRUB_UINT64_T "\n", + addr); for (ptr = data->sblock.bootstrap_mapping; ptr < data->sblock.bootstrap_mapping + sizeof (data->sblock.bootstrap_mapping) @@ -647,6 +649,16 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, unsigned redundancy = 1; unsigned i, j; + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ")\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu64 (chunk->stripe_length)); + switch (grub_le_to_cpu64 (chunk->type) & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE) { From 228f95a2502a35a5a2e9a8a8eab0e66fa2c515ad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:51:15 +0200 Subject: [PATCH 0854/1414] Fix filename comparison --- grub-core/fs/btrfs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index fb7469b67..add590dfb 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1103,12 +1103,9 @@ find_path (struct grub_btrfs_data *data, + grub_le_to_cpu16 (cdirel->n) + grub_le_to_cpu16 (cdirel->m))) { - char c; - c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; - cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; - if (grub_strncmp (cdirel->name, ctoken, ctokenlen) == 0) + if (ctokenlen == grub_le_to_cpu16 (cdirel->n) + && grub_memcmp (cdirel->name, ctoken, ctokenlen) == 0) break; - cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; } if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl >= (grub_ssize_t) elemsize) From 565f0763118ac5d7789f4a85075e8f013f13ac69 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:52:39 +0200 Subject: [PATCH 0855/1414] Take extent offset in account on uncompressed extents --- grub-core/fs/btrfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index add590dfb..7b1888502 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -989,6 +989,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + + grub_le_to_cpu64 (data->extent->offset) + extoff, buf, csize); if (err) From 6a01f54affc70b25a0a0507775ba159423402387 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 07:53:21 +0200 Subject: [PATCH 0856/1414] use actually filled extent size if available --- grub-core/fs/btrfs.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7b1888502..0b0e5259c 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -83,6 +83,7 @@ struct grub_btrfs_data /* Cached extent data. */ grub_uint64_t extstart; + grub_uint64_t extend; grub_uint64_t extino; grub_uint64_t exttree; grub_size_t extsize; @@ -202,6 +203,7 @@ struct grub_btrfs_extent_data grub_uint64_t laddr; grub_uint64_t compressed_size; grub_uint64_t offset; + grub_uint64_t filled; }; }; } __attribute__ ((packed)); @@ -872,12 +874,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_err_t err; grub_off_t extoff; if (!data->extent || data->extstart > pos || data->extino != ino - || data->exttree != tree - || grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) + || data->exttree != tree || data->extend <= pos) { struct grub_btrfs_key key_in, key_out; grub_disk_addr_t elemaddr; grub_size_t elemsize; + grub_free (data->extent); key_in.object_id = ino; key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; @@ -904,15 +906,29 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, data->extent, elemsize); if (err) return err; - if (grub_le_to_cpu64 (data->extent->size) + data->extstart <= pos) - return grub_error (GRUB_ERR_BAD_FS, "extent not found"); + + data->extend = data->extstart + + grub_le_to_cpu64 (data->extent->size); + if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR + && (char *) &data->extent + elemsize + >= (char *) &data->extent->filled + + sizeof (data->extent->filled)) + data->extend = data->extstart + + grub_le_to_cpu64 (data->extent->filled); + grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" - PRIxGRUB_UINT64_T "\n", + PRIxGRUB_UINT64_T " (0x%" + PRIxGRUB_UINT64_T ")\n", grub_le_to_cpu64 (key_out.offset), - grub_le_to_cpu64 (data->extent->size)); + grub_le_to_cpu64 (data->extent->size), + grub_le_to_cpu64 (data->extent->filled)); + if (data->extend <= pos) + { + grub_error (GRUB_ERR_BAD_FS, "extent not found"); + return -1; + } } - csize = grub_le_to_cpu64 (data->extent->size) - + grub_le_to_cpu64 (data->extstart) - pos; + csize = data->extend - pos; extoff = pos - data->extstart; if (csize > len) csize = len; From 3dd3dd335fe8efb23d54bfbc322701d54c28a65d Mon Sep 17 00:00:00 2001 From: Feiran Zheng Date: Mon, 11 Apr 2011 08:16:13 +0200 Subject: [PATCH 0857/1414] 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 0858/1414] 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 0859/1414] 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 0860/1414] 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 2a9bc0169eced59e03dde36de0958c4d3bf06ee0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 11 Apr 2011 16:06:37 +0100 Subject: [PATCH 0861/1414] * grub-core/fs/btrfs.c (grub_btrfs_fs) [GRUB_UTIL]: Set reserved_first_sector to 1. btrfs reserves plenty of space for boot loaders. Reported by: Gene Cumm. Fixes Ubuntu bug #757446. --- ChangeLog | 7 +++++++ grub-core/fs/btrfs.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index dbcbb9651..295a23d1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-04-11 Colin Watson + + * grub-core/fs/btrfs.c (grub_btrfs_fs) [GRUB_UTIL]: Set + reserved_first_sector to 1. btrfs reserves plenty of space for boot + loaders. + Reported by: Gene Cumm. Fixes Ubuntu bug #757446. + 2011-04-11 Vladimir Serbinenko * util/grub-fstest.c (cmd_cmp): Check that sizes match. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 179891da8..11b8dba33 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -122,6 +122,9 @@ static struct grub_fs grub_btrfs_fs = .dir = grub_btrfs_dir, .open = grub_btrfs_open, .uuid = grub_btrfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif }; GRUB_MOD_INIT(btrfs) From 48fe18dcf2d2003846046a808d984a4db0a336ba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 18:13:00 +0200 Subject: [PATCH 0862/1414] exfat reader --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/exfat.c | 2 + grub-core/fs/fat.c | 369 ++++++++++++++++++++++++++++++++++-- 4 files changed, 359 insertions(+), 18 deletions(-) create mode 100644 grub-core/fs/exfat.c diff --git a/Makefile.util.def b/Makefile.util.def index 303baea3f..a1d00a683 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -53,6 +53,7 @@ library = { common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; common = grub-core/fs/fat.c; + common = grub-core/fs/exfat.c; common = grub-core/fs/fshelp.c; common = grub-core/fs/hfs.c; common = grub-core/fs/hfsplus.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7c26b37e9..3ec41ac7f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -923,6 +923,11 @@ module = { common = fs/fat.c; }; +module = { + name = exfat; + common = fs/exfat.c; +}; + module = { name = fshelp; common = fs/fshelp.c; diff --git a/grub-core/fs/exfat.c b/grub-core/fs/exfat.c new file mode 100644 index 000000000..fe149ddd3 --- /dev/null +++ b/grub-core/fs/exfat.c @@ -0,0 +1,2 @@ +#define MODE_EXFAT 1 +#include "fat.c" diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 89050943c..5f7a58571 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -32,23 +32,54 @@ #define GRUB_FAT_ATTR_READ_ONLY 0x01 #define GRUB_FAT_ATTR_HIDDEN 0x02 #define GRUB_FAT_ATTR_SYSTEM 0x04 +#ifndef MODE_EXFAT #define GRUB_FAT_ATTR_VOLUME_ID 0x08 +#endif #define GRUB_FAT_ATTR_DIRECTORY 0x10 #define GRUB_FAT_ATTR_ARCHIVE 0x20 #define GRUB_FAT_MAXFILE 256 +#ifndef MODE_EXFAT #define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \ | GRUB_FAT_ATTR_HIDDEN \ | GRUB_FAT_ATTR_SYSTEM \ | GRUB_FAT_ATTR_VOLUME_ID) -#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \ - | GRUB_FAT_ATTR_HIDDEN \ - | GRUB_FAT_ATTR_SYSTEM \ - | GRUB_FAT_ATTR_DIRECTORY \ - | GRUB_FAT_ATTR_ARCHIVE \ - | GRUB_FAT_ATTR_VOLUME_ID) +#endif +static const grub_uint8_t GRUB_FAT_ATTR_VALID = (GRUB_FAT_ATTR_READ_ONLY + | GRUB_FAT_ATTR_HIDDEN + | GRUB_FAT_ATTR_SYSTEM + | GRUB_FAT_ATTR_DIRECTORY + | GRUB_FAT_ATTR_ARCHIVE +#ifndef MODE_EXFAT + | GRUB_FAT_ATTR_VOLUME_ID +#endif + ); +#ifdef MODE_EXFAT +struct grub_fat_bpb +{ + grub_uint8_t jmp_boot[3]; + grub_uint8_t oem_name[8]; + grub_uint8_t mbz[53]; + grub_uint64_t num_hidden_sectors; + grub_uint64_t num_total_sectors; + grub_uint32_t num_reserved_sectors; + grub_uint32_t sectors_per_fat; + grub_uint32_t cluster_offset; + grub_uint32_t cluster_count; + grub_uint32_t root_cluster; + grub_uint32_t num_serial; + grub_uint16_t fs_revision; + grub_uint16_t volume_flags; + grub_uint8_t bytes_per_sector_shift; + grub_uint8_t sectors_per_cluster_shift; + grub_uint8_t num_fats; + grub_uint8_t num_ph_drive; + grub_uint8_t reserved[8]; +} __attribute__ ((packed)); + +#else struct grub_fat_bpb { grub_uint8_t jmp_boot[3]; @@ -94,7 +125,64 @@ struct grub_fat_bpb } __attribute__ ((packed)) fat32; } __attribute__ ((packed)) version_specific; } __attribute__ ((packed)); +#endif +#ifdef MODE_EXFAT +struct grub_fat_dir_entry +{ + grub_uint8_t entry_type; + union + { + grub_uint8_t placeholder[31]; + struct { + grub_uint8_t secondary_count; + grub_uint16_t checksum; + grub_uint16_t attr; + grub_uint16_t reserved1; + grub_uint32_t c_time; + grub_uint32_t m_time; + grub_uint32_t a_time; + grub_uint8_t c_time_tenth; + grub_uint8_t m_time_tenth; + grub_uint8_t a_time_tenth; + grub_uint8_t reserved2[9]; + } __attribute__ ((packed)) file; + struct { + grub_uint8_t flags; + grub_uint8_t reserved1; + grub_uint8_t name_length; + grub_uint16_t name_hash; + grub_uint16_t reserved2; + grub_uint64_t valid_size; + grub_uint32_t reserved3; + grub_uint32_t first_cluster; + grub_uint64_t file_size; + } __attribute__ ((packed)) stream_extension; + struct { + grub_uint8_t flags; + grub_uint16_t str[15]; + } __attribute__ ((packed)) file_name; + struct { + grub_uint8_t character_count; + grub_uint16_t str[11]; + grub_uint8_t reserved[8]; + } __attribute__ ((packed)) volume_label; + } __attribute__ ((packed)) type_specific; +} __attribute__ ((packed)); + +struct grub_fat_dir_node +{ + grub_uint32_t attr; + grub_uint32_t first_cluster; + grub_uint64_t file_size; + grub_uint64_t valid_size; + int have_stream; + int is_label; +}; + +typedef struct grub_fat_dir_node grub_fat_dir_node_t; + +#else struct grub_fat_dir_entry { grub_uint8_t name[11]; @@ -123,6 +211,10 @@ struct grub_fat_long_name_entry grub_uint16_t name3[2]; } __attribute__ ((packed)); +typedef struct grub_fat_dir_entry grub_fat_dir_node_t; + +#endif + struct grub_fat_data { int logical_sector_bits; @@ -133,8 +225,10 @@ struct grub_fat_data int fat_size; grub_uint32_t root_cluster; +#ifndef MODE_EXFAT grub_uint32_t root_sector; grub_uint32_t num_root_sectors; +#endif int cluster_bits; grub_uint32_t cluster_eof_mark; @@ -152,6 +246,7 @@ struct grub_fat_data static grub_dl_t my_mod; +#ifndef MODE_EXFAT static int fat_log2 (unsigned x) { @@ -168,6 +263,7 @@ fat_log2 (unsigned x) return i; } +#endif static struct grub_fat_data * grub_fat_mount (grub_disk_t disk) @@ -187,20 +283,37 @@ grub_fat_mount (grub_disk_t disk) if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb)) goto fail; +#ifdef MODE_EXFAT + if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ", + sizeof (bpb.oem_name)) != 0) + goto fail; +#else 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)) goto fail; +#endif + + grub_dprintf ("exfat", "alive\n"); /* Get the sizes of logical sectors and clusters. */ +#ifdef MODE_EXFAT + data->logical_sector_bits = bpb.bytes_per_sector_shift; +#else data->logical_sector_bits = fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); - if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS) +#endif + if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS + || data->logical_sector_bits >= 16) goto fail; data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS; +#ifdef MODE_EXFAT + data->cluster_bits = bpb.sectors_per_cluster_shift; +#else data->cluster_bits = fat_log2 (bpb.sectors_per_cluster); - if (data->cluster_bits < 0) +#endif + if (data->cluster_bits < 0 || data->cluster_bits > 25) goto fail; data->cluster_bits += data->logical_sector_bits; @@ -210,18 +323,28 @@ grub_fat_mount (grub_disk_t disk) if (data->fat_sector == 0) goto fail; +#ifdef MODE_EXFAT + data->sectors_per_fat = (grub_le_to_cpu32 (bpb.sectors_per_fat) + << data->logical_sector_bits); +#else data->sectors_per_fat = ((bpb.sectors_per_fat_16 ? grub_le_to_cpu16 (bpb.sectors_per_fat_16) : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)) << data->logical_sector_bits); +#endif if (data->sectors_per_fat == 0) goto fail; /* Get the number of sectors in this volume. */ +#ifdef MODE_EXFAT + data->num_sectors = ((grub_le_to_cpu64 (bpb.num_total_sectors)) + << data->logical_sector_bits); +#else data->num_sectors = ((bpb.num_total_sectors_16 ? grub_le_to_cpu16 (bpb.num_total_sectors_16) : grub_le_to_cpu32 (bpb.num_total_sectors_32)) << data->logical_sector_bits); +#endif if (data->num_sectors == 0) goto fail; @@ -229,6 +352,9 @@ grub_fat_mount (grub_disk_t disk) if (bpb.num_fats == 0) goto fail; + grub_dprintf ("exfat", "alive\n"); + +#ifndef MODE_EXFAT data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat; data->num_root_sectors = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries) @@ -236,15 +362,36 @@ grub_fat_mount (grub_disk_t disk) + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1) >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS)) << (data->logical_sector_bits)); +#endif +#ifdef MODE_EXFAT + data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset) + << data->logical_sector_bits); + data->num_clusters = (grub_le_to_cpu32 (bpb.cluster_count) + << data->logical_sector_bits); +#else data->cluster_sector = data->root_sector + data->num_root_sectors; data->num_clusters = (((data->num_sectors - data->cluster_sector) >> (data->cluster_bits + data->logical_sector_bits)) + 2); +#endif if (data->num_clusters <= 2) goto fail; +#ifdef MODE_EXFAT + { + /* exFAT. */ + grub_uint16_t flags = grub_le_to_cpu16 (bpb.volume_flags); + + data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster); + data->fat_size = 32; + data->cluster_eof_mark = 0xffffffff; + + if ((flags & 0x1) && bpb.num_fats > 1) + data->fat_sector += data->sectors_per_fat; + } +#else if (! bpb.sectors_per_fat_16) { /* FAT32. */ @@ -286,6 +433,7 @@ grub_fat_mount (grub_disk_t disk) data->cluster_eof_mark = 0xfff8; } } +#endif /* More sanity checks. */ if (data->num_sectors <= data->fat_sector) @@ -317,17 +465,23 @@ grub_fat_mount (grub_disk_t disk) } /* Serial number. */ +#ifdef MODE_EXFAT + data->uuid = grub_le_to_cpu32 (bpb.num_serial); +#else if (bpb.sectors_per_fat_16) data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial); else data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial); +#endif +#ifndef MODE_EXFAT /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media descriptor, even if it is a so-called superfloppy (e.g. an USB key). The check may be too strict for this kind of stupid BIOSes, as they overwrite the media descriptor. */ if ((first_fat | 0x8) != (magic | bpb.media | 0x8)) goto fail; +#endif /* Start from the root directory. */ data->file_cluster = data->root_cluster; @@ -354,6 +508,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, grub_ssize_t ret = 0; unsigned long sector; +#ifndef MODE_EXFAT /* This is a special case. FAT12 and FAT16 doesn't have the root directory in clusters. */ if (data->file_cluster == ~0U) @@ -367,6 +522,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, return size; } +#endif /* Calculate the logical cluster number and offset. */ logical_cluster_bits = (data->cluster_bits @@ -465,13 +621,115 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, return ret; } +#ifdef MODE_EXFAT +static grub_err_t +grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, + int (*hook) (const char *filename, + grub_fat_dir_node_t *node)) +{ + struct grub_fat_dir_entry dir; + grub_ssize_t offset = -sizeof(dir); + grub_uint16_t *unibuf; + char *filename; + + unibuf = grub_malloc (15 * 256 * 2); + filename = grub_malloc (15 * 256 * 4 + 1); + + while (1) + { + offset += sizeof (dir); + + if (grub_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + break; + + if (dir.entry_type == 0) + break; + if (!(dir.entry_type & 0x80)) + continue; + + if (dir.entry_type == 0x85) + { + unsigned i, nsec, slots = 0; + grub_fat_dir_node_t node; + + nsec = dir.type_specific.file.secondary_count; + + node.attr = grub_cpu_to_le32 (dir.type_specific.file.attr); + node.have_stream = 0; + for (i = 0; i < nsec; i++) + { + struct grub_fat_dir_entry sec; + offset += sizeof (sec); + if (grub_fat_read_data (disk, data, 0, + offset, sizeof (sec), (char *) &sec) + != sizeof (sec)) + break; + if (!(sec.entry_type & 0x80)) + continue; + if (!(sec.entry_type & 0x40)) + break; + switch (sec.entry_type) + { + case 0xc0: + node.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster); + node.valid_size + = grub_cpu_to_le32 (sec.type_specific.stream_extension.valid_size); + node.file_size + = grub_cpu_to_le32 (sec.type_specific.stream_extension.file_size); + node.have_stream = 1; + break; + case 0xc1: + grub_memcpy (unibuf + slots * 15, + sec.type_specific.file_name.str, 30); + slots++; + break; + default: + grub_printf ("unknown secondary type 0x%02x\n", sec.entry_type); + } + } + + if (i != nsec) + { + offset -= sizeof (dir); + continue; + } + + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf, + slots * 15) = '\0'; + + if (hook (filename, &node)) + break; + continue; + } + /* Allocation bitmap. */ + if (dir.entry_type == 0x81) + continue; + /* Upcase table. */ + if (dir.entry_type == 0x82) + continue; + /* Volume label. */ + if (dir.entry_type == 0x83) + continue; + grub_printf ("unknown primary type 0x%02x\n", dir.entry_type); + } + grub_free (filename); + grub_free (unibuf); + + return grub_errno; +} + +#else + static grub_err_t grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, int (*hook) (const char *filename, struct grub_fat_dir_entry *dir)) { struct grub_fat_dir_entry dir; - char *filename, *filep = 0; + char *filename; + char *filep = 0; grub_uint16_t *unibuf; int slot = -1, slots = -1; int checksum = -1; @@ -498,10 +756,11 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, offset += sizeof (dir); /* Read a directory entry. */ - if ((grub_fat_read_data (disk, data, 0, + if (grub_fat_read_data (disk, data, 0, offset, sizeof (dir), (char *) &dir) - != sizeof (dir) || dir.name[0] == 0)) + != sizeof (dir) || dir.name[0] == 0) break; + /* Handle long name entries. */ if (dir.attr == GRUB_FAT_ATTR_LONG_NAME) { @@ -586,7 +845,6 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, filep++; } *filep = '\0'; - if (hook (filename, &dir)) break; } @@ -596,7 +854,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, return grub_errno; } - +#endif /* Find the underlying directory or file in PATH and return the next path. If there is no next path or an error occurs, return NULL. @@ -611,8 +869,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, int call_hook; int found = 0; - auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir); - int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) + auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir); + int iter_hook (const char *filename, grub_fat_dir_node_t *dir) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -620,8 +878,13 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY); info.case_insensitive = 1; +#ifdef MODE_EXFAT + if (!dir->have_stream) + return 0; +#else if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID) return 0; +#endif if (*dirname == '\0' && call_hook) return hook (filename, &info); @@ -629,9 +892,14 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, { found = 1; data->attr = dir->attr; +#ifdef MODE_EXFAT + data->file_size = dir->file_size; + data->file_cluster = dir->first_cluster; +#else data->file_size = grub_le_to_cpu32 (dir->file_size); data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16) | grub_le_to_cpu16 (dir->first_cluster_low)); +#endif data->cur_cluster_num = ~0U; if (call_hook) @@ -781,14 +1049,61 @@ grub_fat_close (grub_file_t file) return grub_errno; } +#ifdef MODE_EXFAT +static grub_err_t +grub_fat_label (grub_device_t device, char **label) +{ + struct grub_fat_dir_entry dir; + grub_ssize_t offset = -sizeof(dir); + struct grub_fat_data *data; + grub_disk_t disk = device->disk; + + data = grub_fat_mount (disk); + if (! data) + return grub_errno; + + while (1) + { + offset += sizeof (dir); + + if (grub_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + break; + + if (dir.entry_type == 0) + break; + if (!(dir.entry_type & 0x80)) + continue; + + /* Volume label. */ + if (dir.entry_type == 0x83) + { + grub_size_t chc; + *label = grub_malloc (11 * 4 + 1); + if (!*label) + return grub_errno; + chc = dir.type_specific.volume_label.character_count; + if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str)) + chc = ARRAY_SIZE (dir.type_specific.volume_label.str); + *grub_utf16_to_utf8 ((grub_uint8_t *) *label, + dir.type_specific.volume_label.str, chc) = '\0'; + } + } + + return grub_errno; +} + +#else + static grub_err_t grub_fat_label (grub_device_t device, char **label) { struct grub_fat_data *data; grub_disk_t disk = device->disk; - auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir); - int iter_hook (const char *filename, struct grub_fat_dir_entry *dir) + auto int iter_hook (const char *filename, grub_fat_dir_node_t *dir); + int iter_hook (const char *filename, grub_fat_dir_node_t *dir) { if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID) { @@ -823,6 +1138,8 @@ grub_fat_label (grub_device_t device, char **label) return grub_errno; } +#endif + static grub_err_t grub_fat_uuid (grub_device_t device, char **uuid) { @@ -850,7 +1167,11 @@ grub_fat_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_fat_fs = { +#ifdef MODE_EXFAT + .name = "exfat", +#else .name = "fat", +#endif .dir = grub_fat_dir, .open = grub_fat_open, .read = grub_fat_read, @@ -858,18 +1179,30 @@ static struct grub_fs grub_fat_fs = .label = grub_fat_label, .uuid = grub_fat_uuid, #ifdef GRUB_UTIL +#ifdef MODE_EXFAT + /* ExFAT BPB is 30 larger than FAT32 one. */ + .reserved_first_sector = 0, +#else .reserved_first_sector = 1, +#endif #endif .next = 0 }; +#ifdef MODE_EXFAT +GRUB_MOD_INIT(exfat) +#else GRUB_MOD_INIT(fat) +#endif { grub_fs_register (&grub_fat_fs); my_mod = mod; } - +#ifdef MODE_EXFAT +GRUB_MOD_FINI(exfat) +#else GRUB_MOD_FINI(fat) +#endif { grub_fs_unregister (&grub_fat_fs); } From b6929f5ef598a6d76129fc1915a87bdcf7c62fb8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 20:38:08 +0200 Subject: [PATCH 0863/1414] Transform exfat printfs into dprintfs --- grub-core/fs/fat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 5f7a58571..49bb3a599 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -686,7 +686,8 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, slots++; break; default: - grub_printf ("unknown secondary type 0x%02x\n", sec.entry_type); + grub_dprintf ("exfat", "unknown secondary type 0x%02x\n", + sec.entry_type); } } @@ -712,7 +713,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, /* Volume label. */ if (dir.entry_type == 0x83) continue; - grub_printf ("unknown primary type 0x%02x\n", dir.entry_type); + grub_dprintf ("exfat", "unknown primary type 0x%02x\n", dir.entry_type); } grub_free (filename); grub_free (unibuf); From e745cf0ca64f94fa072d777cde8186aca2b78c1f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 23:01:51 +0200 Subject: [PATCH 0864/1414] Implement automatic module license checking according to new GNU guidelines. * grub-core/kern/dl.c (grub_dl_check_license): New function. (grub_dl_load_core): Use grub_dl_check_license. * include/grub/dl.h (GRUB_MOD_SECTION): New macro. (GRUB_MOD_LICENSE): Likewise. (GRUB_MOD_DUAL_LICENSE): Likewise. All modules updated. --- ChangeLog | 12 +++++++ grub-core/bus/cs5536.c | 4 +++ grub-core/bus/pci.c | 2 ++ grub-core/bus/usb/emu/usb.c | 2 ++ grub-core/bus/usb/ohci.c | 2 ++ grub-core/bus/usb/serial/common.c | 3 ++ grub-core/bus/usb/serial/ftdi.c | 2 ++ grub-core/bus/usb/serial/pl2303.c | 2 ++ grub-core/bus/usb/uhci.c | 2 ++ grub-core/bus/usb/usb.c | 2 ++ grub-core/commands/acpi.c | 2 ++ grub-core/commands/blocklist.c | 2 ++ grub-core/commands/boot.c | 2 ++ grub-core/commands/cat.c | 2 ++ grub-core/commands/cmp.c | 2 ++ grub-core/commands/configfile.c | 2 ++ grub-core/commands/date.c | 2 ++ grub-core/commands/echo.c | 2 ++ grub-core/commands/efi/fixvideo.c | 2 ++ grub-core/commands/efi/loadbios.c | 2 ++ grub-core/commands/efi/lsefimmap.c | 2 ++ grub-core/commands/efi/lsefisystab.c | 3 ++ grub-core/commands/efi/lssal.c | 3 ++ grub-core/commands/extcmd.c | 3 ++ grub-core/commands/gptsync.c | 2 ++ grub-core/commands/halt.c | 2 ++ grub-core/commands/hashsum.c | 2 ++ grub-core/commands/hdparm.c | 2 ++ grub-core/commands/help.c | 2 ++ grub-core/commands/hexdump.c | 2 ++ grub-core/commands/i386/cmostest.c | 2 ++ grub-core/commands/i386/cpuid.c | 2 ++ grub-core/commands/i386/pc/drivemap.c | 1 + grub-core/commands/i386/pc/halt.c | 2 ++ grub-core/commands/i386/pc/lsapm.c | 2 ++ grub-core/commands/i386/pc/play.c | 2 ++ grub-core/commands/i386/pc/pxecmd.c | 2 ++ grub-core/commands/i386/pc/sendkey.c | 2 ++ grub-core/commands/ieee1275/suspend.c | 2 ++ grub-core/commands/iorw.c | 2 ++ grub-core/commands/keylayouts.c | 2 ++ grub-core/commands/keystatus.c | 2 ++ grub-core/commands/legacycfg.c | 2 ++ grub-core/commands/loadenv.c | 2 ++ grub-core/commands/ls.c | 2 ++ grub-core/commands/lsacpi.c | 2 ++ grub-core/commands/lsmmap.c | 2 ++ grub-core/commands/lspci.c | 2 ++ grub-core/commands/memrw.c | 2 ++ grub-core/commands/minicmd.c | 2 ++ grub-core/commands/mips/yeeloong/lsspd.c | 2 ++ grub-core/commands/parttool.c | 2 ++ grub-core/commands/password.c | 2 ++ grub-core/commands/password_pbkdf2.c | 2 ++ grub-core/commands/probe.c | 2 ++ grub-core/commands/read.c | 2 ++ grub-core/commands/reboot.c | 2 ++ grub-core/commands/regexp.c | 2 ++ grub-core/commands/search.c | 2 ++ grub-core/commands/search_wrap.c | 2 ++ grub-core/commands/setpci.c | 2 ++ grub-core/commands/sleep.c | 2 ++ grub-core/commands/terminal.c | 2 ++ grub-core/commands/test.c | 2 ++ grub-core/commands/testload.c | 2 ++ grub-core/commands/true.c | 2 ++ grub-core/commands/usbtest.c | 2 ++ grub-core/commands/videoinfo.c | 2 ++ grub-core/commands/videotest.c | 2 ++ grub-core/commands/xnu_uuid.c | 2 ++ grub-core/disk/ata.c | 2 ++ grub-core/disk/ata_pthru.c | 1 + grub-core/disk/dmraid_nvidia.c | 2 ++ grub-core/disk/i386/pc/biosdisk.c | 2 ++ grub-core/disk/ieee1275/nand.c | 2 ++ grub-core/disk/loopback.c | 2 ++ grub-core/disk/lvm.c | 2 ++ grub-core/disk/mdraid1x_linux.c | 2 ++ grub-core/disk/mdraid_linux.c | 2 ++ grub-core/disk/memdisk.c | 2 ++ grub-core/disk/raid.c | 2 ++ grub-core/disk/raid5_recover.c | 2 ++ grub-core/disk/raid6_recover.c | 2 ++ grub-core/disk/scsi.c | 2 ++ grub-core/disk/usbms.c | 2 ++ grub-core/efiemu/main.c | 2 ++ grub-core/font/font.c | 2 ++ grub-core/fs/affs.c | 2 ++ grub-core/fs/afs.c | 2 ++ grub-core/fs/btrfs.c | 2 ++ grub-core/fs/cpio.c | 2 ++ grub-core/fs/ext2.c | 2 ++ grub-core/fs/fat.c | 2 ++ grub-core/fs/fshelp.c | 2 ++ grub-core/fs/hfs.c | 2 ++ grub-core/fs/hfsplus.c | 2 ++ grub-core/fs/i386/pc/pxe.c | 2 ++ grub-core/fs/iso9660.c | 2 ++ grub-core/fs/jfs.c | 2 ++ grub-core/fs/minix.c | 2 ++ grub-core/fs/nilfs2.c | 2 ++ grub-core/fs/ntfs.c | 2 ++ grub-core/fs/ntfscomp.c | 2 ++ grub-core/fs/reiserfs.c | 2 ++ grub-core/fs/sfs.c | 2 ++ grub-core/fs/udf.c | 2 ++ grub-core/fs/ufs.c | 2 ++ grub-core/fs/xfs.c | 2 ++ grub-core/fs/zfs/zfs.c | 2 ++ grub-core/fs/zfs/zfsinfo.c | 2 ++ grub-core/gentrigtables.c | 8 +++++ grub-core/gettext/gettext.c | 2 ++ grub-core/gfxmenu/gfxmenu.c | 2 ++ grub-core/gnulib/regex.c | 3 ++ grub-core/hello/hello.c | 2 ++ grub-core/hook/datehook.c | 2 ++ grub-core/io/bufio.c | 3 ++ grub-core/io/gzio.c | 2 ++ grub-core/io/xzio.c | 2 ++ grub-core/kern/dl.c | 43 ++++++++++++++++++++++- grub-core/kern/elf.c | 3 ++ grub-core/lib/cmos_datetime.c | 3 ++ grub-core/lib/crypto.c | 3 ++ grub-core/lib/pbkdf2.c | 3 ++ grub-core/lib/relocator.c | 3 ++ grub-core/loader/aout.c | 2 ++ grub-core/loader/efi/appleloader.c | 2 ++ grub-core/loader/efi/chainloader.c | 2 ++ grub-core/loader/i386/bsd.c | 2 ++ grub-core/loader/i386/linux.c | 2 ++ grub-core/loader/i386/pc/chainloader.c | 2 ++ grub-core/loader/i386/pc/linux.c | 2 ++ grub-core/loader/i386/pc/ntldr.c | 2 ++ grub-core/loader/mips/linux.c | 2 ++ grub-core/loader/multiboot.c | 2 ++ grub-core/loader/powerpc/ieee1275/linux.c | 2 ++ grub-core/loader/sparc64/ieee1275/linux.c | 2 ++ grub-core/loader/xnu.c | 2 ++ grub-core/mmap/mmap.c | 2 ++ grub-core/normal/main.c | 2 ++ grub-core/partmap/acorn.c | 2 ++ grub-core/partmap/amiga.c | 2 ++ grub-core/partmap/apple.c | 2 ++ grub-core/partmap/bsdlabel.c | 2 ++ grub-core/partmap/gpt.c | 2 ++ grub-core/partmap/msdos.c | 2 ++ grub-core/partmap/sun.c | 2 ++ grub-core/partmap/sunpc.c | 2 ++ grub-core/parttool/msdospart.c | 2 ++ grub-core/term/at_keyboard.c | 2 ++ grub-core/term/gfxterm.c | 2 ++ grub-core/term/i386/pc/vga_text.c | 2 ++ grub-core/term/serial.c | 2 ++ grub-core/term/terminfo.c | 2 ++ grub-core/term/usb_keyboard.c | 2 ++ grub-core/tests/example_functional_test.c | 3 ++ grub-core/tests/lib/functional_test.c | 3 ++ grub-core/tests/test_blockarg.c | 2 ++ grub-core/video/bitmap.c | 2 ++ grub-core/video/bitmap_scale.c | 3 ++ grub-core/video/bochs.c | 2 ++ grub-core/video/cirrus.c | 2 ++ grub-core/video/efi_gop.c | 2 ++ grub-core/video/efi_uga.c | 2 ++ grub-core/video/emu/sdl.c | 2 ++ grub-core/video/fb/video_fb.c | 3 ++ grub-core/video/i386/pc/vbe.c | 2 ++ grub-core/video/i386/pc/vga.c | 2 ++ grub-core/video/ieee1275.c | 2 ++ grub-core/video/readers/jpeg.c | 2 ++ grub-core/video/readers/png.c | 2 ++ grub-core/video/readers/tga.c | 2 ++ grub-core/video/video.c | 2 ++ include/grub/dl.h | 24 +++++++++++++ util/import_gcry.py | 7 +++- 175 files changed, 447 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 295a23d1a..a3d1e7f92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-04-11 Vladimir Serbinenko + + Implement automatic module license checking according to new GNU + guidelines. + + * grub-core/kern/dl.c (grub_dl_check_license): New function. + (grub_dl_load_core): Use grub_dl_check_license. + * include/grub/dl.h (GRUB_MOD_SECTION): New macro. + (GRUB_MOD_LICENSE): Likewise. + (GRUB_MOD_DUAL_LICENSE): Likewise. + All modules updated. + 2011-04-11 Colin Watson * grub-core/fs/btrfs.c (grub_btrfs_fs) [GRUB_UTIL]: Set diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index 088f4dfc1..fbcb83cfe 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -22,6 +22,10 @@ #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + int grub_cs5536_find (grub_pci_device_t *devp) { diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index 11101d42b..07d20e3f5 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -21,6 +21,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* FIXME: correctly support 64-bit architectures. */ /* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */ struct grub_pci_dma_chunk * diff --git a/grub-core/bus/usb/emu/usb.c b/grub-core/bus/usb/emu/usb.c index 7d52decb2..38c5f01f1 100644 --- a/grub-core/bus/usb/emu/usb.c +++ b/grub-core/bus/usb/emu/usb.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_usb_controller_dev usb_controller = { diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index 8adaee6e0..df0d0f4af 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_ohci_hcca { /* Pointers to Interrupt Endpoint Descriptors. Not used by diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c index ee8794de0..55d1884cc 100644 --- a/grub-core/bus/usb/serial/common.c +++ b/grub-core/bus/usb/serial/common.c @@ -18,6 +18,9 @@ #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); void grub_usbserial_fini (struct grub_serial_port *port) diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c index bd1713b27..07ac7ac52 100644 --- a/grub-core/bus/usb/serial/ftdi.c +++ b/grub-core/bus/usb/serial/ftdi.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + enum { GRUB_FTDI_MODEM_CTRL = 0x01, diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c index 9e3b9ae7e..b9954116b 100644 --- a/grub-core/bus/usb/serial/pl2303.c +++ b/grub-core/bus/usb/serial/pl2303.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Convert speed to divisor. */ static grub_uint32_t is_speed_supported (unsigned int speed) diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 71142846b..99e597f6d 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_UHCI_IOMASK (0x7FF << 5) #define N_QH 256 diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c index 70173b7ea..005d3bcf0 100644 --- a/grub-core/bus/usb/usb.c +++ b/grub-core/bus/usb/usb.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_usb_controller_dev_t grub_usb_list; static struct grub_usb_attach_desc *attach_hooks; diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index 4f03997e0..8f4429627 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -33,6 +33,8 @@ #include #endif +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"exclude", 'x', 0, N_("Don't load host tables specified by comma-separated list."), diff --git a/grub-core/commands/blocklist.c b/grub-core/commands/blocklist.c index 4651fb32a..5eb12e434 100644 --- a/grub-core/commands/blocklist.c +++ b/grub-core/commands/blocklist.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c index 1ec1e6f77..7714011bf 100644 --- a/grub-core/commands/boot.c +++ b/grub-core/commands/boot.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t (*grub_loader_boot_func) (void); static grub_err_t (*grub_loader_unload_func) (void); static int grub_loader_noreturn; diff --git a/grub-core/commands/cat.c b/grub-core/commands/cat.c index 79ecf75c7..9be6cbc8f 100644 --- a/grub-core/commands/cat.c +++ b/grub-core/commands/cat.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0}, diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c index d9e76a4d7..0222927b6 100644 --- a/grub-core/commands/cmp.c +++ b/grub-core/commands/cmp.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define BUFFER_SIZE 512 static grub_err_t diff --git a/grub-core/commands/configfile.c b/grub-core/commands/configfile.c index 2568b7ee6..124a09a9e 100644 --- a/grub-core/commands/configfile.c +++ b/grub-core/commands/configfile.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_source (grub_command_t cmd, int argc, char **args) { diff --git a/grub-core/commands/date.c b/grub-core/commands/date.c index 623db4943..d27162077 100644 --- a/grub-core/commands/date.c +++ b/grub-core/commands/date.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_DATETIME_SET_YEAR 1 #define GRUB_DATETIME_SET_MONTH 2 #define GRUB_DATETIME_SET_DAY 4 diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c index 93a452fc8..81ba50d68 100644 --- a/grub-core/commands/echo.c +++ b/grub-core/commands/echo.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {0, 'n', 0, N_("Do not output the trailing newline."), 0, 0}, diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c index 6430be5e3..c53e47d8a 100644 --- a/grub-core/commands/efi/fixvideo.c +++ b/grub-core/commands/efi/fixvideo.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_video_patch { const char *name; diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c index 8c7c25abd..138311222 100644 --- a/grub-core/commands/efi/loadbios.c +++ b/grub-core/commands/efi/loadbios.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID; static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID; diff --git a/grub-core/commands/efi/lsefimmap.c b/grub-core/commands/efi/lsefimmap.c index 2bb5dcb5d..215b45bff 100644 --- a/grub-core/commands/efi/lsefimmap.c +++ b/grub-core/commands/efi/lsefimmap.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define ADD_MEMORY_DESCRIPTOR(desc, size) \ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c index aa3e05aee..b2359253a 100644 --- a/grub-core/commands/efi/lsefisystab.c +++ b/grub-core/commands/efi/lsefisystab.c @@ -18,12 +18,15 @@ */ #include #include +#include #include #include #include #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct guid_mapping { grub_efi_guid_t guid; diff --git a/grub-core/commands/efi/lssal.c b/grub-core/commands/efi/lssal.c index 2ee993033..fa8005b88 100644 --- a/grub-core/commands/efi/lssal.c +++ b/grub-core/commands/efi/lssal.c @@ -23,6 +23,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); static void disp_sal (void *table) diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c index e9274fbab..69574e2b0 100644 --- a/grub-core/commands/extcmd.c +++ b/grub-core/commands/extcmd.c @@ -22,6 +22,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); grub_err_t grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, diff --git a/grub-core/commands/gptsync.c b/grub-core/commands/gptsync.c index 6364c13f7..e92dc20ec 100644 --- a/grub-core/commands/gptsync.c +++ b/grub-core/commands/gptsync.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Convert a LBA address to a CHS address in the INT 13 format. */ /* Taken from grub1. */ /* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63. diff --git a/grub-core/commands/halt.c b/grub-core/commands/halt.c index 3400115a0..317f7753f 100644 --- a/grub-core/commands/halt.c +++ b/grub-core/commands/halt.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index 664fe9c24..6825d4811 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING}, {"check", 'c', 0, N_("Check hash list file."), N_("FILE"), ARG_TYPE_STRING}, diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c index b6ab78755..0c12b8814 100644 --- a/grub-core/commands/hdparm.c +++ b/grub-core/commands/hdparm.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"apm", 'B', 0, N_("Set Advanced Power Management\n" "(1=low, ..., 254=high, 255=off)."), diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c index ff6d7ed2e..82f3200c7 100644 --- a/grub-core/commands/help.c +++ b/grub-core/commands/help.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, char **args) diff --git a/grub-core/commands/hexdump.c b/grub-core/commands/hexdump.c index 629f2a069..9ba83598a 100644 --- a/grub-core/commands/hexdump.c +++ b/grub-core/commands/hexdump.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"skip", 's', 0, N_("Skip offset bytes from the beginning of file."), 0, ARG_TYPE_INT}, diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index 994da11b0..c79bd0387 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -21,6 +21,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t parse_args (int argc, char *argv[], int *byte, int *bit) { diff --git a/grub-core/commands/i386/cpuid.c b/grub-core/commands/i386/cpuid.c index f5f0f15a8..6a771ba74 100644 --- a/grub-core/commands/i386/cpuid.c +++ b/grub-core/commands/i386/cpuid.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define cpuid(num,a,b,c,d) \ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index ed4211cca..c9c8881b4 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -29,6 +29,7 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */ static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13); diff --git a/grub-core/commands/i386/pc/halt.c b/grub-core/commands/i386/pc/halt.c index 81eb6a1bb..e7c191de3 100644 --- a/grub-core/commands/i386/pc/halt.c +++ b/grub-core/commands/i386/pc/halt.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"no-apm", 'n', 0, N_("Do not use APM to halt the computer."), 0, 0}, diff --git a/grub-core/commands/i386/pc/lsapm.c b/grub-core/commands/i386/pc/lsapm.c index 30475d2ec..17bcfd6eb 100644 --- a/grub-core/commands/i386/pc/lsapm.c +++ b/grub-core/commands/i386/pc/lsapm.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + int grub_apm_get_info (struct grub_apm_info *info) { diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c index 4ed937d4a..57980eb92 100644 --- a/grub-core/commands/i386/pc/play.c +++ b/grub-core/commands/i386/pc/play.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define BASE_TEMPO (60 * GRUB_TICKS_PER_SECOND) /* The speaker port. */ diff --git a/grub-core/commands/i386/pc/pxecmd.c b/grub-core/commands/i386/pc/pxecmd.c index b576a8ea4..dffa15a3a 100644 --- a/grub-core/commands/i386/pc/pxecmd.c +++ b/grub-core/commands/i386/pc/pxecmd.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index c777ea60a..a55d17bd0 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv2+"); + static char sendkey[0x20]; /* Length of sendkey. */ static int keylen = 0; diff --git a/grub-core/commands/ieee1275/suspend.c b/grub-core/commands/ieee1275/suspend.c index f096cc9ba..de068951d 100644 --- a/grub-core/commands/ieee1275/suspend.c +++ b/grub-core/commands/ieee1275/suspend.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c index 20d203e92..e7035b528 100644 --- a/grub-core/commands/iorw.c +++ b/grub-core/commands/iorw.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword; static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c index deb482a85..6c5913a54 100644 --- a/grub-core/commands/keylayouts.c +++ b/grub-core/commands/keylayouts.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_keyboard_layout layout_us = { .keyboard_map = { /* Keyboard errors. Handled by driver. */ diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c index 9e1486c9d..f3a669942 100644 --- a/grub-core/commands/keystatus.c +++ b/grub-core/commands/keystatus.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"shift", 's', 0, N_("Check Shift key."), 0, 0}, diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 23c1c1908..e68b3315a 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -33,6 +33,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t legacy_file (const char *filename) { diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index 38b3a84c6..5d53a8e66 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME}, diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 481d17db0..5fc648a9b 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -32,6 +32,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"long", 'l', 0, N_("Show a long list with more detailed information."), 0, 0}, diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c index 64b559665..fd19e380a 100644 --- a/grub-core/commands/lsacpi.c +++ b/grub-core/commands/lsacpi.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static void print_strn (grub_uint8_t *str, grub_size_t len) { diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c index 657f81387..44598f0df 100644 --- a/grub-core/commands/lsmmap.c +++ b/grub-core/commands/lsmmap.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const char *names[] = { [GRUB_MEMORY_AVAILABLE] = "available", diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c index fd2d4eaf2..03541df6c 100644 --- a/grub-core/commands/lspci.c +++ b/grub-core/commands/lspci.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_pci_classname { int class; diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c index 28aac7d81..3b51189d6 100644 --- a/grub-core/commands/memrw.c +++ b/grub-core/commands/memrw.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword; static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c index 5cf109fde..c7d1ec4f5 100644 --- a/grub-core/commands/minicmd.c +++ b/grub-core/commands/minicmd.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* cat FILE */ static grub_err_t grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)), diff --git a/grub-core/commands/mips/yeeloong/lsspd.c b/grub-core/commands/mips/yeeloong/lsspd.c index 539cda34c..c1c5e2ef7 100644 --- a/grub-core/commands/mips/yeeloong/lsspd.c +++ b/grub-core/commands/mips/yeeloong/lsspd.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index 31e768553..a54286161 100644 --- a/grub-core/commands/parttool.c +++ b/grub-core/commands/parttool.c @@ -31,6 +31,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv2+"); + static struct grub_parttool *parts = 0; static int curhandle = 0; static grub_dl_t mymod; diff --git a/grub-core/commands/password.c b/grub-core/commands/password.c index db5951cbb..8821607b8 100644 --- a/grub-core/commands/password.c +++ b/grub-core/commands/password.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static grub_err_t diff --git a/grub-core/commands/password_pbkdf2.c b/grub-core/commands/password_pbkdf2.c index 6886987da..05a627219 100644 --- a/grub-core/commands/password_pbkdf2.c +++ b/grub-core/commands/password_pbkdf2.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; struct pbkdf2_password diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index 3ace596d8..c5f946340 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -32,6 +32,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"set", 's', 0, diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c index 6a187fc3e..fe3e88b15 100644 --- a/grub-core/commands/read.c +++ b/grub-core/commands/read.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static char * grub_getline (void) { diff --git a/grub-core/commands/reboot.c b/grub-core/commands/reboot.c index eedd53c91..8e18083c0 100644 --- a/grub-core/commands/reboot.c +++ b/grub-core/commands/reboot.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c index 83c0d8d43..1e8a6f309 100644 --- a/grub-core/commands/regexp.c +++ b/grub-core/commands/regexp.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { { "set", 's', GRUB_ARG_OPTION_REPEATABLE, diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c index f265f86d6..ba80d80ef 100644 --- a/grub-core/commands/search.c +++ b/grub-core/commands/search.c @@ -31,6 +31,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + void FUNC_NAME (const char *key, const char *var, int no_floppy, char **hints, unsigned nhints) diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 80741d7ab..7b0a99565 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"file", 'f', 0, N_("Search devices by a file."), 0, 0}, diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index 88dfa4c08..70f5bcdad 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct pci_register { const char *name; diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c index da642fcd9..97e7a40a6 100644 --- a/grub-core/commands/sleep.c +++ b/grub-core/commands/sleep.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const struct grub_arg_option options[] = { {"verbose", 'v', 0, N_("Verbose countdown."), 0, 0}, diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c index c2d9550f6..0adfd3d2e 100644 --- a/grub-core/commands/terminal.c +++ b/grub-core/commands/terminal.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_term_autoload *grub_term_input_autoload = NULL; struct grub_term_autoload *grub_term_output_autoload = NULL; diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c index e981c945a..50d5aba5e 100644 --- a/grub-core/commands/test.c +++ b/grub-core/commands/test.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* A simple implementation for signed numbers. */ static int grub_strtosl (char *arg, char **end, int base) diff --git a/grub-core/commands/testload.c b/grub-core/commands/testload.c index 86b8a9253..fe06f3d1e 100644 --- a/grub-core/commands/testload.c +++ b/grub-core/commands/testload.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), int argc, char *argv[]) diff --git a/grub-core/commands/true.c b/grub-core/commands/true.c index aa8125853..82775e7ef 100644 --- a/grub-core/commands/true.c +++ b/grub-core/commands/true.c @@ -21,6 +21,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_true (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c index 7f00c8856..4a051ad1f 100644 --- a/grub-core/commands/usbtest.c +++ b/grub-core/commands/usbtest.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static const char *usb_classes[] = { "Unknown", diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 10f77915b..3e0c1a12e 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static unsigned height, width, depth; static int diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c index 435ac2937..dc7a6485f 100644 --- a/grub-core/commands/videotest.c +++ b/grub-core/commands/videotest.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) diff --git a/grub-core/commands/xnu_uuid.c b/grub-core/commands/xnu_uuid.c index 382d3196b..f618b4ec0 100644 --- a/grub-core/commands/xnu_uuid.c +++ b/grub-core/commands/xnu_uuid.c @@ -34,6 +34,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* This prefix is used by xnu and boot-132 to hash together with volume serial. */ static grub_uint8_t hash_prefix[16] diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index fe677e2a0..7f261560d 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* At the moment, only two IDE ports are supported. */ static const grub_port_t grub_ata_ioaddress[] = { GRUB_ATA_CH0_PORT1, GRUB_ATA_CH1_PORT1 }; diff --git a/grub-core/disk/ata_pthru.c b/grub-core/disk/ata_pthru.c index f52725a49..eb9cb5f85 100644 --- a/grub-core/disk/ata_pthru.c +++ b/grub-core/disk/ata_pthru.c @@ -22,6 +22,7 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); /* ATA pass through support, used by hdparm.mod. */ static grub_err_t diff --git a/grub-core/disk/dmraid_nvidia.c b/grub-core/disk/dmraid_nvidia.c index d3f45935c..154193eb0 100644 --- a/grub-core/disk/dmraid_nvidia.c +++ b/grub-core/disk/dmraid_nvidia.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define NV_SIGNATURES 4 #define NV_IDLE 0 diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 069bb0b59..1d47dc727 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static int cd_drive = 0; static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap); diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c index a2c717cdb..e9450167e 100644 --- a/grub-core/disk/ieee1275/nand.c +++ b/grub-core/disk/ieee1275/nand.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_nand_data { grub_ieee1275_ihandle_t handle; diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index 939043f01..d50f353b1 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_loopback { char *devname; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 00c6d8f9b..206e3e220 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -28,6 +28,8 @@ #include #endif +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_lvm_vg *vg_list; static int lv_count; diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index e30878365..19c43f455 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Linux RAID on disk structures and constants, copied from include/linux/raid/md_p.h. */ diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index 06d3498a8..691d100b8 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -27,6 +27,8 @@ /* Linux RAID on disk structures and constants, copied from include/linux/raid/md_p.h. */ +GRUB_MOD_LICENSE ("GPLv3+"); + #define RESERVED_BYTES (64 * 1024) #define RESERVED_SECTORS (RESERVED_BYTES / 512) diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index e00280dd7..114ac0d9e 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static char *memdisk_addr; static grub_off_t memdisk_size = 0; diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index ac2b9fefe..3c74bba99 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -27,6 +27,8 @@ #include #endif +GRUB_MOD_LICENSE ("GPLv3+"); + /* Linked list of RAID arrays. */ static struct grub_raid_array *array_list; grub_raid5_recover_func_t grub_raid5_recover_func; diff --git a/grub-core/disk/raid5_recover.c b/grub-core/disk/raid5_recover.c index 349eb0291..c26d05e94 100644 --- a/grub-core/disk/raid5_recover.c +++ b/grub-core/disk/raid5_recover.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_raid5_recover (struct grub_raid_array *array, int disknr, char *buf, grub_disk_addr_t sector, int size) diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index dfaa60ea4..25b50eb6b 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_uint8_t raid6_table1[256][256]; static grub_uint8_t raid6_table2[256][256]; diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index a40de278f..25f0e3aea 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_scsi_dev_t grub_scsi_dev_list; diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c index fcfe9e5d4..2f1dbd487 100644 --- a/grub-core/disk/usbms.c +++ b/grub-core/disk/usbms.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_USBMS_DIRECTION_BIT 7 /* The USB Mass Storage Command Block Wrapper. */ diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index da813b00d..772db2956 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -32,6 +32,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* System table. Two version depending on mode */ grub_efi_system_table32_t *grub_efiemu_system_table32 = 0; grub_efi_system_table64_t *grub_efiemu_system_table64 = 0; diff --git a/grub-core/font/font.c b/grub-core/font/font.c index b5ec43bb2..ef6caf77b 100644 --- a/grub-core/font/font.c +++ b/grub-core/font/font.c @@ -30,6 +30,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef USE_ASCII_FAILBACK #include "ascii.h" #endif diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 40be4b2f6..1c4f80ec0 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* The affs bootblock. */ struct grub_affs_bblock { diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index cd61f4db9..35ef49937 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef MODE_BIGENDIAN #define GRUB_AFS_FSNAME_SUFFIX "_be" #else diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 11b8dba33..3e73837d9 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define BTRFS_SIGNATURE "_BHRfS_M" struct btrfs_superblock diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 2c92404c3..a7ccfbded 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifndef MODE_USTAR /* cpio support */ #define MAGIC_BCPIO 070707 diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c index 9d7bbfd36..0fdf151a2 100644 --- a/grub-core/fs/ext2.c +++ b/grub-core/fs/ext2.c @@ -51,6 +51,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Log2 size of ext2 block in 512 blocks. */ #define LOG2_EXT2_BLOCK_SIZE(data) \ (grub_le_to_cpu32 (data->sblock.log2_block_size) + 1) diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 89050943c..76b9c52d7 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_FAT_DIR_ENTRY_SIZE 32 #define GRUB_FAT_ATTR_READ_ONLY 0x01 diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c index d0b1e493e..f879885ac 100644 --- a/grub-core/fs/fshelp.c +++ b/grub-core/fs/fshelp.c @@ -22,7 +22,9 @@ #include #include #include +#include +GRUB_MOD_LICENSE ("GPLv3+"); /* Lookup the node PATH. The node ROOTNODE describes the root of the directory tree. The node found is returned in FOUNDNODE, which is diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index cef856326..1f67ea155 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_HFS_SBLOCK 2 #define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 7d7115ce3..304b32126 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -30,6 +30,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_HFSPLUS_MAGIC 0x482B #define GRUB_HFSPLUSX_MAGIC 0x4858 #define GRUB_HFSPLUS_SBLOCK 2 diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index c800ea2ad..d6dc2c22d 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -30,6 +30,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define SEGMENT(x) ((x) >> 4) #define OFFSET(x) ((x) & 0xF) #define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index f72249d20..a9a17fef8 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_ISO9660_FSTYPE_DIR 0040000 #define GRUB_ISO9660_FSTYPE_REG 0100000 #define GRUB_ISO9660_FSTYPE_SYMLINK 0120000 diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 6857c4a2c..72e6adc74 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_JFS_MAX_SYMLNK_CNT 8 #define GRUB_JFS_FILETYPE_MASK 0170000 #define GRUB_JFS_FILETYPE_REG 0100000 diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 679e1ec51..523e6e616 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef MODE_MINIX2 #define GRUB_MINIX_MAGIC 0x2468 #define GRUB_MINIX_MAGIC_30 0x2478 diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index e529775f4..4c8d7633c 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -35,6 +35,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define NILFS_INODE_BMAP_SIZE 7 #define NILFS_SUPORT_REV 2 diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 414f6513d..e01ce34c2 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; ntfscomp_func_t grub_ntfscomp_func; diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c index c29979edc..d2893cb99 100644 --- a/grub-core/fs/ntfscomp.c +++ b/grub-core/fs/ntfscomp.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t decomp_nextvcn (struct grub_ntfs_comp *cc) { diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c index e92279554..f2984f845 100644 --- a/grub-core/fs/reiserfs.c +++ b/grub-core/fs/reiserfs.c @@ -39,6 +39,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define MIN(a, b) \ ({ typeof (a) _a = (a); \ typeof (b) _b = (b); \ diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index b49420de1..455743117 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* The common header for a block. */ struct grub_sfs_bheader { diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 1672aab1b..5842d5d12 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_UDF_MAX_PDS 2 #define GRUB_UDF_MAX_PMS 6 diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 2b1021db6..86fe8af65 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef MODE_UFS2 #define GRUB_UFS_MAGIC 0x19540119 #else diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 9f8dc28de..2eadc3768 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define XFS_INODE_EXTENTS 9 #define XFS_INODE_FORMAT_INO 1 diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8e83ea0b5..8d86cf9e5 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -52,6 +52,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define ZPOOL_PROP_BOOTFS "bootfs" #define MIN(a,b) (((a) < (b)) ? (a) : (b)) diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 224a97792..1968ed554 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static inline void print_tabs (int n) { diff --git a/grub-core/gentrigtables.c b/grub-core/gentrigtables.c index bef2b083c..8c039570d 100644 --- a/grub-core/gentrigtables.c +++ b/grub-core/gentrigtables.c @@ -30,6 +30,14 @@ main (int argc __attribute__ ((unused)), int i; printf ("#include \n"); + printf ("#include \n"); + printf ("\n"); + + printf ("/* Under copyright legislature such automated output isn't\n"); + printf ("covered by any copyright. Hence it's public domain. Public\n"); + printf ("domain works can be dual-licenced with any license. */\n"); + printf ("GRUB_MOD_LICENSE (\"GPLv3+\");"); + printf ("GRUB_MOD_DUAL_LICENSE (\"Public Domain\");"); #define TAB(op) \ printf ("grub_int16_t grub_trig_" #op "tab[] =\n{"); \ diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 84937f19b..cca8b901f 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* .mo file information from: http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html . diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c index 564a87634..2f210e02b 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/grub-core/gfxmenu/gfxmenu.c @@ -37,6 +37,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_gfxmenu_view_t cached_view; static void diff --git a/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c index ba0eebee7..4c2243f64 100644 --- a/grub-core/gnulib/regex.c +++ b/grub-core/gnulib/regex.c @@ -19,6 +19,9 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); /* Make sure noone compiles this code with a C++ compiler. */ #if defined __cplusplus && defined _LIBC diff --git a/grub-core/hello/hello.c b/grub-core/hello/hello.c index 77c4c96b1..2c9e90f72 100644 --- a/grub-core/hello/hello.c +++ b/grub-core/hello/hello.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t grub_cmd_hello (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc __attribute__ ((unused)), diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c index d855311d3..f64fac074 100644 --- a/grub-core/hook/datehook.c +++ b/grub-core/hook/datehook.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static char *grub_datetime_names[] = { "YEAR", diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c index 891fb78e9..3b456c1d2 100644 --- a/grub-core/io/bufio.c +++ b/grub-core/io/bufio.c @@ -23,6 +23,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_BUFIO_DEF_SIZE 8192 #define GRUB_BUFIO_MAX_SIZE 1048576 diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 47df23833..ad185dcab 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -42,6 +42,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* * Window Size * diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index 3daf6a3fe..1f42cd242 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #include "xz.h" #include "xz_stream.h" diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 02d785b9b..c5e2888cd 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -373,6 +373,38 @@ grub_dl_call_init (grub_dl_t mod) (mod->init) (mod); } +/* Me, Vladimir Serbinenko, hereby I add this module check as per new + GNU module policy. Note that this license check is informative only. + Modules have to be licensed under GPLv3 or GPLv3+ (optionally + multi-licensed under other licences as well) independently of the + presence of this check and solely by linking (module loading in GRUB + constitutes linking) and GRUB core being licensed under GPLv3+. + Be sure to understand your license obligations. +*/ +static grub_err_t +grub_dl_check_license (Elf_Ehdr *e) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); + str = (char *) e + s->sh_offset; + + 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 (grub_strcmp (str + s->sh_name, ".module_license") == 0) + { + if (grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3") == 0 + || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3+") == 0 + || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv2+") == 0) + return GRUB_ERR_NONE; + } + + return grub_error (GRUB_ERR_BAD_MODULE, "incompatible license"); +} + static grub_err_t grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e) { @@ -519,7 +551,16 @@ grub_dl_load_core (void *addr, grub_size_t size) mod->ref_count = 1; grub_dprintf ("modules", "relocating to %p\n", mod); - if (grub_dl_resolve_name (mod, e) + /* Me, Vladimir Serbinenko, hereby I add this module check as per new + GNU module policy. Note that this license check is informative only. + Modules have to be licensed under GPLv3 or GPLv3+ (optionally + multi-licensed under other licences as well) independently of the + presence of this check and solely by linking (module loading in GRUB + constitutes linking) and GRUB core being licensed under GPLv3+. + Be sure to understand your license obligations. + */ + if (grub_dl_check_license (e) + || grub_dl_resolve_name (mod, e) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) || grub_dl_resolve_symbols (mod, e) diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c index 56218b4e4..9c7b8cec2 100644 --- a/grub-core/kern/elf.c +++ b/grub-core/kern/elf.c @@ -23,6 +23,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); /* Check if EHDR is a valid ELF header. */ static grub_err_t diff --git a/grub-core/lib/cmos_datetime.c b/grub-core/lib/cmos_datetime.c index 8db60b48c..73c5a03c0 100644 --- a/grub-core/lib/cmos_datetime.c +++ b/grub-core/lib/cmos_datetime.c @@ -19,6 +19,9 @@ #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); grub_err_t grub_get_datetime (struct grub_datetime *datetime) diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index f5768b8b5..ad1bfc4d3 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -21,6 +21,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); struct grub_crypto_hmac_handle { diff --git a/grub-core/lib/pbkdf2.c b/grub-core/lib/pbkdf2.c index 083446ab9..09b8c7360 100644 --- a/grub-core/lib/pbkdf2.c +++ b/grub-core/lib/pbkdf2.c @@ -21,6 +21,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv2+"); /* Implement PKCS#5 PBKDF2 as per RFC 2898. The PRF to use is HMAC variant of digest supplied by MD. Inputs are the password P of length PLEN, diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 3642de9dc..6eb20b865 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -22,6 +22,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); struct grub_relocator { diff --git a/grub-core/loader/aout.c b/grub-core/loader/aout.c index 611960f92..69bf6e6ad 100644 --- a/grub-core/loader/aout.c +++ b/grub-core/loader/aout.c @@ -21,6 +21,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + int grub_aout_get_type (union grub_aout_header *header) { diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c index dc42683a6..847750dc0 100644 --- a/grub-core/loader/efi/appleloader.c +++ b/grub-core/loader/efi/appleloader.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static grub_efi_handle_t image_handle; diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index a095ad931..869b64ced 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -35,6 +35,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static grub_efi_physical_address_t address; diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index ecd5bd5cd..6487dc3df 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -34,6 +34,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #include #ifdef GRUB_MACHINE_PCBIOS #include diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 0178e2fd4..241eaa5e7 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -35,6 +35,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef GRUB_MACHINE_PCBIOS #include #endif diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index fd99c81d5..794316b34 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -38,6 +38,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static int boot_drive; static void *boot_part_addr; diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index 96d00f927..c6e6b67d1 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -36,6 +36,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_LINUX_CL_OFFSET 0x9000 #define GRUB_LINUX_CL_END_OFFSET 0x90FF diff --git a/grub-core/loader/i386/pc/ntldr.c b/grub-core/loader/i386/pc/ntldr.c index 0c33a0680..4a08b54f2 100644 --- a/grub-core/loader/i386/pc/ntldr.c +++ b/grub-core/loader/i386/pc/ntldr.c @@ -33,6 +33,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static struct grub_relocator *rel; static grub_uint32_t edx = 0xffffffff; diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 9accfc270..0bf7b1f8e 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* For frequencies. */ #include #include diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 4bfc2c191..d9e74b3c7 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -43,6 +43,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef GRUB_MACHINE_EFI #include #endif diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c index 0cf0eb825..12a3fa9f6 100644 --- a/grub-core/loader/powerpc/ieee1275/linux.c +++ b/grub-core/loader/powerpc/ieee1275/linux.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define ELF32_LOADMASK (0xc0000000UL) #define ELF64_LOADMASK (0xc000000000000000ULL) diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c index a262049a7..8ed61f8bf 100644 --- a/grub-core/loader/sparc64/ieee1275/linux.c +++ b/grub-core/loader/sparc64/ieee1275/linux.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static int loaded; diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 73158fd10..a98d60c20 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -34,6 +34,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #if defined (__i386) && !defined (GRUB_MACHINE_EFI) #include #endif diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index 1c1825490..07a71336b 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE struct grub_mmap_region *grub_mmap_overlays = 0; diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index cefb1cb9b..837fcb960 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -33,6 +33,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_DEFAULT_HISTORY_SIZE 50 static int nested_level = 0; diff --git a/grub-core/partmap/acorn.c b/grub-core/partmap/acorn.c index 677ec61d5..9a68ddd92 100644 --- a/grub-core/partmap/acorn.c +++ b/grub-core/partmap/acorn.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de) #define LINUX_SWAP_MAGIC grub_cpu_to_le32 (0xdeafab1e) #define LINUX_MAP_ENTRIES (512 / 12) diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c index 1e0f23402..f3ba950aa 100644 --- a/grub-core/partmap/amiga.c +++ b/grub-core/partmap/amiga.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_amiga_rdsk { /* "RDSK". */ diff --git a/grub-core/partmap/apple.c b/grub-core/partmap/apple.c index e162d18d7..c08cae589 100644 --- a/grub-core/partmap/apple.c +++ b/grub-core/partmap/apple.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_APPLE_HEADER_MAGIC 0x4552 #define GRUB_APPLE_PART_MAGIC 0x504D diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 4dec3851c..888100aa2 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #ifdef GRUB_UTIL #include #endif diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 7f2c36143..73a1c3b19 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -25,6 +25,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_uint8_t grub_gpt_magic[8] = { 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 31a0a0707..1b71c69ab 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_partition_map grub_msdos_partition_map; diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c index 7af95c939..c7ef681c4 100644 --- a/grub-core/partmap/sun.c +++ b/grub-core/partmap/sun.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_PARTMAP_SUN_MAGIC 0xDABE #define GRUB_PARTMAP_SUN_MAX_PARTS 8 #define GRUB_PARTMAP_SUN_WHOLE_DISK_ID 0x05 diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c index ea69c28b9..28dc4f5be 100644 --- a/grub-core/partmap/sunpc.c +++ b/grub-core/partmap/sunpc.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_PARTMAP_SUN_PC_MAGIC 0xDABE #define GRUB_PARTMAP_SUN_PC_MAX_PARTS 16 #define GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID 0x05 diff --git a/grub-core/parttool/msdospart.c b/grub-core/parttool/msdospart.c index 006a87def..ecaca140a 100644 --- a/grub-core/parttool/msdospart.c +++ b/grub-core/parttool/msdospart.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv2+"); + static int activate_table_handle = -1; static int type_table_handle = -1; diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index 7ce287ecc..210ac21cc 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -26,6 +26,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static short at_keyboard_status = 0; static int e0_received = 0; static int f0_received = 0; diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 44d1a9be8..0ade65f27 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -31,6 +31,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define DEFAULT_VIDEO_MODE "auto" #define DEFAULT_BORDER_WIDTH 10 diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c index fbb65ae0c..1816bfae2 100644 --- a/grub-core/term/i386/pc/vga_text.c +++ b/grub-core/term/i386/pc/vga_text.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define COLS 80 #define ROWS 25 diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 32628dbae..073c27aed 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports)) /* Argument options. */ diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 0a8c75c74..16158139d 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -34,6 +34,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct grub_term_output *terminfo_outputs; /* Get current terminfo name. */ diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c index 23c0c10ca..ae00936b8 100644 --- a/grub-core/term/usb_keyboard.c +++ b/grub-core/term/usb_keyboard.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + enum diff --git a/grub-core/tests/example_functional_test.c b/grub-core/tests/example_functional_test.c index 525988145..802088791 100644 --- a/grub-core/tests/example_functional_test.c +++ b/grub-core/tests/example_functional_test.c @@ -18,6 +18,9 @@ /* All tests need to include test.h for GRUB testing framework. */ #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); /* Functional test main method. */ static void diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c index 521f4ad22..fd199bd63 100644 --- a/grub-core/tests/lib/functional_test.c +++ b/grub-core/tests/lib/functional_test.c @@ -20,6 +20,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); static grub_err_t grub_functional_test (grub_extcmd_context_t ctxt __attribute__ ((unused)), diff --git a/grub-core/tests/test_blockarg.c b/grub-core/tests/test_blockarg.c index 41460fb7e..ddd46e1f6 100644 --- a/grub-core/tests/test_blockarg.c +++ b/grub-core/tests/test_blockarg.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t test_blockarg (grub_extcmd_context_t ctxt, int argc, char **args) { diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c index 659ab9a57..32e9358a3 100644 --- a/grub-core/video/bitmap.c +++ b/grub-core/video/bitmap.c @@ -23,6 +23,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* List of bitmap readers registered to system. */ static grub_video_bitmap_reader_t bitmap_readers_list; diff --git a/grub-core/video/bitmap_scale.c b/grub-core/video/bitmap_scale.c index 6f8ff247e..8da5697f8 100644 --- a/grub-core/video/bitmap_scale.c +++ b/grub-core/video/bitmap_scale.c @@ -23,6 +23,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); /* Prototypes for module-local functions. */ static grub_err_t scale_nn (struct grub_video_bitmap *dst, diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c index 832cd9903..79cae6547 100644 --- a/grub-core/video/bochs.c +++ b/grub-core/video/bochs.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct { struct grub_video_mode_info mode_info; diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c index a964c85cd..7fad50e5b 100644 --- a/grub-core/video/cirrus.c +++ b/grub-core/video/cirrus.c @@ -28,6 +28,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static struct { struct grub_video_mode_info mode_info; diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c index f02dc9cb6..d14ae98d2 100644 --- a/grub-core/video/efi_gop.c +++ b/grub-core/video/efi_gop.c @@ -29,6 +29,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_efi_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID; static struct grub_efi_gop *gop; static unsigned old_mode; diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c index a8f70edea..1e709a52d 100644 --- a/grub-core/video/efi_uga.c +++ b/grub-core/video/efi_uga.c @@ -30,6 +30,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; static struct grub_efi_uga_draw_protocol *uga; static grub_uint32_t uga_fb; diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c index d66b8b0c0..f4c1a6ab6 100644 --- a/grub-core/video/emu/sdl.c +++ b/grub-core/video/emu/sdl.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static SDL_Surface *window = 0; static struct grub_video_render_target *sdl_render_target; static struct grub_video_mode_info mode_info; diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c index 2226d6583..2cffcb3d9 100644 --- a/grub-core/video/fb/video_fb.c +++ b/grub-core/video/fb/video_fb.c @@ -24,6 +24,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); static struct { diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 08bf124b6..a109bcf43 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -30,6 +30,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static int vbe_detected = -1; static struct grub_vbe_info_block controller_info; diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c index 19770ce0a..fe387a26b 100644 --- a/grub-core/video/i386/pc/vga.c +++ b/grub-core/video/i386/pc/vga.c @@ -30,6 +30,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define VGA_WIDTH 640 #define VGA_HEIGHT 350 #define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c index 501ba7c2f..913ea8376 100644 --- a/grub-core/video/ieee1275.c +++ b/grub-core/video/ieee1275.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Only 8-bit indexed color is supported for now. */ static unsigned old_width, old_height; diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c index 9d88163bd..8cdb2f61d 100644 --- a/grub-core/video/readers/jpeg.c +++ b/grub-core/video/readers/jpeg.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Uncomment following define to enable JPEG debug. */ //#define JPEG_DEBUG diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c index 2cec49e2f..5728651e0 100644 --- a/grub-core/video/readers/png.c +++ b/grub-core/video/readers/png.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Uncomment following define to enable PNG debug. */ //#define PNG_DEBUG diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c index 6c9e9d691..84be68a0a 100644 --- a/grub-core/video/readers/tga.c +++ b/grub-core/video/readers/tga.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* Uncomment following define to enable TGA debug. */ //#define TGA_DEBUG diff --git a/grub-core/video/video.c b/grub-core/video/video.c index 7a1a446e4..6a1d47304 100644 --- a/grub-core/video/video.c +++ b/grub-core/video/video.c @@ -22,6 +22,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + /* The list of video adapters registered to system. */ grub_video_adapter_t grub_video_adapter_list = NULL; diff --git a/include/grub/dl.h b/include/grub/dl.h index afc4af41a..71db90c8b 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -63,8 +63,32 @@ __asm__ (".section .modname\n.asciz \"" #name "\"\n") #define GRUB_MOD_DEP(name) \ __asm__ (".section .moddeps\n.asciz \"" #name "\"\n") + #endif +#ifdef APPLE_CC +#define GRUB_MOD_SECTION(x) "_" x ", _" x "" +#else +#define GRUB_MOD_SECTION(x) "." x +#endif + +/* Me, Vladimir Serbinenko, hereby I add this module check as per new + GNU module policy. Note that this license check is informative only. + Modules have to be licensed under GPLv3 or GPLv3+ (optionally + multi-licensed under other licences as well) independently of the + presence of this check and solely by linking (module loading in GRUB + constitutes linking) and GRUB core being licensed under GPLv3+. + Be sure to understand your license obligations. +*/ +#define GRUB_MOD_LICENSE(license) \ + static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION ("module_license")), used)) = "LICENSE=" license; + +/* Under GPL license obligations you have to distribute your module + under GPLv3(+). However, you can also distribute the same code under + another license as long as GPLv3(+) version is provided. +*/ +#define GRUB_MOD_DUAL_LICENSE(x) + struct grub_dl_segment { struct grub_dl_segment *next; diff --git a/util/import_gcry.py b/util/import_gcry.py index 494a4ae7b..54c178dbf 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -91,7 +91,12 @@ for cipher_file in cipher_files: f = open (infile, "r") fw = open (outfile, "w") fw.write ("/* This file was automatically imported with \n") - fw.write (" import_gcry.py. Please don't modify it */\n"); + fw.write (" import_gcry.py. Please don't modify it */\n") + fw.write ("#include \n") + # Whole libgcrypt is distributedunder GPLv3+ or compatible + if isc: + fw.write ("GRUB_MOD_LICENSE (\"GPLv3+\");\n") + ciphernames = [] mdnames = [] hold = False From ec9f5e0d7387817ca986a33de79c9323d35beabb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 11 Apr 2011 23:30:15 +0200 Subject: [PATCH 0865/1414] * NEWS: Add btrfs support. --- ChangeLog | 4 ++++ NEWS | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 29dbceec0..6112407bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-11 Vladimir Serbinenko + + * NEWS: Add btrfs support. + 2011-04-11 Vladimir Serbinenko 2011-04-11 Colin Watson diff --git a/NEWS b/NEWS index 36e3f25bf..81b6ecb2d 100644 --- a/NEWS +++ b/NEWS @@ -29,7 +29,7 @@ New in 1.99: * New `lsacpi' command. -* Basic btrfs support (detection and UUID). +* Btrfs support. * New `--boot-directory' option to `grub-install', `grub-reboot', and `grub-set-default', with clearer semantics than the previous From 0c6769339490388a44e3b782a16443c0219029fe Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 12 Apr 2011 11:39:17 +0100 Subject: [PATCH 0866/1414] * util/import_gcry.py: Fix typo. --- ChangeLog | 4 ++++ util/import_gcry.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6112407bc..63c6ec58d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-12 Colin Watson + + * util/import_gcry.py: Fix typo. + 2011-04-11 Vladimir Serbinenko * NEWS: Add btrfs support. diff --git a/util/import_gcry.py b/util/import_gcry.py index 54c178dbf..b2a0a5451 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -93,7 +93,7 @@ for cipher_file in cipher_files: fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n") fw.write ("#include \n") - # Whole libgcrypt is distributedunder GPLv3+ or compatible + # Whole libgcrypt is distributed under GPLv3+ or compatible if isc: fw.write ("GRUB_MOD_LICENSE (\"GPLv3+\");\n") From 09a9d66f1d670be91aab7915284c18e67e8602e3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 12 Apr 2011 11:44:35 +0100 Subject: [PATCH 0867/1414] * NEWS: Drop obsolete entry about probe-only btrfs support. --- ChangeLog | 4 ++++ NEWS | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63c6ec58d..cf6fa18c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-12 Colin Watson + + * NEWS: Drop obsolete entry about probe-only btrfs support. + 2011-04-12 Colin Watson * util/import_gcry.py: Fix typo. diff --git a/NEWS b/NEWS index 81b6ecb2d..2a93c2526 100644 --- a/NEWS +++ b/NEWS @@ -83,10 +83,6 @@ New in 1.99: * Extensive updates to the Texinfo documentation. -* Add `grub-probe' support for the btrfs filesystem, permitting / to - reside on btrfs as long as /boot is on a filesystem natively supported - by GRUB. - * Handle symbolic links under /dev/mapper on GNU/Linux. * Handle installation across multiple partition table types. From 9d5f81622cd2bc422d6165b6d7a1b022495ecfc4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 12 Apr 2011 13:23:19 +0100 Subject: [PATCH 0868/1414] * docs/grub.texi (normal): New section. (normal_exit): New section. (Embedded configuration): Add reference to normal. (GRUB only offers a rescue shell): Likewise. * docs/grub-dev.texi (Error Handling): Fix typo. --- ChangeLog | 8 ++++++++ docs/grub-dev.texi | 2 +- docs/grub.texi | 48 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf6fa18c9..c1ee7cf9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-04-12 Colin Watson + + * docs/grub.texi (normal): New section. + (normal_exit): New section. + (Embedded configuration): Add reference to normal. + (GRUB only offers a rescue shell): Likewise. + * docs/grub-dev.texi (Error Handling): Fix typo. + 2011-04-12 Colin Watson * NEWS: Drop obsolete entry about probe-only btrfs support. diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi index a45b8b198..93d2bdb4d 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -451,7 +451,7 @@ request. Instead, please subscribe to the mailing list, and communicate first @chapter Error Handling Error handling in GRUB 2 is based on exception handling model. As C language -doesn't direcly support exceptions, exception handling behavior is emulated +doesn't directly support exceptions, exception handling behavior is emulated in software. When exception is raised, function must return to calling function. If calling diff --git a/docs/grub.texi b/docs/grub.texi index 0c59975cd..8d2223fb4 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1486,14 +1486,14 @@ reside anywhere on the file system, and may be removed after running @command{grub-mkimage}. After the embedded configuration file (if any) is executed, GRUB will load -the @samp{normal} module, which will then read the real configuration file -from @file{$prefix/grub.cfg}. By this point, the @code{root} variable will -also have been set to the root device name. For example, @code{prefix} -might be set to @samp{(hd0,1)/boot/grub}, and @code{root} might be set to -@samp{hd0,1}. Thus, in most cases, the embedded configuration file only -needs to set the @code{prefix} and @code{root} variables, and then drop -through to GRUB's normal processing. A typical example of this might look -like this: +the @samp{normal} module (@pxref{normal}), which will then read the real +configuration file from @file{$prefix/grub.cfg}. By this point, the +@code{root} variable will also have been set to the root device name. For +example, @code{prefix} might be set to @samp{(hd0,1)/boot/grub}, and +@code{root} might be set to @samp{hd0,1}. Thus, in most cases, the embedded +configuration file only needs to set the @code{prefix} and @code{root} +variables, and then drop through to GRUB's normal processing. A typical +example of this might look like this: @example @group @@ -3089,6 +3089,8 @@ you forget a command, you can run the command @command{help} * load_env:: Load variables from environment block * loopback:: Make a device from a filesystem image * ls:: List devices or files +* normal:: Enter normal mode +* normal_exit:: Exit from normal mode * parttool:: Modify partition table entries * password:: Set a clear-text password * password_pbkdf2:: Set a hashed password @@ -3545,6 +3547,34 @@ name syntax}), then list the contents of that directory. @end deffn +@node normal +@subsection normal + +@deffn Command normal [file] +Enter normal mode and display the GRUB menu. + +In normal mode, commands, filesystem modules, and cryptography modules are +automatically loaded, and the full GRUB script parser is available. Other +modules may be explicitly loaded using @command{insmod} (@pxref{insmod}). + +If a @var{file} is given, then commands will be read from that file. +Otherwise, they will be read from @file{$prefix/grub.cfg} if it exists. + +@command{normal} may be called from within normal mode, creating a nested +environment. It is more usual to use @command{configfile} +(@pxref{configfile}) for this. +@end deffn + + +@node normal_exit +@subsection normal_exit + +@deffn Command normal_exit +Exit normal mode (@pxref{normal}). If this instance of normal mode was not +nested within another one, then return to rescue mode. +@end deffn + + @node parttool @subsection parttool @@ -4082,7 +4112,7 @@ GRUB's normal start-up procedure involves setting the @samp{prefix} environment variable to a value set in the core image by @command{grub-install}, setting the @samp{root} variable to match, loading the @samp{normal} module from the prefix, and running the @samp{normal} -command. This command is responsible for reading +command (@pxref{normal}). This command is responsible for reading @file{/boot/grub/grub.cfg}, running the menu, and doing all the useful things GRUB is supposed to do. From 78fa584f67811a331de065dc1cca39e65a40b21e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 13 Apr 2011 12:36:04 +0100 Subject: [PATCH 0869/1414] Rewrite /proc/self/mountinfo handling to cope with bind-mounts and move-mounts appearing out of order. Fixes Ubuntu bug #738345. * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): Build a list of relevant visible mounts using the mnt_id and parent_mnt_id fields, and then scan that list at the end. --- ChangeLog | 9 ++++ grub-core/kern/emu/getroot.c | 100 ++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1ee7cf9d..d0269c905 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-13 Colin Watson + + Rewrite /proc/self/mountinfo handling to cope with bind-mounts and + move-mounts appearing out of order. Fixes Ubuntu bug #738345. + + * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): + Build a list of relevant visible mounts using the mnt_id and + parent_mnt_id fields, and then scan that list at the end. + 2011-04-12 Colin Watson * docs/grub.texi (normal): New section. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index c4cbb9c18..17da9070f 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -98,6 +98,14 @@ xgetcwd (void) #ifdef __linux__ +struct mountinfo_entry +{ + int id; + int major, minor; + char enc_root[PATH_MAX], enc_path[PATH_MAX]; + char fstype[PATH_MAX], device[PATH_MAX]; +}; + /* Statting something on a btrfs filesystem always returns a virtual device major/minor pair rather than the real underlying device, because btrfs can span multiple underlying devices (and even if it's currently only @@ -112,6 +120,10 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) char *buf = NULL; size_t len = 0; char *ret = NULL; + int entry_len = 0, entry_max = 4; + struct mountinfo_entry *entries; + struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" }; + int i; if (! *dir) dir = "/"; @@ -122,52 +134,102 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) if (! fp) return NULL; /* fall through to other methods */ + entries = xmalloc (entry_max * sizeof (*entries)); + + /* First, build a list of relevant visible mounts. */ while (getline (&buf, &len, fp) > 0) { - int mnt_id, parent_mnt_id; - unsigned int major, minor; - char enc_root[PATH_MAX], enc_path[PATH_MAX]; + struct mountinfo_entry entry; int count; size_t enc_path_len; const char *sep; - char fstype[PATH_MAX], device[PATH_MAX]; if (sscanf (buf, "%d %d %u:%u %s %s%n", - &mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path, - &count) < 6) + &entry.id, &parent_entry.id, &entry.major, &entry.minor, + entry.enc_root, entry.enc_path, &count) < 6) continue; - enc_path_len = strlen (enc_path); + enc_path_len = strlen (entry.enc_path); /* Check that enc_path is a prefix of dir. The prefix must either be the entire string, or end with a slash, or be immediately followed by a slash. */ - if (strncmp (dir, enc_path, enc_path_len) != 0 || + if (strncmp (dir, entry.enc_path, enc_path_len) != 0 || (enc_path_len && dir[enc_path_len - 1] != '/' && dir[enc_path_len] && dir[enc_path_len] != '/')) continue; - /* This is a parent of the requested directory. /proc/self/mountinfo - is in mount order, so it must be the closest parent we've - encountered so far. If it's virtual, return its device node; - otherwise, carry on to try to find something closer. */ - - free (ret); - ret = NULL; - sep = strstr (buf + count, " - "); if (!sep) continue; sep += sizeof (" - ") - 1; - if (sscanf (sep, "%s %s", fstype, device) != 2) + if (sscanf (sep, "%s %s", entry.fstype, entry.device) != 2) continue; - ret = strdup (device); + /* Using the mount IDs, find out where this fits in the list of + visible mount entries we've seen so far. There are three + interesting cases. Firstly, it may be inserted at the end: this is + the usual case of /foo/bar being mounted after /foo. Secondly, it + may be inserted at the start: for example, this can happen for + filesystems that are mounted before / and later moved under it. + Thirdly, it may occlude part or all of the existing filesystem + tree, in which case the end of the list needs to be pruned and this + new entry will be inserted at the end. */ + if (entry_len >= entry_max) + { + entry_max <<= 1; + entries = xrealloc (entries, entry_max * sizeof (*entries)); + } + + if (!entry_len) + { + /* Initialise list. */ + entry_len = 2; + entries[0] = parent_entry; + entries[1] = entry; + } + else + { + for (i = entry_len - 1; i >= 0; i--) + { + if (entries[i].id == parent_entry.id) + { + /* Insert at end, pruning anything previously above this. */ + entry_len = i + 2; + entries[i + 1] = entry; + break; + } + else if (i == 0 && entries[i].id == entry.id) + { + /* Insert at start. */ + entry_len++; + memmove (entries + 1, entries, + (entry_len - 1) * sizeof (*entries)); + entries[0] = parent_entry; + entries[1] = entry; + break; + } + } + } + } + + /* Now scan visible mounts for the ones we're interested in. */ + for (i = entry_len - 1; i >= 0; i--) + { + if (entries[i].major != 0) + continue; /* not a virtual device */ + + if (!*entries[i].device) + continue; + + ret = strdup (entries[i].device); if (relroot) - *relroot = strdup (enc_root); + *relroot = strdup (entries[i].enc_root); + break; } free (buf); + free (entries); fclose (fp); return ret; } From e74c31125d2466db7d5a190f924b1abee6094947 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 13 Apr 2011 12:57:26 +0100 Subject: [PATCH 0870/1414] * util/grub.d/10_linux.in: Add rootflags=subvol= if / is on a btrfs subvolume. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 6 ++++++ util/grub.d/10_linux.in | 8 ++++++++ util/grub.d/20_linux_xen.in | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index d0269c905..47935890d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-13 Colin Watson + + * util/grub.d/10_linux.in: Add rootflags=subvol= if / is on a + btrfs subvolume. + * util/grub.d/20_linux_xen.in: Likewise. + 2011-04-13 Colin Watson Rewrite /proc/self/mountinfo handling to cope with bind-mounts and diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 930ce06ef..1dbcad90c 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -51,6 +51,14 @@ else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} 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#/}" + if [ "x${rootsubvol}" != x ]; then + GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" + fi +fi + linux_entry () { os="$1" diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 858627aa3..a9007603d 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 +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#/}" + if [ "x${rootsubvol}" != x ]; then + GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" + fi +fi + linux_entry () { os="$1" From 2a861f38a7f0b17ada0057b139f9ad6f63aad24f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 14 Apr 2011 20:27:27 +0100 Subject: [PATCH 0871/1414] Tell FUSE to run single-threaded, since GRUB code is not thread-safe. Fixes Ubuntu bug #756297. --- util/grub-mount.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index efada771a..434772eec 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -450,9 +450,12 @@ main (int argc, char *argv[]) grub_util_init_nls (); - fuse_args = xrealloc (fuse_args, (fuse_argc + 1) * sizeof (fuse_args[0])); + fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); fuse_args[fuse_argc] = xstrdup (argv[0]); fuse_argc++; + /* Run single-threaded. */ + fuse_args[fuse_argc] = xstrdup ("-s"); + fuse_argc++; argp_parse (&argp, argc, argv, 0, 0, 0); From bd671cc4fe27784df6bacb57d83f691a84e3f5f0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 15 Apr 2011 18:15:06 +0200 Subject: [PATCH 0872/1414] Use Block IO on EFI --- grub-core/disk/efi/efidisk.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 1bf764f10..35602513e 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -33,12 +33,10 @@ struct grub_efidisk_data grub_efi_device_path_t *device_path; grub_efi_device_path_t *last_device_path; grub_efi_block_io_t *block_io; - grub_efi_disk_io_t *disk_io; struct grub_efidisk_data *next; }; -/* GUIDs. */ -static grub_efi_guid_t disk_io_guid = GRUB_EFI_DISK_IO_GUID; +/* GUID. */ static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_GUID; static struct grub_efidisk_data *fd_devices; @@ -143,7 +141,7 @@ make_devices (void) struct grub_efidisk_data *devices = 0; /* Find handles which support the disk io interface. */ - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid, + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &block_io_guid, 0, &num_handles); if (! handles) return 0; @@ -155,7 +153,6 @@ make_devices (void) grub_efi_device_path_t *ldp; struct grub_efidisk_data *d; grub_efi_block_io_t *bio; - grub_efi_disk_io_t *dio; dp = grub_efi_get_device_path (*handle); if (! dp) @@ -168,9 +165,7 @@ make_devices (void) bio = grub_efi_open_protocol (*handle, &block_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - dio = grub_efi_open_protocol (*handle, &disk_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! bio || ! dio) + if (! bio) /* This should not happen... Why? */ continue; @@ -186,7 +181,6 @@ make_devices (void) d->device_path = dp; d->last_device_path = ldp; d->block_io = bio; - d->disk_io = dio; d->next = devices; devices = d; } @@ -563,22 +557,20 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, { /* For now, use the disk io interface rather than the block io's. */ struct grub_efidisk_data *d; - grub_efi_disk_io_t *dio; grub_efi_block_io_t *bio; grub_efi_status_t status; d = disk->data; - dio = d->disk_io; bio = d->block_io; grub_dprintf ("efidisk", "reading 0x%lx sectors at the sector 0x%llx from %s\n", (unsigned long) size, (unsigned long long) sector, disk->name); - status = efi_call_5 (dio->read, dio, bio->media->media_id, - (grub_efi_uint64_t) sector << disk->log_sector_size, - (grub_efi_uintn_t) size << disk->log_sector_size, - buf); + status = efi_call_5 (bio->read_blocks, bio, bio->media->media_id, + (grub_efi_uint64_t) sector, + (grub_efi_uintn_t) size << disk->log_sector_size, + buf); if (status != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error"); @@ -591,20 +583,18 @@ grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector, { /* For now, use the disk io interface rather than the block io's. */ struct grub_efidisk_data *d; - grub_efi_disk_io_t *dio; grub_efi_block_io_t *bio; grub_efi_status_t status; d = disk->data; - dio = d->disk_io; bio = d->block_io; grub_dprintf ("efidisk", "writing 0x%lx sectors at the sector 0x%llx to %s\n", (unsigned long) size, (unsigned long long) sector, disk->name); - status = efi_call_5 (dio->write, dio, bio->media->media_id, - (grub_efi_uint64_t) sector << disk->log_sector_size, + status = efi_call_5 (bio->write_blocks, bio, bio->media->media_id, + (grub_efi_uint64_t) sector, (grub_efi_uintn_t) size << disk->log_sector_size, (void *) buf); if (status != GRUB_EFI_SUCCESS) From d8a2bcf564728cc38b138fed18cd89b097493e75 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 15 Apr 2011 21:42:29 +0200 Subject: [PATCH 0873/1414] contiguous read --- grub-core/kern/disk.c | 296 +++++++++++++++++++++++++----------------- 1 file changed, 178 insertions(+), 118 deletions(-) diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index af56527ad..5439a02f6 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -398,13 +398,93 @@ transform_sector (grub_disk_t disk, grub_disk_addr_t sector) return sector >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); } +/* Small read (less than cache size and not pass across cache unit boundaries). + sector is already adjusted and is divisible by cache unit size. + */ +static grub_err_t +grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, void *buf) +{ + char *data; + char *tmp_buf; + + /* Fetch the cache. */ + data = grub_disk_cache_fetch (disk->dev->id, disk->id, sector); + if (data) + { + /* Just copy it! */ + grub_memcpy (buf, data + offset, size); + grub_disk_cache_unlock (disk->dev->id, disk->id, sector); + return GRUB_ERR_NONE; + } + + /* Allocate a temporary buffer. */ + tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + if (! tmp_buf) + return grub_errno; + + /* Otherwise read data from the disk actually. */ + if (disk->total_sectors == GRUB_DISK_SIZE_UNKNOWN + || sector + GRUB_DISK_CACHE_SIZE + < (disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) + { + grub_err_t err; + err = (disk->dev->read) (disk, transform_sector (disk, sector), + 1 << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS + - disk->log_sector_size), tmp_buf); + if (!err) + { + /* Copy it and store it in the disk cache. */ + grub_memcpy (buf, tmp_buf + offset, size); + grub_disk_cache_store (disk->dev->id, disk->id, + sector, tmp_buf); + grub_free (tmp_buf); + return GRUB_ERR_NONE; + } + } + + grub_errno = GRUB_ERR_NONE; + + { + /* Uggh... Failed. Instead, just read necessary data. */ + unsigned num; + grub_disk_addr_t aligned_sector; + + sector += (offset >> GRUB_DISK_SECTOR_BITS); + offset &= ((1 << GRUB_DISK_SECTOR_BITS) - 1); + aligned_sector = (sector & ~((1 << (disk->log_sector_size + - GRUB_DISK_SECTOR_BITS)) + - 1)); + offset += ((sector - aligned_sector) << GRUB_DISK_SECTOR_BITS); + num = ((size + offset + (1 << (disk->log_sector_size)) + - 1) >> (disk->log_sector_size)); + + tmp_buf = grub_malloc (num << disk->log_sector_size); + if (!tmp_buf) + return grub_errno; + + if ((disk->dev->read) (disk, transform_sector (disk, aligned_sector), + num, tmp_buf)) + { + grub_error_push (); + grub_dprintf ("disk", "%s read failed\n", disk->name); + grub_error_pop (); + return grub_errno; + } + grub_memcpy (buf, tmp_buf + offset, size); + return GRUB_ERR_NONE; + } +} + /* Read data from the disk. */ grub_err_t grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_off_t offset, grub_size_t size, void *buf) { - char *tmp_buf; - unsigned real_offset; + grub_off_t real_offset; + grub_disk_addr_t real_sector; + grub_size_t real_size; /* First of all, check if the region is within the disk. */ if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) @@ -416,138 +496,118 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, return grub_errno; } + real_sector = sector; real_offset = offset; + real_size = size; - /* Allocate a temporary buffer. */ - tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); - if (! tmp_buf) - return grub_errno; - - /* Until SIZE is zero... */ - while (size) + /* First read until first cache boundary. */ + if (offset || (sector & (GRUB_DISK_CACHE_SIZE - 1))) { - char *data; grub_disk_addr_t start_sector; - grub_size_t len; grub_size_t pos; + grub_err_t err; + grub_size_t len; - /* For reading bulk data. */ start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1); pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS; len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS) - - pos - real_offset); + - pos - offset); if (len > size) len = size; - - /* Fetch the cache. */ - data = grub_disk_cache_fetch (disk->dev->id, disk->id, start_sector); - if (data) - { - /* Just copy it! */ - grub_memcpy (buf, data + pos + real_offset, len); - grub_disk_cache_unlock (disk->dev->id, disk->id, start_sector); - } - else - { - /* Otherwise read data from the disk actually. */ - if ((disk->total_sectors != GRUB_DISK_SIZE_UNKNOWN - && start_sector + GRUB_DISK_CACHE_SIZE - > (disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) - || (disk->dev->read) (disk, transform_sector (disk, start_sector), - 1 << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size), tmp_buf) - != GRUB_ERR_NONE) - { - /* Uggh... Failed. Instead, just read necessary data. */ - unsigned num; - char *p; - grub_disk_addr_t aligned_sector; - - grub_errno = GRUB_ERR_NONE; - - aligned_sector = (sector & ~((1 << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)) - - 1)); - real_offset += ((sector - aligned_sector) - << GRUB_DISK_SECTOR_BITS); - num = ((size + real_offset + (1 << (disk->log_sector_size)) - - 1) >> (disk->log_sector_size)); - - p = grub_realloc (tmp_buf, num << disk->log_sector_size); - if (!p) - goto finish; - - tmp_buf = p; - - if ((disk->dev->read) (disk, transform_sector (disk, - aligned_sector), - num, tmp_buf)) - { - grub_error_push (); - grub_dprintf ("disk", "%s read failed\n", disk->name); - grub_error_pop (); - goto finish; - } - - grub_memcpy (buf, tmp_buf + real_offset, size); - - /* Call the read hook, if any. */ - if (disk->read_hook) - while (size) - { - grub_size_t to_read = (size > GRUB_DISK_SECTOR_SIZE) ? GRUB_DISK_SECTOR_SIZE : size; - (disk->read_hook) (sector, real_offset, - to_read); - if (grub_errno != GRUB_ERR_NONE) - goto finish; - - sector++; - size -= to_read - real_offset; - real_offset = 0; - } - - /* This must be the end. */ - goto finish; - } - - /* Copy it and store it in the disk cache. */ - grub_memcpy (buf, tmp_buf + pos + real_offset, len); - grub_disk_cache_store (disk->dev->id, disk->id, - start_sector, tmp_buf); - } - - /* Call the read hook, if any. */ - if (disk->read_hook) - { - grub_disk_addr_t s = sector; - grub_size_t l = len; - - while (l) - { - (disk->read_hook) (s, real_offset, - ((l > GRUB_DISK_SECTOR_SIZE) - ? GRUB_DISK_SECTOR_SIZE - : l)); - - if (l < GRUB_DISK_SECTOR_SIZE - real_offset) - break; - - s++; - l -= GRUB_DISK_SECTOR_SIZE - real_offset; - real_offset = 0; - } - } - - sector = start_sector + GRUB_DISK_CACHE_SIZE; + err = grub_disk_read_small (disk, start_sector, + offset + pos, len, buf); + if (err) + return err; buf = (char *) buf + len; size -= len; - real_offset = 0; + offset += len; + sector += (offset >> GRUB_DISK_SECTOR_BITS); + offset &= ((1 << GRUB_DISK_SECTOR_BITS) - 1); } - finish: + /* Until SIZE is zero... */ + while (size >= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS)) + { + char *data = NULL; + grub_disk_addr_t agglomerate; + grub_err_t err; - grub_free (tmp_buf); + /* agglomerate read until we find a first cached entry. */ + for (agglomerate = 0; agglomerate + < (size >> (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS)); + agglomerate++) + { + data = grub_disk_cache_fetch (disk->dev->id, disk->id, + sector + (agglomerate + << GRUB_DISK_CACHE_BITS)); + if (data) + break; + } + + if (agglomerate) + { + grub_disk_addr_t i; + + err = (disk->dev->read) (disk, transform_sector (disk, sector), + agglomerate << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS + - disk->log_sector_size), + buf); + if (err) + return err; + + for (i = 0; i < agglomerate; i ++) + grub_disk_cache_store (disk->dev->id, disk->id, + sector + (i << GRUB_DISK_CACHE_BITS), + (char *) buf + + (i << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS))); + + sector += agglomerate << GRUB_DISK_CACHE_BITS; + size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS); + buf = (char *) buf + + (agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS)); + } + + if (data) + { + grub_memcpy (buf, data, GRUB_DISK_CACHE_SIZE); + sector += GRUB_DISK_CACHE_SIZE; + buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); + size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); + grub_disk_cache_unlock (disk->dev->id, disk->id, + sector + (agglomerate + << GRUB_DISK_CACHE_BITS)); + } + } + + /* And now read the last part. */ + if (size) + { + grub_err_t err; + err = grub_disk_read_small (disk, sector, 0, size, buf); + if (err) + return err; + } + + /* Call the read hook, if any. */ + if (disk->read_hook) + { + grub_disk_addr_t s = real_sector; + grub_size_t l = real_size; + grub_off_t o = real_offset; + + while (l) + { + (disk->read_hook) (s, o, + ((l > GRUB_DISK_SECTOR_SIZE) + ? GRUB_DISK_SECTOR_SIZE + : l)); + s++; + l -= GRUB_DISK_SECTOR_SIZE - o; + o = 0; + } + } return grub_errno; } From e03f7bea4526068566c7c305e90b4614132129dc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Apr 2011 09:16:44 +0200 Subject: [PATCH 0874/1414] * grub-core/gfxmenu/gui_image.c (rescale_image): Don't attempt to scale to negative size. --- ChangeLog | 5 +++++ grub-core/gfxmenu/gui_image.c | 17 ++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47935890d..572d49a13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-16 Vladimir Serbinenko + + * grub-core/gfxmenu/gui_image.c (rescale_image): Don't attempt to scale + to negative size. + 2011-04-13 Colin Watson * util/grub.d/10_linux.in: Add rootflags=subvol= if / is on a diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c index 3988f4ba8..60e4a46de 100644 --- a/grub-core/gfxmenu/gui_image.c +++ b/grub-core/gfxmenu/gui_image.c @@ -101,6 +101,9 @@ image_get_parent (void *vself) static grub_err_t rescale_image (grub_gui_image_t self) { + signed width; + signed height; + if (! self->raw_bitmap) { if (self->bitmap) @@ -111,12 +114,12 @@ rescale_image (grub_gui_image_t self) return grub_errno; } - unsigned width = self->bounds.width; - unsigned height = self->bounds.height; + width = self->bounds.width; + height = self->bounds.height; if (self->bitmap - && (grub_video_bitmap_get_width (self->bitmap) == width) - && (grub_video_bitmap_get_height (self->bitmap) == height)) + && ((signed) grub_video_bitmap_get_width (self->bitmap) == width) + && ((signed) grub_video_bitmap_get_height (self->bitmap) == height)) { /* Nothing to do; already the right size. */ return grub_errno; @@ -131,15 +134,15 @@ rescale_image (grub_gui_image_t self) /* Create a scaled bitmap, unless the requested size is the same as the raw size -- in that case a reference is made. */ - if (grub_video_bitmap_get_width (self->raw_bitmap) == width - && grub_video_bitmap_get_height (self->raw_bitmap) == height) + if ((signed) grub_video_bitmap_get_width (self->raw_bitmap) == width + && (signed) grub_video_bitmap_get_height (self->raw_bitmap) == height) { self->bitmap = self->raw_bitmap; return grub_errno; } /* Don't scale to an invalid size. */ - if (width == 0 || height == 0) + if (width <= 0 || height <= 0) return grub_errno; /* Create the scaled bitmap. */ From 50d2cc5ae5712101b2307d5b8df2d1e05a63ea41 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Apr 2011 15:27:35 +0200 Subject: [PATCH 0875/1414] Identify RAID by its UUID rather than (guessed) name. * grub-core/disk/raid.c (ascii2hex): New function. (grub_raid_open): Accept mduuid/%s specification. * grub-core/kern/emu/getroot.c (get_mdadm_name): Revamped into ... (get_mdadm_uuid): ... this. (grub_util_get_grub_dev): Use mduuid/%s if UUID is available. --- ChangeLog | 10 +++++++++ grub-core/disk/raid.c | 39 ++++++++++++++++++++++++++++---- grub-core/kern/emu/getroot.c | 43 ++++++++++++++---------------------- 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 572d49a13..84840a9a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-04-17 Vladimir Serbinenko + + Identify RAID by its UUID rather than (guessed) name. + + * grub-core/disk/raid.c (ascii2hex): New function. + (grub_raid_open): Accept mduuid/%s specification. + * grub-core/kern/emu/getroot.c (get_mdadm_name): Revamped into ... + (get_mdadm_uuid): ... this. + (grub_util_get_grub_dev): Use mduuid/%s if UUID is available. + 2011-04-16 Vladimir Serbinenko * grub-core/gfxmenu/gui_image.c (rescale_image): Don't attempt to scale diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 3c74bba99..946e6d2c2 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -122,18 +122,49 @@ grub_raid_getname (struct grub_disk *disk) } #endif +static inline int +ascii2hex (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; +} + static grub_err_t grub_raid_open (const char *name, grub_disk_t disk) { struct grub_raid_array *array; unsigned n; - for (array = array_list; array != NULL; array = array->next) + if (grub_memcmp (name, "mduuid/", sizeof ("mduuid/") - 1) == 0) { - if (!grub_strcmp (array->name, name)) - if (grub_is_array_readable (array)) - break; + const char *uuidstr = name + sizeof ("mduuid/") - 1; + grub_size_t uuid_len = grub_strlen (uuidstr) / 2; + grub_uint8_t uuidbin[uuid_len]; + unsigned i; + for (i = 0; i < uuid_len; i++) + uuidbin[i] = ascii2hex (uuidstr[2 * i + 1]) + | (ascii2hex (uuidstr[2 * i]) << 4); + + for (array = array_list; array != NULL; array = array->next) + { + if (uuid_len == (unsigned) array->uuid_len + && grub_memcmp (uuidbin, array->uuid, uuid_len) == 0) + if (grub_is_array_readable (array)) + break; + } } + else + for (array = array_list; array != NULL; array = array->next) + { + if (!grub_strcmp (array->name, name)) + if (grub_is_array_readable (array)) + break; + } if (!array) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 17da9070f..f836a6625 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -690,7 +690,7 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) #ifdef __linux__ static char * -get_mdadm_name (const char *os_dev) +get_mdadm_uuid (const char *os_dev) { int mdadm_pipe[2]; pid_t mdadm_pid; @@ -742,19 +742,21 @@ get_mdadm_name (const char *os_dev) while (getline (&buf, &len, mdadm) > 0) { - if (strncmp (buf, "MD_NAME=", sizeof ("MD_NAME=") - 1) == 0) + if (strncmp (buf, "MD_UUID=", sizeof ("MD_UUID=") - 1) == 0) { - char *name_start, *colon; + char *name_start, *ptri, *ptro; size_t name_len; free (name); - name_start = buf + sizeof ("MD_NAME=") - 1; - /* Strip off the homehost if present. */ - colon = strchr (name_start, ':'); - name = strdup (colon ? colon + 1 : name_start); - name_len = strlen (name); - if (name[name_len - 1] == '\n') - name[name_len - 1] = '\0'; + name_start = buf + sizeof ("MD_UUID=") - 1; + ptro = name = xmalloc (strlen (name_start) + 1); + for (ptri = name_start; *ptri && *ptri != '\n' && *ptri != '\r'; + ptri++) + if ((*ptri >= '0' && *ptri <= '9') + || (*ptri >= 'a' && *ptri <= 'f') + || (*ptri >= 'A' && *ptri <= 'F')) + *ptro++ = *ptri; + *ptro = 0; } } @@ -870,37 +872,26 @@ grub_util_get_grub_dev (const char *os_dev) #ifdef __linux__ { - char *mdadm_name = get_mdadm_name (os_dev); + char *mdadm_name = get_mdadm_uuid (os_dev); struct stat st; if (mdadm_name) { - char *newname; const char *q; for (q = os_dev + strlen (os_dev) - 1; q >= os_dev && grub_isdigit (*q); q--); if (q >= os_dev && *q == 'p') - { - newname = xasprintf ("/dev/md/%sp%s", mdadm_name, q + 1); - if (stat (newname, &st) == 0) - { - free (grub_dev); - grub_dev = xasprintf ("md/%s,%s", mdadm_name, q + 1); - goto done; - } - free (newname); - } - newname = xasprintf ("/dev/md/%s", mdadm_name); - if (stat (newname, &st) == 0) { free (grub_dev); - grub_dev = xasprintf ("md/%s", mdadm_name); + grub_dev = xasprintf ("mduuid/%s,%s", mdadm_name, q + 1); + goto done; } + free (grub_dev); + grub_dev = xasprintf ("mduuid/%s", mdadm_name); done: - free (newname); free (mdadm_name); } } From 9ac718b06128f3d55ebdd704cec668347e06af2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Apr 2011 17:24:47 +0200 Subject: [PATCH 0876/1414] * Makefile.am (multiboot.elf): Add -Wl,--build-id=none. (kfreebsd.elf): Likewise. (pc-chainloader.elf): Likewise. (ntldr.elf): Likewise. --- ChangeLog | 7 +++++++ Makefile.am | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84840a9a7..859f337ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-04-17 Vladimir Serbinenko + + * Makefile.am (multiboot.elf): Add -Wl,--build-id=none. + (kfreebsd.elf): Likewise. + (pc-chainloader.elf): Likewise. + (ntldr.elf): Likewise. + 2011-04-17 Vladimir Serbinenko Identify RAID by its UUID rather than (guessed) name. diff --git a/Makefile.am b/Makefile.am index 60e041a8d..9301c91a5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -147,28 +147,28 @@ linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S - $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include + $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S - $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include + $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include kfreebsd.aout: kfreebsd.elf $(OBJCOPY) -O a.out-i386-linux $< $@ -R .note.gnu.build-id pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S - $(TARGET_CC) -o $@ $< -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0x7c00 -m32 + $(TARGET_CC) -o $@ $< -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x7c00 -m32 pc-chainloader.bin: pc-chainloader.elf $(OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@; ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S - $(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0 -m32 + $(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0 -m32 ntldr.bin: ntldr.elf $(OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@; multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S - $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1 + $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1 kfreebsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kfreebsd.init-x86_64.S $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@ From f3fb7b36df4c729f001bc245a64304a5a34e30d6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Apr 2011 09:31:13 +0200 Subject: [PATCH 0877/1414] * util/grub-mkimage.c (generate_image): Update fwstart.img hash after performing the necessary test. --- ChangeLog | 5 +++++ util/grub-mkimage.c | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 859f337ac..a29a5b694 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-18 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Update fwstart.img hash after + performing the necessary test. + 2011-04-17 Vladimir Serbinenko * Makefile.am (multiboot.elf): Add -Wl,--build-id=none. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 70c5ef6a9..c07f43af2 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1174,14 +1174,16 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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 }; + { + 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 + }; boot_path = grub_util_get_path (dir, "fwstart.img"); boot_size = grub_util_get_image_size (boot_path); From a5102d9433ca39c8f73615b757b2b35225c2d165 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Apr 2011 17:47:21 +0200 Subject: [PATCH 0878/1414] * util/grub-mkimage.c (generate_image): Add forgotten comma. --- ChangeLog | 4 ++++ util/grub-mkimage.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a29a5b694..f9cfcdb46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-18 Vladimir Serbinenko + + * util/grub-mkimage.c (generate_image): Add forgotten comma. + 2011-04-18 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Update fwstart.img hash after diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index c07f43af2..2ba351596 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1175,7 +1175,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], */ const grub_uint8_t fwstart_good_hash[] = { - 0x9f, 0x7f, 0x79, 0x47, 0x68, 0x91, 0x61, 0xb3 + 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, From 93a777e38840ad59105cd6552c9a787e61b6f338 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Apr 2011 23:03:52 +0200 Subject: [PATCH 0879/1414] Complete 64-bit division support. * grub-core/kern/misc.c (grub_divmod64): Rename to ... (grub_divmod64_full): ... this. Support 64-bit divisor and reminder. * include/grub/misc.h (grub_divmod64): Rename to ... (grub_divmod64_full): ... this. (grub_divmod64): New inline function. --- ChangeLog | 10 ++++++++++ grub-core/kern/misc.c | 14 +++++++------- include/grub/misc.h | 16 ++++++++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f9cfcdb46..f46277405 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-04-18 Vladimir Serbinenko + + Complete 64-bit division support. + + * grub-core/kern/misc.c (grub_divmod64): Rename to ... + (grub_divmod64_full): ... this. Support 64-bit divisor and reminder. + * include/grub/misc.h (grub_divmod64): Rename to ... + (grub_divmod64_full): ... this. + (grub_divmod64): New inline function. + 2011-04-18 Vladimir Serbinenko * util/grub-mkimage.c (generate_image): Add forgotten comma. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 37ce8decd..1b4cdec66 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -597,23 +597,23 @@ grub_reverse (char *str) /* Divide N by D, return the quotient, and store the remainder in *R. */ grub_uint64_t -grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r) +grub_divmod64_full (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 - upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper + upper(N * 2^i) = (Q * D + M), where upper represents the high 64 bits in 128-bits space. */ unsigned bits = 64; - unsigned long long q = 0; - unsigned m = 0; + grub_uint64_t q = 0; + grub_uint64_t m = 0; /* Skip the slow computation if 32-bit arithmetic is possible. */ - if (n < 0xffffffff) + if (n < 0xffffffff && d < 0xffffffff) { if (r) - *r = ((grub_uint32_t) n) % d; + *r = ((grub_uint32_t) n) % (grub_uint32_t) d; - return ((grub_uint32_t) n) / d; + return ((grub_uint32_t) n) / (grub_uint32_t) d; } while (bits--) diff --git a/include/grub/misc.h b/include/grub/misc.h index 6fcaa148b..80588be33 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -287,8 +287,20 @@ 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) (grub_uint64_t n, - grub_uint32_t d, grub_uint32_t *r); +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; +} #if NEED_ENABLE_EXECUTE_STACK && !defined(GRUB_UTIL) void EXPORT_FUNC(__enable_execute_stack) (void *addr); From 34faa5955af9527d6d12cca5bf22b613b98586a0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Apr 2011 23:10:19 +0200 Subject: [PATCH 0880/1414] * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge chunks. * include/grub/err.h (grub_err_t): New enum value GRUB_ERR_BUG. --- ChangeLog | 6 ++++++ grub-core/fs/btrfs.c | 29 ++++++++++++++++++++--------- include/grub/err.h | 3 ++- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index f46277405..676c374aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-18 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge + chunks. + * include/grub/err.h (grub_err_t): New enum value GRUB_ERR_BUG. + 2011-04-18 Vladimir Serbinenko Complete 64-bit division support. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index bbb326b98..42aa257d9 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -588,7 +588,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_uint8_t *ptr; struct grub_btrfs_key *key; struct grub_btrfs_chunk_item *chunk; - grub_ssize_t csize; + grub_uint64_t csize; grub_err_t err; struct grub_btrfs_key key_out; int challoc = 0; @@ -648,11 +648,18 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, chunk_found: { grub_uint32_t stripen; - grub_uint32_t stripe_offset; + grub_uint64_t stripe_offset; grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); unsigned redundancy = 1; unsigned i, j; + if (grub_le_to_cpu64 (chunk->size) <= off) + { + grub_dprintf ("btrfs", "no chunk\n"); + return grub_error (GRUB_ERR_BAD_FS, + "couldn't find the chunk descriptor"); + } + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" @@ -668,17 +675,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, { case GRUB_BTRFS_CHUNK_TYPE_SINGLE: { - grub_uint32_t stripe_length; - 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); + 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); csize = (stripen + 1) * stripe_length - off; break; } case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: case GRUB_BTRFS_CHUNK_TYPE_RAID1: { + grub_dprintf ("btrfs", "RAID1\n"); stripen = 0; stripe_offset = off; csize = grub_le_to_cpu64 (chunk->size) - off; @@ -689,6 +698,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, { grub_uint64_t middle, high; grub_uint32_t low; + grub_dprintf ("btrfs", "RAID0\n"); middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), &low); @@ -721,12 +731,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, break; } default: + grub_dprintf ("btrfs", "unsupported RAID\n"); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "unsupported RAID flags %" PRIxGRUB_UINT64_T, grub_le_to_cpu64 (chunk->type)); } - if (csize <= 0) - return grub_error (GRUB_ERR_BAD_FS, + if (csize == 0) + return grub_error (GRUB_ERR_BUG, "couldn't find the chunk descriptor"); if ((grub_size_t) csize > size) csize = size; diff --git a/include/grub/err.h b/include/grub/err.h index 22334038d..69bc6ec79 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -55,7 +55,8 @@ typedef enum GRUB_ERR_TIMEOUT, GRUB_ERR_IO, GRUB_ERR_ACCESS_DENIED, - GRUB_ERR_EXTRACTOR + GRUB_ERR_EXTRACTOR, + GRUB_ERR_BUG } grub_err_t; From e74b3947af1d11b8279706e07302ed0debe82779 Mon Sep 17 00:00:00 2001 From: Endres Puschner Date: Mon, 18 Apr 2011 23:24:41 +0200 Subject: [PATCH 0881/1414] * grub-core/gfxmenu/icon_manager.c (grub_gfxmenu_icon_manager_get_icon): Don't skip first class. --- ChangeLog | 5 +++++ grub-core/gfxmenu/icon_manager.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 676c374aa..8c00f7849 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-18 Endres Puschner + + * grub-core/gfxmenu/icon_manager.c (grub_gfxmenu_icon_manager_get_icon): + Don't skip first class. + 2011-04-18 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge diff --git a/grub-core/gfxmenu/icon_manager.c b/grub-core/gfxmenu/icon_manager.c index 0c304ede0..6990d05d4 100644 --- a/grub-core/gfxmenu/icon_manager.c +++ b/grub-core/gfxmenu/icon_manager.c @@ -257,7 +257,7 @@ grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr, /* Try each class in succession. */ icon = 0; - for (c = entry->classes->next; c && ! icon; c = c->next) + for (c = entry->classes; c && ! icon; c = c->next) icon = get_icon_by_class (mgr, c->name); return icon; } From abc474ef4bb79cd21e5510c302309ab87008ef65 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 19 Apr 2011 00:44:53 +0200 Subject: [PATCH 0882/1414] Take into account the decorations the computing menu entry width. * grub-core/gfxmenu/widget-box.c (get_border_width): New function. (grub_gfxmenu_create_box): Register get_border_width. * grub-core/gfxmenu/gui_list.c (draw_menu): Use get_border_width if available. * include/grub/gfxwidgets.h (grub_gfxmenu_box): New member get_border_width. --- ChangeLog | 11 +++++++++++ grub-core/gfxmenu/gui_list.c | 6 ++++-- grub-core/gfxmenu/widget-box.c | 9 +++++++++ include/grub/gfxwidgets.h | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c00f7849..79d868f86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-04-19 Vladimir Serbinenko + + Take into account the decorations the computing menu entry width. + + * grub-core/gfxmenu/widget-box.c (get_border_width): New function. + (grub_gfxmenu_create_box): Register get_border_width. + * grub-core/gfxmenu/gui_list.c (draw_menu): Use get_border_width + if available. + * include/grub/gfxwidgets.h (grub_gfxmenu_box): New member + get_border_width. + 2011-04-18 Endres Puschner * grub-core/gfxmenu/icon_manager.c (grub_gfxmenu_icon_manager_get_icon): diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index b6b07dfd6..e5d6fc2a1 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -248,8 +248,10 @@ draw_menu (list_impl_t self, int num_shown_items) if (is_selected) { - selbox->set_content_size (selbox, oviewport.width - 2 * boxpad - 2, - item_height - 1); + int cwidth = oviewport.width - 2 * boxpad - 2; + if (selbox->get_border_width) + cwidth -= selbox->get_border_width (selbox); + selbox->set_content_size (selbox, cwidth, item_height - 1); selbox->draw (selbox, 0, item_top - sel_toppad); } diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c index 244fe1e6c..41ca7f536 100644 --- a/grub-core/gfxmenu/widget-box.c +++ b/grub-core/gfxmenu/widget-box.c @@ -178,6 +178,13 @@ set_content_size (grub_gfxmenu_box_t self, return; } +static int +get_border_width (grub_gfxmenu_box_t self) +{ + return (get_width (self->raw_pixmaps[BOX_PIXMAP_E]) + + get_width (self->raw_pixmaps[BOX_PIXMAP_W])); +} + static int get_left_pad (grub_gfxmenu_box_t self) { @@ -288,6 +295,8 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix, box->draw = draw; box->set_content_size = set_content_size; + box->get_border_width = get_border_width; + box->get_left_pad = get_left_pad; box->get_top_pad = get_top_pad; box->get_right_pad = get_right_pad; diff --git a/include/grub/gfxwidgets.h b/include/grub/gfxwidgets.h index f9678bf9e..8ce666c5c 100644 --- a/include/grub/gfxwidgets.h +++ b/include/grub/gfxwidgets.h @@ -36,6 +36,7 @@ struct grub_gfxmenu_box void (*draw) (grub_gfxmenu_box_t self, int x, int y); void (*set_content_size) (grub_gfxmenu_box_t self, int width, int height); + int (*get_border_width) (grub_gfxmenu_box_t self); int (*get_left_pad) (grub_gfxmenu_box_t self); int (*get_top_pad) (grub_gfxmenu_box_t self); int (*get_right_pad) (grub_gfxmenu_box_t self); From bba79a1502b433c013ac034ed931da93f30802d4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 19 Apr 2011 22:31:50 +0200 Subject: [PATCH 0883/1414] * grub-core/term/gfxterm.c (grub_gfxterm_fullscreen): Preserve previous bitmap. (grub_gfxterm_term_init): Likewise. --- ChangeLog | 6 ++++++ grub-core/term/gfxterm.c | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79d868f86..2eade534d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-19 Vladimir Serbinenko + + * grub-core/term/gfxterm.c (grub_gfxterm_fullscreen): Preserve previous + bitmap. + (grub_gfxterm_term_init): Likewise. + 2011-04-19 Vladimir Serbinenko Take into account the decorations the computing menu entry width. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 0ade65f27..e58d6722d 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -345,7 +345,6 @@ grub_gfxterm_fullscreen (void) grub_video_swap_buffers (); grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); } - bitmap = 0; /* Select the font to use. */ font_name = grub_env_get ("gfxterm_font"); @@ -394,12 +393,6 @@ grub_gfxterm_term_init (struct grub_term_output *term __attribute__ ((unused))) static void destroy_window (void) { - if (bitmap) - { - grub_video_bitmap_destroy (bitmap); - bitmap = 0; - } - repaint_callback = 0; grub_virtual_screen_free (); } From e8f28d4c0e8af4103e50776a0614cd2c73a98136 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 19 Apr 2011 22:39:14 +0200 Subject: [PATCH 0884/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_flush): New function. (grub_util_biosdisk_close): Use grub_util_biosdisk_flush. * include/grub/emu/hostdisk.h (grub_util_biosdisk_flush): New proto. * util/grub-setup.c (setup): Use grub_util_biosdisk_flush. --- ChangeLog | 8 ++++++++ grub-core/kern/emu/hostdisk.c | 29 ++++++++++++++++++++++------- include/grub/emu/hostdisk.h | 1 + util/grub-setup.c | 10 ++++------ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2eade534d..1eff73ca3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-04-19 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_flush): + New function. + (grub_util_biosdisk_close): Use grub_util_biosdisk_flush. + * include/grub/emu/hostdisk.h (grub_util_biosdisk_flush): New proto. + * util/grub-setup.c (setup): Use grub_util_biosdisk_flush. + 2011-04-19 Vladimir Serbinenko * grub-core/term/gfxterm.c (grub_gfxterm_fullscreen): Preserve previous diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index f01e21aa0..63bca37ee 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -945,6 +945,27 @@ grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, return grub_errno; } +grub_err_t +grub_util_biosdisk_flush (struct grub_disk *disk) +{ + struct grub_util_biosdisk_data *data = disk->data; + + if (disk->dev->id != GRUB_DISK_DEVICE_BIOSDISK_ID) + return GRUB_ERR_NONE; + if (data->fd == -1) + { + data->fd = open_device (disk, 0, O_RDONLY); + if (data->fd < 0) + return grub_errno; + } + fsync (data->fd); +#ifdef __linux__ + if (data->is_disk) + ioctl (data->fd, BLKFLSBUF, 0); +#endif + return GRUB_ERR_NONE; +} + static void grub_util_biosdisk_close (struct grub_disk *disk) { @@ -954,13 +975,7 @@ grub_util_biosdisk_close (struct grub_disk *disk) if (data->fd != -1) { if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) - { - fsync (data->fd); -#ifdef __linux__ - if (data->is_disk) - ioctl (data->fd, BLKFLSBUF, 0); -#endif - } + grub_util_biosdisk_flush (disk); close (data->fd); } free (data); diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index d8cc02e14..842dff496 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -28,5 +28,6 @@ char *grub_util_biosdisk_get_grub_dev (const char *os_dev); const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); int grub_util_biosdisk_is_present (const char *name); int grub_util_biosdisk_is_floppy (grub_disk_t disk); +grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/grub-setup.c b/util/grub-setup.c index ed2d63fdd..7d47fa654 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -520,9 +520,7 @@ unable_to_embed: core_path_dev = grub_make_system_path_relative_to_its_root (core_path_dev_full); free (core_path_dev_full); - /* It is a Good Thing to sync two times. */ - sync (); - sync (); + grub_util_biosdisk_flush (root_dev->disk); #define MAX_TRIES 5 @@ -583,7 +581,7 @@ unable_to_embed: grub_util_info ("error message = %s", grub_errmsg); grub_errno = GRUB_ERR_NONE; - sync (); + grub_util_biosdisk_flush (root_dev->disk); sleep (1); } @@ -674,8 +672,8 @@ unable_to_embed: grub_util_error ("%s", grub_errmsg); - /* Sync is a Good Thing. */ - sync (); + grub_util_biosdisk_flush (root_dev->disk); + grub_util_biosdisk_flush (dest_dev->disk); free (core_path); free (core_img); From 0624551c2286f9ce94f6c9a24a66da6f60dbe08b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Apr 2011 01:32:21 +0200 Subject: [PATCH 0885/1414] * grub-core/lib/efi/datetime.c: Add missing GRUB_MOD_LICENSE. * grub-core/lib/efi/datetime.c: Likewise. --- ChangeLog | 5 +++++ grub-core/lib/efi/datetime.c | 3 +++ grub-core/lib/ieee1275/datetime.c | 3 +++ 3 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1eff73ca3..877186e23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-20 Vladimir Serbinenko + + * grub-core/lib/efi/datetime.c: Add missing GRUB_MOD_LICENSE. + * grub-core/lib/efi/datetime.c: Likewise. + 2011-04-19 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_flush): diff --git a/grub-core/lib/efi/datetime.c b/grub-core/lib/efi/datetime.c index 0a91c345a..0fd1b5fbd 100644 --- a/grub-core/lib/efi/datetime.c +++ b/grub-core/lib/efi/datetime.c @@ -22,6 +22,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); grub_err_t grub_get_datetime (struct grub_datetime *datetime) diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c index 7e6f8d1f1..4105c639b 100644 --- a/grub-core/lib/ieee1275/datetime.c +++ b/grub-core/lib/ieee1275/datetime.c @@ -20,6 +20,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); static char *rtc = 0; From d97e7b5935896a7c5bfe0592385bf19a77f97560 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Apr 2011 01:37:48 +0200 Subject: [PATCH 0886/1414] * include/grub/dl.h [ASM_FILE]: Adapt for assembly. * grub-core/lib/i386/setjmp.S: Add missing GRUB_MOD_LICENSE. * grub-core/lib/x86_64/setjmp.S: Likewise. * grub-core/lib/mips/setjmp.S: Likewise. * grub-core/lib/powerpc/setjmp.S: Likewise. * grub-core/lib/sparc64/setjmp.S: Likewise. --- ChangeLog | 9 +++++++++ grub-core/lib/i386/setjmp.S | 3 +++ grub-core/lib/mips/setjmp.S | 3 +++ grub-core/lib/powerpc/setjmp.S | 3 +++ grub-core/lib/sparc64/setjmp.S | 3 +++ grub-core/lib/x86_64/setjmp.S | 3 +++ include/grub/dl.h | 31 ++++++++++++++++++++++++++++--- 7 files changed, 52 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 877186e23..c78ae8cab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-04-20 Vladimir Serbinenko + + * include/grub/dl.h [ASM_FILE]: Adapt for assembly. + * grub-core/lib/i386/setjmp.S: Add missing GRUB_MOD_LICENSE. + * grub-core/lib/x86_64/setjmp.S: Likewise. + * grub-core/lib/mips/setjmp.S: Likewise. + * grub-core/lib/powerpc/setjmp.S: Likewise. + * grub-core/lib/sparc64/setjmp.S: Likewise. + 2011-04-20 Vladimir Serbinenko * grub-core/lib/efi/datetime.c: Add missing GRUB_MOD_LICENSE. diff --git a/grub-core/lib/i386/setjmp.S b/grub-core/lib/i386/setjmp.S index a2002ae3d..5b7aa158b 100644 --- a/grub-core/lib/i386/setjmp.S +++ b/grub-core/lib/i386/setjmp.S @@ -17,9 +17,12 @@ */ #include +#include .file "setjmp.S" +GRUB_MOD_LICENSE ("GPLv3+") + .text /* diff --git a/grub-core/lib/mips/setjmp.S b/grub-core/lib/mips/setjmp.S index 8ab6222c4..8259c9d22 100644 --- a/grub-core/lib/mips/setjmp.S +++ b/grub-core/lib/mips/setjmp.S @@ -17,9 +17,12 @@ */ #include +#include .file "setjmp.S" +GRUB_MOD_LICENSE ("GPLv3+") + .text /* diff --git a/grub-core/lib/powerpc/setjmp.S b/grub-core/lib/powerpc/setjmp.S index 25cbaa3e9..8c7540e3c 100644 --- a/grub-core/lib/powerpc/setjmp.S +++ b/grub-core/lib/powerpc/setjmp.S @@ -17,9 +17,12 @@ */ #include +#include .file "setjmp.S" +GRUB_MOD_LICENSE ("GPLv3+") + .text /* diff --git a/grub-core/lib/sparc64/setjmp.S b/grub-core/lib/sparc64/setjmp.S index 0e23ecfa1..5c2ec2cf3 100644 --- a/grub-core/lib/sparc64/setjmp.S +++ b/grub-core/lib/sparc64/setjmp.S @@ -17,9 +17,12 @@ */ #include +#include .file "setjmp.S" +GRUB_MOD_LICENSE ("GPLv3+") + .text /* diff --git a/grub-core/lib/x86_64/setjmp.S b/grub-core/lib/x86_64/setjmp.S index 621b09b93..b1f1b22cb 100644 --- a/grub-core/lib/x86_64/setjmp.S +++ b/grub-core/lib/x86_64/setjmp.S @@ -17,9 +17,12 @@ */ #include +#include .file "setjmp.S" +GRUB_MOD_LICENSE ("GPLv3+") + .text /* diff --git a/include/grub/dl.h b/include/grub/dl.h index 71db90c8b..6f23f7d63 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -21,15 +21,18 @@ #define GRUB_DL_H 1 #include +#ifndef ASM_FILE #include #include #include +#endif /* * Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules * to collect module names, so we define them only when they are not * defined already. */ +#ifndef ASM_FILE #ifndef GRUB_MOD_INIT #define GRUB_MOD_INIT(name) \ @@ -66,10 +69,20 @@ __asm__ (".section .moddeps\n.asciz \"" #name "\"\n") #endif +#endif + +#ifndef ASM_FILE #ifdef APPLE_CC -#define GRUB_MOD_SECTION(x) "_" x ", _" x "" +#define GRUB_MOD_SECTION(x) "_" #x ", _" #x "" #else -#define GRUB_MOD_SECTION(x) "." x +#define GRUB_MOD_SECTION(x) "." #x +#endif +#else +#ifdef APPLE_CC +#define GRUB_MOD_SECTION(x) _ ## x , _ ##x +#else +#define GRUB_MOD_SECTION(x) . ## x +#endif #endif /* Me, Vladimir Serbinenko, hereby I add this module check as per new @@ -80,8 +93,16 @@ __asm__ (".section .moddeps\n.asciz \"" #name "\"\n") constitutes linking) and GRUB core being licensed under GPLv3+. Be sure to understand your license obligations. */ +#ifndef ASM_FILE #define GRUB_MOD_LICENSE(license) \ - static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION ("module_license")), used)) = "LICENSE=" license; + static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), used)) = "LICENSE=" license; +#else +#define GRUB_MOD_LICENSE(license) \ + .section GRUB_MOD_SECTION(module_license), "a"; \ + .ascii "LICENSE="; \ + .ascii license; \ + .byte 0 +#endif /* Under GPL license obligations you have to distribute your module under GPLv3(+). However, you can also distribute the same code under @@ -89,6 +110,8 @@ __asm__ (".section .moddeps\n.asciz \"" #name "\"\n") */ #define GRUB_MOD_DUAL_LICENSE(x) +#ifndef ASM_FILE + struct grub_dl_segment { struct grub_dl_segment *next; @@ -143,4 +166,6 @@ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); void grub_arch_dl_init_linker (void); #endif +#endif + #endif /* ! GRUB_DL_H */ From 9b710a888e80862a18449bc9b5a31e2148da56c6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Apr 2011 09:23:55 +0200 Subject: [PATCH 0887/1414] * configure.ac: Bump version to 1.99~rc2. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c78ae8cab..083d22ec5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-20 Vladimir Serbinenko + + * configure.ac: Bump version to 1.99~rc2. + 2011-04-20 Vladimir Serbinenko * include/grub/dl.h [ASM_FILE]: Adapt for assembly. diff --git a/configure.ac b/configure.ac index f9e974bca..811bd992d 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~rc1],[bug-grub@gnu.org]) +AC_INIT([GRUB],[1.99~rc2],[bug-grub@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) From b13f79a427b6ae6c1405c48b8cf57a1e99de16f9 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 21 Apr 2011 00:07:22 +0100 Subject: [PATCH 0888/1414] Fix stack pointer handling in 16-bit relocator. * grub-core/lib/i386/relocator16.S (grub_relocator16_start): Move grub_relocator16_sp to %esp rather than %ss, and zero-extend it. Fixes Ubuntu bug #683904. --- ChangeLog | 8 ++++++++ grub-core/lib/i386/relocator16.S | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 083d22ec5..98d3b0ea8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-04-21 Colin Watson + + Fix stack pointer handling in 16-bit relocator. + + * grub-core/lib/i386/relocator16.S (grub_relocator16_start): Move + grub_relocator16_sp to %esp rather than %ss, and zero-extend it. + Fixes Ubuntu bug #683904. + 2011-04-20 Vladimir Serbinenko * configure.ac: Bump version to 1.99~rc2. diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index c3768f4eb..982415de4 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -130,7 +130,7 @@ VARIABLE(grub_relocator16_ss) .byte 0xb8 VARIABLE(grub_relocator16_sp) .word 0 - movw %ax, %ss + movzwl %ax, %esp /* movw imm32, %edx. */ .byte 0x66, 0xba From 7217f315d375c678d4f00a4601923769b9b5a6ad Mon Sep 17 00:00:00 2001 From: Michael Gorven Date: Thu, 21 Apr 2011 11:14:29 +0200 Subject: [PATCH 0889/1414] LUKS support based on work of Michael Gorven with some code from Clemens Fruhwirth and heavily cleaned up by me (phcoder) Also-By: Clemens Fruhwirth Also-By: Vladimir Serbinenko --- grub-core/Makefile.core.def | 6 + grub-core/disk/AFSplitter.c | 104 ++++++ grub-core/disk/luks.c | 700 ++++++++++++++++++++++++++++++++++++ 3 files changed, 810 insertions(+) create mode 100644 grub-core/disk/AFSplitter.c create mode 100644 grub-core/disk/luks.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f4d38149d..b8c996ba7 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -767,6 +767,12 @@ module = { common = disk/loopback.c; }; +module = { + name = luks; + common = disk/luks.c; + common = disk/AFSplitter.c; +}; + module = { name = lvm; common = disk/lvm.c; diff --git a/grub-core/disk/AFSplitter.c b/grub-core/disk/AFSplitter.c new file mode 100644 index 000000000..6c3dc488e --- /dev/null +++ b/grub-core/disk/AFSplitter.c @@ -0,0 +1,104 @@ +/* + * AFsplitter - Anti forensic information splitter + * Copyright 2004, Clemens Fruhwirth + * + * AFsplitter diffuses information over a large stripe of data, + * therefor supporting secure data destruction. + * + * This program is grub_free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the grub_free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * along with this program; if not, write to the grub_free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_uint8_t * dst, grub_size_t blocksize, + grub_size_t blocknumbers); +static void diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_uint8_t * dst, grub_size_t size); +gcry_err_code_t AF_split (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_uint8_t * dst, grub_size_t blocksize, + grub_size_t blocknumbers); + + +static void +diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_uint8_t * dst, grub_size_t size) +{ + grub_size_t i; + grub_uint32_t IV; /* host byte order independend hash IV */ + + grub_size_t fullblocks = size / hash->mdlen; + int padding = size % hash->mdlen; + grub_uint8_t final[hash->mdlen]; + grub_uint8_t temp[sizeof (IV) + hash->mdlen]; + + /* hash block the whole data set with different IVs to produce + * more than just a single data block + */ + for (i = 0; i < fullblocks; i++) + { + IV = grub_cpu_to_be32 (i); + grub_memcpy (temp, &IV, sizeof (IV)); + grub_memcpy (temp + sizeof (IV), src + hash->mdlen * i, hash->mdlen); + grub_crypto_hash (hash, dst + hash->mdlen * i, temp, + sizeof (IV) + hash->mdlen); + } + + if (padding) + { + IV = grub_cpu_to_be32 (i); + grub_memcpy (temp, &IV, sizeof (IV)); + grub_memcpy (temp + sizeof (IV), src + hash->mdlen * i, padding); + grub_crypto_hash (hash, final, temp, sizeof (IV) + padding); + grub_memcpy (dst + hash->mdlen * i, final, padding); + } +} + +/** + * Merges the splitted master key stored on disk into the original key + */ +gcry_err_code_t +AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst, + grub_size_t blocksize, grub_size_t blocknumbers) +{ + grub_size_t i; + grub_uint8_t *bufblock; + + bufblock = grub_zalloc (blocksize); + if (bufblock == NULL) + return GPG_ERR_OUT_OF_MEMORY; + + grub_memset (bufblock, 0, blocksize); + for (i = 0; i < blocknumbers - 1; i++) + { + grub_crypto_xor (bufblock, src + (blocksize * i), bufblock, blocksize); + diffuse (hash, bufblock, bufblock, blocksize); + } + grub_crypto_xor (dst, src + (i * blocksize), bufblock, blocksize); + + grub_free (bufblock); + return GPG_ERR_NO_ERROR; +} diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c new file mode 100644 index 000000000..47d10d63c --- /dev/null +++ b/grub-core/disk/luks.c @@ -0,0 +1,700 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2010,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 +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define MAX_PASSPHRASE 256 + +#define LUKS_KEY_ENABLED 0x00AC71F3 +#define LUKS_STRIPES 4000 + +/* On disk LUKS header */ +struct grub_luks_phdr +{ + grub_uint8_t magic[6]; +#define LUKS_MAGIC "LUKS\xBA\xBE" + grub_uint16_t version; + char cipherName[32]; + char cipherMode[32]; + char hashSpec[32]; + grub_uint32_t payloadOffset; + grub_uint32_t keyBytes; + grub_uint8_t mkDigest[20]; + grub_uint8_t mkDigestSalt[32]; + grub_uint32_t mkDigestIterations; + grub_uint8_t uuid[40]; + struct + { + grub_uint32_t active; + grub_uint32_t passwordIterations; + grub_uint8_t passwordSalt[32]; + grub_uint32_t keyMaterialOffset; + grub_uint32_t stripes; + } keyblock[8]; +} __attribute__ ((packed)); + +typedef struct grub_luks_phdr *grub_luks_phdr_t; + +typedef enum +{ + GRUB_LUKS_MODE_ECB, + GRUB_LUKS_MODE_CBC_PLAIN, + GRUB_LUKS_MODE_CBC_ESSIV +} +luks_mode_t; + +struct grub_luks +{ + char *devname, *source; + grub_uint32_t offset; + grub_disk_t source_disk; + int ref; + grub_crypto_cipher_handle_t cipher; + grub_crypto_cipher_handle_t essiv_cipher; + luks_mode_t mode; + int id; + struct grub_luks *next; +}; +typedef struct grub_luks *grub_luks_t; + +static grub_luks_t luks_list = NULL; +static grub_uint8_t n = 0; + +gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_uint8_t * dst, grub_size_t blocksize, + grub_size_t blocknumbers); + +static const struct grub_arg_option options[] = + { + {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static gcry_err_code_t +luks_decrypt (grub_crypto_cipher_handle_t cipher, luks_mode_t mode, + grub_uint8_t * data, grub_size_t len, + grub_size_t sector, grub_crypto_cipher_handle_t essiv_cipher) +{ + grub_size_t i; + gcry_err_code_t err; + + switch (mode) + { + case GRUB_LUKS_MODE_ECB: + return grub_crypto_ecb_decrypt (cipher, data, data, len); + + case GRUB_LUKS_MODE_CBC_PLAIN: + for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) + { + grub_uint32_t iv[(cipher->cipher->blocksize + + sizeof (grub_uint32_t) - 1) + / sizeof (grub_uint32_t)]; + grub_memset (iv, 0, cipher->cipher->blocksize); + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + err = grub_crypto_cbc_decrypt (cipher, data + i, data + i, + GRUB_DISK_SECTOR_SIZE, iv); + if (err) + return err; + sector++; + } + return GPG_ERR_NO_ERROR; + + case GRUB_LUKS_MODE_CBC_ESSIV: + for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) + { + grub_uint32_t iv[(cipher->cipher->blocksize + + sizeof (grub_uint32_t) - 1) + / sizeof (grub_uint32_t)]; + grub_memset (iv, 0, cipher->cipher->blocksize); + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + err = + grub_crypto_ecb_encrypt (essiv_cipher, iv, iv, + cipher->cipher->blocksize); + if (err) + return err; + err = grub_crypto_cbc_decrypt (cipher, data + i, data + i, + GRUB_DISK_SECTOR_SIZE, iv); + if (err) + return err; + sector++; + } + return GPG_ERR_NO_ERROR; + + default: + return GPG_ERR_NOT_IMPLEMENTED; + } +} + +static int check_uuid, have_it; +static char *uuid; + +static grub_err_t +grub_luks_scan_device_real (const char *name) +{ + grub_disk_t source; + grub_err_t err; + grub_luks_t newdev; + struct grub_luks_phdr header; + grub_crypto_cipher_handle_t cipher = NULL, essiv_cipher = NULL; + const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; + grub_size_t keysize; + /* GCC thinks we may use this variable uninitialised. Silence the warning. */ + grub_size_t essiv_keysize = 0; + grub_uint8_t *hashed_key = NULL; + luks_mode_t mode; + grub_uint8_t *split_key = NULL; + unsigned i; + grub_size_t length; + const struct gcry_cipher_spec *ciph; + char passphrase[MAX_PASSPHRASE] = ""; + grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; + + /* Try to open disk. */ + source = grub_disk_open (name); + if (!source) + return grub_errno; + + /* Read the LUKS header. */ + err = grub_disk_read (source, 0, 0, sizeof (header), &header); + if (err) + { + grub_disk_close (source); + return err; + } + + /* Look for LUKS magic sequence. */ + if (grub_memcmp (header.magic, LUKS_MAGIC, sizeof (header.magic)) + || grub_be_to_cpu16 (header.version) != 1) + { + grub_disk_close (source); + return GRUB_ERR_NONE; + } + + if (check_uuid && grub_memcmp (header.uuid, uuid, + sizeof (header.uuid)) != 0) + return 0; + + newdev = grub_zalloc (sizeof (struct grub_luks)); + if (!newdev) + { + grub_disk_close (source); + return grub_errno; + } + + newdev->id = n; + newdev->devname = grub_xasprintf ("luks%d", n); + newdev->source = grub_strdup (name); + n++; + + /* Make sure that strings are null terminated. */ + header.cipherName[sizeof (header.cipherName) - 1] = 0; + header.cipherMode[sizeof (header.cipherMode) - 1] = 0; + header.hashSpec[sizeof (header.hashSpec) - 1] = 0; + + ciph = grub_crypto_lookup_cipher_by_name (header.cipherName); + if (!ciph) + { + grub_disk_close (source); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", + header.cipherName); + } + + /* Configure the cipher used for the bulk data. */ + cipher = grub_crypto_cipher_open (ciph); + if (!cipher) + { + grub_disk_close (source); + grub_free (newdev); + return grub_errno; + } + + keysize = grub_be_to_cpu32 (header.keyBytes); + if (keysize > 1024) + { + grub_disk_close (source); + grub_free (newdev); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", + keysize); + } + + /* Configure the cipher mode. */ + if (grub_strncmp (header.cipherMode, "ecb", 3) == 0) + mode = GRUB_LUKS_MODE_ECB; + else if (grub_strncmp (header.cipherMode, "cbc-plain", 9) == 0 + || grub_strncmp (header.cipherMode, "plain", 5) == 0) + mode = GRUB_LUKS_MODE_CBC_PLAIN; + else if (grub_strncmp (header.cipherMode, "cbc-essiv", 9) == 0) + { + mode = GRUB_LUKS_MODE_CBC_ESSIV; + char *hash_str = header.cipherMode + 10; + + /* Configure the hash and cipher used for ESSIV. */ + essiv_hash = grub_crypto_lookup_md_by_name (hash_str); + if (!essiv_hash) + { + grub_crypto_cipher_close (cipher); + grub_disk_close (source); + grub_free (newdev); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load %s hash", hash_str); + } + essiv_cipher = grub_crypto_cipher_open (ciph); + if (!cipher) + { + grub_crypto_cipher_close (cipher); + grub_disk_close (source); + grub_free (newdev); + return grub_errno; + } + + essiv_keysize = essiv_hash->mdlen; + hashed_key = grub_malloc (essiv_hash->mdlen); + if (!hashed_key) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_disk_close (source); + grub_free (newdev); + return grub_errno; + } + } + else + { + grub_crypto_cipher_close (cipher); + grub_disk_close (source); + grub_free (newdev); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", + header.cipherMode); + } + + /* Configure the hash used for the AF splitter and HMAC. */ + hash = grub_crypto_lookup_md_by_name (header.hashSpec); + if (!hash) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_disk_close (source); + grub_free (newdev); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", + header.hashSpec); + } + + grub_printf ("Attempting to decrypt master key...\n"); + + grub_uint8_t candidate_key[keysize]; + grub_uint8_t digest[keysize]; + + split_key = grub_malloc (keysize * LUKS_STRIPES); + if (!split_key) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_disk_close (source); + grub_free (newdev); + return grub_errno; + } + + /* Get the passphrase from the user. */ + grub_printf ("Enter passphrase: "); + if (!grub_password_get (passphrase, MAX_PASSPHRASE)) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); + } + + /* Try to recover master key from each active keyslot. */ + for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) + { + gcry_err_code_t gcry_err; + + /* Check if keyslot is enabled. */ + if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) + continue; + + grub_dprintf ("luks", "Trying keyslot %d\n", i); + + /* Calculate the PBKDF2 of the user supplied passphrase. */ + gcry_err = grub_crypto_pbkdf2 (hash, (grub_uint8_t *) passphrase, + grub_strlen (passphrase), + header.keyblock[i].passwordSalt, + sizeof (header. + keyblock[i].passwordSalt), + grub_be_to_cpu32 (header.keyblock[i]. + passwordIterations), + digest, keysize); + + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + + grub_dprintf ("luks", "PBKDF2 done\n"); + + /* Set the PBKDF2 output as the cipher key. */ + gcry_err = grub_crypto_cipher_set_key (cipher, digest, keysize); + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + + /* Configure ESSIV if necessary. */ + if (mode == GRUB_LUKS_MODE_CBC_ESSIV) + { + grub_crypto_hash (essiv_hash, hashed_key, digest, keysize); + grub_crypto_cipher_set_key (essiv_cipher, hashed_key, + essiv_keysize); + } + + length = + grub_be_to_cpu32 (header.keyBytes) * + grub_be_to_cpu32 (header.keyblock[i].stripes); + + /* Read and decrypt the key material from the disk. */ + err = grub_disk_read (source, + grub_be_to_cpu32 (header.keyblock + [i].keyMaterialOffset), 0, + length, split_key); + if (err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return err; + } + + gcry_err = luks_decrypt (cipher, mode, split_key, + length, 0, essiv_cipher); + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + + /* Merge the decrypted key material to get the candidate master key. */ + gcry_err = AF_merge (hash, split_key, candidate_key, keysize, + grub_be_to_cpu32 (header.keyblock[i].stripes)); + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + + grub_dprintf ("luks", "candidate key recovered\n"); + + /* Calculate the PBKDF2 of the candidate master key. */ + gcry_err = grub_crypto_pbkdf2 (hash, candidate_key, + grub_be_to_cpu32 (header.keyBytes), + header.mkDigestSalt, + sizeof (header.mkDigestSalt), + grub_be_to_cpu32 + (header.mkDigestIterations), + candidate_digest, + sizeof (candidate_digest)); + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_disk_close (source); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + + /* Compare the calculated PBKDF2 to the digest stored + in the header to see if it's correct. */ + if (grub_memcmp (candidate_digest, header.mkDigest, + sizeof (header.mkDigest)) != 0) + continue; + + grub_disk_close (source); + + grub_printf ("Slot %d opened\n", i); + + /* Set the master key. */ + gcry_err = grub_crypto_cipher_set_key (cipher, candidate_key, keysize); + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + + newdev->cipher = cipher; + + /* Configure ESSIV if necessary. */ + if (mode == GRUB_LUKS_MODE_CBC_ESSIV) + { + grub_crypto_hash (essiv_hash, hashed_key, candidate_key, keysize); + gcry_err = + grub_crypto_cipher_set_key (essiv_cipher, hashed_key, + essiv_keysize); + if (gcry_err) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); + grub_free (hashed_key); + grub_free (split_key); + grub_free (newdev); + return grub_crypto_gcry_error (gcry_err); + } + newdev->essiv_cipher = essiv_cipher; + } + else + { + newdev->essiv_cipher = NULL; + } + + newdev->offset = grub_be_to_cpu32 (header.payloadOffset); + newdev->source_disk = NULL; + newdev->mode = mode; + + grub_free (split_key); + grub_free (hashed_key); + newdev->next = luks_list; + luks_list = newdev; + + have_it = 1; + + return GRUB_ERR_NONE; + } + + return GRUB_ACCESS_DENIED; +} + +static int +grub_luks_scan_device (const char *name) +{ + grub_err_t err; + err = grub_luks_scan_device_real (name); + if (err) + grub_print_error (); + return have_it && check_uuid ? 0 : 1; +} + +static int +grub_luks_iterate (int (*hook) (const char *name)) +{ + grub_luks_t i; + + for (i = luks_list; i != NULL; i = i->next) + if (hook (i->devname)) + return 1; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_luks_open (const char *name, grub_disk_t disk) +{ + grub_luks_t dev; + + /* Search for requested device in the list of LUKS devices. */ + for (dev = luks_list; dev != NULL; dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (!dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + + if (!dev->source_disk) + { + grub_dprintf ("luks", "Opening device %s\n", name); + /* Try to open the source disk and populate the requested disk. */ + dev->source_disk = grub_disk_open (dev->source); + if (!dev->source_disk) + return grub_errno; + } + + disk->data = dev; + disk->total_sectors = grub_disk_get_size (dev->source_disk) - dev->offset; + disk->id = dev->id; + dev->ref++; + return GRUB_ERR_NONE; +} + +static void +grub_luks_close (grub_disk_t disk) +{ + grub_luks_t dev = (grub_luks_t) disk->data; + grub_dprintf ("luks", "Closing disk\n"); + + dev->ref--; + + if (dev->ref == 0) + { + grub_disk_close (dev->source_disk); + dev->source_disk = NULL; + } +} + +static grub_err_t +grub_luks_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_luks_t dev = (grub_luks_t) disk->data; + grub_err_t err; + grub_dprintf ("luks", + "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%" + PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT32_T "\n", + size, sector, dev->offset); + + err = grub_disk_read (dev->source_disk, sector + dev->offset, 0, + size << GRUB_DISK_SECTOR_BITS, buf); + if (err) + { + grub_dprintf ("luks", "grub_disk_read failed with error %d\n", err); + return err; + } + return grub_crypto_gcry_error (luks_decrypt (dev->cipher, + dev->mode, + (grub_uint8_t *) buf, + size << GRUB_DISK_SECTOR_BITS, + sector, dev->essiv_cipher)); +} + +static grub_err_t +grub_luks_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 void +luks_cleanup (void) +{ + grub_luks_t dev = luks_list; + grub_luks_t tmp; + + while (dev != NULL) + { + grub_free (dev->devname); + grub_free (dev->source); + grub_free (dev->cipher); + grub_free (dev->essiv_cipher); + tmp = dev->next; + grub_free (dev); + dev = tmp; + } +} + +static grub_err_t +grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + have_it = 0; + if (state[0].set) + { + check_uuid = 1; + uuid = args[0]; + grub_device_iterate (&grub_luks_scan_device); + uuid = NULL; + } + else + { + grub_err_t err; + check_uuid = 0; + uuid = NULL; + err = grub_luks_scan_device_real (args[0]); + return err; + } + if (!have_it) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); + return 0; +} + +static struct grub_disk_dev grub_luks_dev = { + .name = "luks", + .id = GRUB_DISK_DEVICE_LUKS_ID, + .iterate = grub_luks_iterate, + .open = grub_luks_open, + .close = grub_luks_close, + .read = grub_luks_read, + .write = grub_luks_write, + .next = 0 +}; + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT (luks) +{ + cmd = grub_register_extcmd ("luksmount", grub_cmd_luksmount, 0, + N_("SOURCE|-u UUID"), + N_("Mount a LUKS device."), options); + grub_disk_dev_register (&grub_luks_dev); +} + +GRUB_MOD_FINI (luks) +{ + grub_unregister_extcmd (cmd); + grub_disk_dev_unregister (&grub_luks_dev); + luks_cleanup (); +} From 5709ed126d9155ae06c284f9c8fceb11227cc73d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Apr 2011 11:17:01 +0200 Subject: [PATCH 0890/1414] small cleanup --- grub-core/disk/AFSplitter.c | 19 ++----------------- grub-core/disk/luks.c | 2 -- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/grub-core/disk/AFSplitter.c b/grub-core/disk/AFSplitter.c index 6c3dc488e..ebcc35221 100644 --- a/grub-core/disk/AFSplitter.c +++ b/grub-core/disk/AFSplitter.c @@ -20,28 +20,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst, grub_size_t blocksize, grub_size_t blocknumbers); -static void diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_uint8_t * dst, grub_size_t size); -gcry_err_code_t AF_split (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_uint8_t * dst, grub_size_t blocksize, - grub_size_t blocknumbers); - static void diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src, diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 47d10d63c..78fcabb03 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -20,11 +20,9 @@ #include #include #include -#include #include #include #include -#include #include #include From 92051871b736cde73d8755b3e29781a677ee362c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 21 Apr 2011 10:26:29 +0100 Subject: [PATCH 0891/1414] * grub-core/kern/emu/getroot.c (grub_find_root_device_from_mountinfo): Remove non-virtual-device test that was incorrectly reintroduced in r3214. Reported by: Ian Dall. Fixes Savannah bug #33133. --- ChangeLog | 7 +++++++ grub-core/kern/emu/getroot.c | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 98d3b0ea8..1142cf81d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-04-21 Colin Watson + + * grub-core/kern/emu/getroot.c + (grub_find_root_device_from_mountinfo): Remove non-virtual-device + test that was incorrectly reintroduced in r3214. + Reported by: Ian Dall. Fixes Savannah bug #33133. + 2011-04-21 Colin Watson Fix stack pointer handling in 16-bit relocator. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index f836a6625..a274f3c06 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -216,9 +216,6 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) /* Now scan visible mounts for the ones we're interested in. */ for (i = entry_len - 1; i >= 0; i--) { - if (entries[i].major != 0) - continue; /* not a virtual device */ - if (!*entries[i].device) continue; From cff5e5e58d93bdd028aba1a220bb59a7962bba52 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 21 Apr 2011 10:37:45 +0100 Subject: [PATCH 0892/1414] 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 a89c3dd3f7f587447b61cdfb4de587951217fca2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Apr 2011 11:38:51 +0200 Subject: [PATCH 0893/1414] Don't mount the same LUKS volume twice --- grub-core/disk/luks.c | 171 ++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 96 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 78fcabb03..160d1102c 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -47,7 +47,7 @@ struct grub_luks_phdr grub_uint8_t mkDigest[20]; grub_uint8_t mkDigestSalt[32]; grub_uint32_t mkDigestIterations; - grub_uint8_t uuid[40]; + char uuid[40]; struct { grub_uint32_t active; @@ -65,8 +65,7 @@ typedef enum GRUB_LUKS_MODE_ECB, GRUB_LUKS_MODE_CBC_PLAIN, GRUB_LUKS_MODE_CBC_ESSIV -} -luks_mode_t; +} luks_mode_t; struct grub_luks { @@ -77,7 +76,9 @@ struct grub_luks grub_crypto_cipher_handle_t cipher; grub_crypto_cipher_handle_t essiv_cipher; luks_mode_t mode; - int id; + unsigned long id, source_id; + enum grub_disk_dev_id source_dev_id; + char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid)]; struct grub_luks *next; }; typedef struct grub_luks *grub_luks_t; @@ -154,11 +155,9 @@ static int check_uuid, have_it; static char *uuid; static grub_err_t -grub_luks_scan_device_real (const char *name) +grub_luks_scan_device_real (const char *name, grub_disk_t source) { - grub_disk_t source; grub_err_t err; - grub_luks_t newdev; struct grub_luks_phdr header; grub_crypto_cipher_handle_t cipher = NULL, essiv_cipher = NULL; const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; @@ -174,73 +173,38 @@ grub_luks_scan_device_real (const char *name) char passphrase[MAX_PASSPHRASE] = ""; grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; - /* Try to open disk. */ - source = grub_disk_open (name); - if (!source) - return grub_errno; - /* Read the LUKS header. */ err = grub_disk_read (source, 0, 0, sizeof (header), &header); if (err) - { - grub_disk_close (source); - return err; - } + return err; /* Look for LUKS magic sequence. */ if (grub_memcmp (header.magic, LUKS_MAGIC, sizeof (header.magic)) || grub_be_to_cpu16 (header.version) != 1) - { - grub_disk_close (source); - return GRUB_ERR_NONE; - } - - if (check_uuid && grub_memcmp (header.uuid, uuid, - sizeof (header.uuid)) != 0) - return 0; - - newdev = grub_zalloc (sizeof (struct grub_luks)); - if (!newdev) - { - grub_disk_close (source); - return grub_errno; - } - - newdev->id = n; - newdev->devname = grub_xasprintf ("luks%d", n); - newdev->source = grub_strdup (name); - n++; + return GRUB_ERR_NONE; /* Make sure that strings are null terminated. */ header.cipherName[sizeof (header.cipherName) - 1] = 0; header.cipherMode[sizeof (header.cipherMode) - 1] = 0; header.hashSpec[sizeof (header.hashSpec) - 1] = 0; + header.uuid[sizeof (header.uuid) - 1] = 0; + + if (check_uuid && grub_strcmp (header.uuid, uuid) != 0) + return 0; ciph = grub_crypto_lookup_cipher_by_name (header.cipherName); if (!ciph) - { - grub_disk_close (source); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", - header.cipherName); - } + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", + header.cipherName); /* Configure the cipher used for the bulk data. */ cipher = grub_crypto_cipher_open (ciph); if (!cipher) - { - grub_disk_close (source); - grub_free (newdev); - return grub_errno; - } + return grub_errno; keysize = grub_be_to_cpu32 (header.keyBytes); if (keysize > 1024) - { - grub_disk_close (source); - grub_free (newdev); - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", - keysize); - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", keysize); /* Configure the cipher mode. */ if (grub_strncmp (header.cipherMode, "ecb", 3) == 0) @@ -258,8 +222,6 @@ grub_luks_scan_device_real (const char *name) if (!essiv_hash) { grub_crypto_cipher_close (cipher); - grub_disk_close (source); - grub_free (newdev); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", hash_str); } @@ -267,8 +229,6 @@ grub_luks_scan_device_real (const char *name) if (!cipher) { grub_crypto_cipher_close (cipher); - grub_disk_close (source); - grub_free (newdev); return grub_errno; } @@ -278,16 +238,12 @@ grub_luks_scan_device_real (const char *name) { grub_crypto_cipher_close (cipher); grub_crypto_cipher_close (essiv_cipher); - grub_disk_close (source); - grub_free (newdev); return grub_errno; } } else { grub_crypto_cipher_close (cipher); - grub_disk_close (source); - grub_free (newdev); return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", header.cipherMode); } @@ -299,8 +255,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (cipher); grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); - grub_disk_close (source); - grub_free (newdev); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", header.hashSpec); } @@ -316,8 +270,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (cipher); grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); - grub_disk_close (source); - grub_free (newdev); return grub_errno; } @@ -329,8 +281,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); } @@ -361,8 +311,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } @@ -376,8 +324,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } @@ -404,8 +350,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return err; } @@ -417,8 +361,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } @@ -431,8 +373,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } @@ -453,8 +393,6 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_disk_close (source); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } @@ -464,8 +402,6 @@ grub_luks_scan_device_real (const char *name) sizeof (header.mkDigest)) != 0) continue; - grub_disk_close (source); - grub_printf ("Slot %d opened\n", i); /* Set the master key. */ @@ -476,12 +412,9 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } - newdev->cipher = cipher; - /* Configure ESSIV if necessary. */ if (mode == GRUB_LUKS_MODE_CBC_ESSIV) { @@ -495,24 +428,33 @@ grub_luks_scan_device_real (const char *name) grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); - grub_free (newdev); return grub_crypto_gcry_error (gcry_err); } - newdev->essiv_cipher = essiv_cipher; - } - else - { - newdev->essiv_cipher = NULL; } - newdev->offset = grub_be_to_cpu32 (header.payloadOffset); - newdev->source_disk = NULL; - newdev->mode = mode; + { + grub_luks_t newdev; + newdev = grub_zalloc (sizeof (struct grub_luks)); + if (!newdev) + return grub_errno; + newdev->id = n; + newdev->devname = grub_xasprintf ("luks%d", n); + newdev->source = grub_strdup (name); + newdev->source_id = source->id; + newdev->source_dev_id = source->dev->id; + newdev->cipher = cipher; + newdev->offset = grub_be_to_cpu32 (header.payloadOffset); + newdev->source_disk = NULL; + newdev->mode = mode; + newdev->essiv_cipher = essiv_cipher; + grub_memcpy (newdev->uuid, header.uuid, sizeof (newdev->uuid)); + newdev->next = luks_list; + luks_list = newdev; + n++; + } grub_free (split_key); grub_free (hashed_key); - newdev->next = luks_list; - luks_list = newdev; have_it = 1; @@ -526,7 +468,17 @@ static int grub_luks_scan_device (const char *name) { grub_err_t err; - err = grub_luks_scan_device_real (name); + grub_disk_t source; + + /* Try to open disk. */ + source = grub_disk_open (name); + if (!source) + return grub_errno; + + err = grub_luks_scan_device_real (name, source); + + grub_disk_close (source); + if (err) grub_print_error (); return have_it && check_uuid ? 0 : 1; @@ -651,6 +603,15 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) have_it = 0; if (state[0].set) { + grub_luks_t dev; + + for (dev = luks_list; dev != NULL; dev = dev->next) + if (grub_strcmp (dev->uuid, args[0]) == 0) + { + grub_dprintf ("luks", "already mounted as %s\n", dev->devname); + return GRUB_ERR_NONE; + } + check_uuid = 1; uuid = args[0]; grub_device_iterate (&grub_luks_scan_device); @@ -659,9 +620,27 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) else { grub_err_t err; + grub_disk_t disk; + grub_luks_t dev; + check_uuid = 0; uuid = NULL; - err = grub_luks_scan_device_real (args[0]); + disk = grub_disk_open (args[0]); + if (!disk) + return grub_errno; + + for (dev = luks_list; dev != NULL; dev = dev->next) + if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id) + { + grub_dprintf ("luks", "already mounted as %s\n", dev->devname); + grub_disk_close (disk); + return GRUB_ERR_NONE; + } + + err = grub_luks_scan_device_real (args[0], disk); + + grub_disk_close (disk); + return err; } if (!have_it) From 79cde98f5d1c77697e8e3713987136cbf35a13c8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Apr 2011 11:58:06 +0200 Subject: [PATCH 0894/1414] Support luksuuid specification --- grub-core/disk/luks.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 160d1102c..3ab6b844d 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -69,7 +69,7 @@ typedef enum struct grub_luks { - char *devname, *source; + char *source; grub_uint32_t offset; grub_disk_t source_disk; int ref; @@ -438,7 +438,6 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) if (!newdev) return grub_errno; newdev->id = n; - newdev->devname = grub_xasprintf ("luks%d", n); newdev->source = grub_strdup (name); newdev->source_id = source->id; newdev->source_dev_id = source->dev->id; @@ -490,8 +489,12 @@ grub_luks_iterate (int (*hook) (const char *name)) grub_luks_t i; for (i = luks_list; i != NULL; i = i->next) - if (hook (i->devname)) - return 1; + { + char buf[30]; + grub_snprintf (buf, sizeof (buf), "luks%lu", i->id); + if (hook (buf)) + return 1; + } return GRUB_ERR_NONE; } @@ -501,11 +504,25 @@ grub_luks_open (const char *name, grub_disk_t disk) { grub_luks_t dev; - /* Search for requested device in the list of LUKS devices. */ - for (dev = luks_list; dev != NULL; dev = dev->next) - if (grub_strcmp (dev->devname, name) == 0) - break; + if (grub_memcmp (name, "luks", sizeof ("luks") - 1) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + if (grub_memcmp (name, "luksuuid/", sizeof ("luksuuid/") - 1) == 0) + { + for (dev = luks_list; dev != NULL; dev = dev->next) + if (grub_strcmp (name + sizeof ("luksuuid/") - 1, dev->uuid) == 0) + break; + } + else + { + unsigned long id = grub_strtoul (name + sizeof ("luks") - 1, 0, 0); + if (grub_errno) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + /* Search for requested device in the list of LUKS devices. */ + for (dev = luks_list; dev != NULL; dev = dev->next) + if (dev->id == id) + break; + } if (!dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); @@ -582,7 +599,6 @@ luks_cleanup (void) while (dev != NULL) { - grub_free (dev->devname); grub_free (dev->source); grub_free (dev->cipher); grub_free (dev->essiv_cipher); @@ -608,7 +624,7 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) for (dev = luks_list; dev != NULL; dev = dev->next) if (grub_strcmp (dev->uuid, args[0]) == 0) { - grub_dprintf ("luks", "already mounted as %s\n", dev->devname); + grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); return GRUB_ERR_NONE; } @@ -632,7 +648,7 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) for (dev = luks_list; dev != NULL; dev = dev->next) if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id) { - grub_dprintf ("luks", "already mounted as %s\n", dev->devname); + grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); grub_disk_close (disk); return GRUB_ERR_NONE; } From 64516e9df6de88b84e53e7b84a25bff2130c00ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Apr 2011 12:39:14 +0200 Subject: [PATCH 0895/1414] Fix couple of UUID problems --- grub-core/disk/luks.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 3ab6b844d..bc53e0a2b 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -78,7 +78,7 @@ struct grub_luks luks_mode_t mode; unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; - char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid)]; + char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; struct grub_luks *next; }; typedef struct grub_luks *grub_luks_t; @@ -152,7 +152,7 @@ luks_decrypt (grub_crypto_cipher_handle_t cipher, luks_mode_t mode, } static int check_uuid, have_it; -static char *uuid; +static char *search_uuid; static grub_err_t grub_luks_scan_device_real (const char *name, grub_disk_t source) @@ -172,6 +172,8 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) const struct gcry_cipher_spec *ciph; char passphrase[MAX_PASSPHRASE] = ""; grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; + char uuid[sizeof (header.uuid) + 1]; + char *iptr, *optr; /* Read the LUKS header. */ err = grub_disk_read (source, 0, 0, sizeof (header), &header); @@ -189,8 +191,20 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) header.hashSpec[sizeof (header.hashSpec) - 1] = 0; header.uuid[sizeof (header.uuid) - 1] = 0; - if (check_uuid && grub_strcmp (header.uuid, uuid) != 0) - return 0; + optr = uuid; + for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)]; + iptr++) + { + if (*iptr != '-') + *optr++ = *iptr; + } + *optr = 0; + + if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) + { + grub_dprintf ("luks", "%s != %s", uuid, search_uuid); + return 0; + } ciph = grub_crypto_lookup_cipher_by_name (header.cipherName); if (!ciph) @@ -274,7 +288,7 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) } /* Get the passphrase from the user. */ - grub_printf ("Enter passphrase: "); + grub_printf ("Enter passphrase for %s (%s): ", name, uuid); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) { grub_crypto_cipher_close (cipher); @@ -446,7 +460,7 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) newdev->source_disk = NULL; newdev->mode = mode; newdev->essiv_cipher = essiv_cipher; - grub_memcpy (newdev->uuid, header.uuid, sizeof (newdev->uuid)); + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); newdev->next = luks_list; luks_list = newdev; n++; @@ -510,7 +524,7 @@ grub_luks_open (const char *name, grub_disk_t disk) if (grub_memcmp (name, "luksuuid/", sizeof ("luksuuid/") - 1) == 0) { for (dev = luks_list; dev != NULL; dev = dev->next) - if (grub_strcmp (name + sizeof ("luksuuid/") - 1, dev->uuid) == 0) + if (grub_strcasecmp (name + sizeof ("luksuuid/") - 1, dev->uuid) == 0) break; } else @@ -622,16 +636,20 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) grub_luks_t dev; for (dev = luks_list; dev != NULL; dev = dev->next) - if (grub_strcmp (dev->uuid, args[0]) == 0) + if (grub_strcasecmp (dev->uuid, args[0]) == 0) { grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); return GRUB_ERR_NONE; } check_uuid = 1; - uuid = args[0]; + search_uuid = args[0]; grub_device_iterate (&grub_luks_scan_device); - uuid = NULL; + search_uuid = NULL; + + if (!have_it) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); + return GRUB_ERR_NONE; } else { @@ -640,7 +658,7 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) grub_luks_t dev; check_uuid = 0; - uuid = NULL; + search_uuid = NULL; disk = grub_disk_open (args[0]); if (!disk) return grub_errno; @@ -659,9 +677,6 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) return err; } - if (!have_it) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); - return 0; } static struct grub_disk_dev grub_luks_dev = { From a10e7a5a8918bea6e2632055129fa9b516fe965a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Apr 2011 12:39:31 +0200 Subject: [PATCH 0896/1414] Support grub-probe -t drive --- grub-core/kern/emu/getroot.c | 75 +++++++++++++++++++++++++++--------- include/grub/emu/getroot.h | 1 + 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index f47203cfc..40cbc4998 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -640,11 +640,11 @@ grub_guess_root_device (const char *dir) return os_dev; } -static int -grub_util_is_lvm (const char *os_dev) +static char * +get_dm_uuid (const char *os_dev) { if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) - return 0; + return NULL; #ifdef HAVE_DEVICE_MAPPER { @@ -652,17 +652,18 @@ grub_util_is_lvm (const char *os_dev) uint32_t maj, min; struct dm_tree_node *node = NULL; const char *node_uuid; + char *ret; struct stat st; if (stat (os_dev, &st) < 0) - return 0; + return NULL; tree = dm_tree_create (); if (! tree) { grub_printf ("Failed to create tree\n"); grub_dprintf ("hostdisk", "dm_tree_create failed\n"); - return 0; + return NULL; } maj = major (st.st_rdev); @@ -672,7 +673,7 @@ grub_util_is_lvm (const char *os_dev) { grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); dm_tree_free (tree); - return 0; + return NULL; } node = dm_tree_find_node (tree, maj, min); @@ -680,39 +681,64 @@ grub_util_is_lvm (const char *os_dev) { grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); dm_tree_free (tree); - return 0; + return NULL; } 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; + return NULL; } + + ret = grub_strdup (node_uuid); dm_tree_free (tree); - return 1; + return ret; } #else - return 1; + return NULL; #endif /* HAVE_DEVICE_MAPPER */ } +static enum grub_dev_abstraction_types +grub_util_get_dm_abstraction (const char *os_dev) +{ + char *uuid; + uuid = get_dm_uuid (os_dev); + + if (uuid == NULL) + return GRUB_DEV_ABSTRACTION_NONE; + + if (strncmp (uuid, "LVM-", 4) == 0) + { + grub_free (uuid); + return GRUB_DEV_ABSTRACTION_LVM; + } + if (strncmp (uuid, "CRYPT-LUKS1-", 4) == 0) + { + grub_free (uuid); + return GRUB_DEV_ABSTRACTION_LUKS; + } + + grub_free (uuid); + return GRUB_DEV_ABSTRACTION_NONE; +} + int grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { #ifdef __linux__ + enum grub_dev_abstraction_types ret; + /* User explicitly claims that this drive is visible by BIOS. */ if (grub_util_biosdisk_is_present (os_dev)) return GRUB_DEV_ABSTRACTION_NONE; - /* Check for LVM. */ - if (grub_util_is_lvm (os_dev)) - return GRUB_DEV_ABSTRACTION_LVM; + /* Check for LVM and LUKS. */ + ret = grub_util_get_dm_abstraction (os_dev); + + if (ret != GRUB_DEV_ABSTRACTION_NONE) + return ret; /* Check for RAID. */ if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev)) @@ -830,6 +856,19 @@ grub_util_get_grub_dev (const char *os_dev) break; + case GRUB_DEV_ABSTRACTION_LUKS: + { + char *uuid, *dash; + uuid = get_dm_uuid (os_dev); + dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-'); + if (dash) + *dash = 0; + grub_dev = grub_xasprintf ("luksuuid/%s", + uuid + sizeof ("CRYPT-LUKS1-") - 1); + grub_free (uuid); + } + break; + case GRUB_DEV_ABSTRACTION_RAID: if (os_dev[7] == '_' && os_dev[8] == 'd') diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 581ea8056..14df583b3 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -25,6 +25,7 @@ enum grub_dev_abstraction_types { GRUB_DEV_ABSTRACTION_NONE, GRUB_DEV_ABSTRACTION_LVM, GRUB_DEV_ABSTRACTION_RAID, + GRUB_DEV_ABSTRACTION_LUKS, }; char *grub_find_device (const char *dir, dev_t dev); From c85140b3b79fb91fb7d174042139adc9b5028a23 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 21 Apr 2011 15:17:48 +0100 Subject: [PATCH 0897/1414] Add "SEE ALSO" sections to most man pages. Fixes Debian bug #551428. * docs/man/grub-editenv.h2m (SEE ALSO): New section. * docs/man/grub-emu.h2m (SEE ALSO): Likewise. * docs/man/grub-fstest.h2m (SEE ALSO): Likewise. * docs/man/grub-install.h2m (SEE ALSO): Likewise. * docs/man/grub-macho2img.h2m (SEE ALSO): Likewise. * docs/man/grub-menulst2cfg.h2m (SEE ALSO): Likewise. * docs/man/grub-mkconfig.h2m (SEE ALSO): Likewise. * docs/man/grub-mkdevicemap.h2m (SEE ALSO): Likewise. * docs/man/grub-mkfont.h2m (SEE ALSO): Likewise. * docs/man/grub-mkimage.h2m (SEE ALSO): Likewise. * docs/man/grub-mklayout.h2m (SEE ALSO): Likewise. * docs/man/grub-mknetdir.h2m (SEE ALSO): Likewise. * docs/man/grub-mkpasswd-pbkdf2.h2m (SEE ALSO): Likewise. * docs/man/grub-mkrelpath.h2m (SEE ALSO): Likewise. * docs/man/grub-mkrescue.h2m (SEE ALSO): Likewise. * docs/man/grub-ofpathname.h2m (SEE ALSO): Likewise. * docs/man/grub-pe2elf.h2m (SEE ALSO): Likewise. * docs/man/grub-probe.h2m (SEE ALSO): Likewise. * docs/man/grub-reboot.h2m (SEE ALSO): Likewise. * docs/man/grub-script-check.h2m (SEE ALSO): Likewise. * docs/man/grub-set-default.h2m (SEE ALSO): Likewise. * docs/man/grub-setup.h2m (SEE ALSO): Likewise. --- ChangeLog | 28 ++++++++++++++++++++++++++++ docs/man/grub-editenv.h2m | 3 +++ docs/man/grub-emu.h2m | 4 ++++ docs/man/grub-fstest.h2m | 2 ++ docs/man/grub-install.h2m | 5 +++++ docs/man/grub-macho2img.h2m | 2 ++ docs/man/grub-menulst2cfg.h2m | 3 ++- docs/man/grub-mkconfig.h2m | 2 ++ docs/man/grub-mkdevicemap.h2m | 2 ++ docs/man/grub-mkfont.h2m | 2 ++ docs/man/grub-mkimage.h2m | 5 +++++ docs/man/grub-mklayout.h2m | 2 ++ docs/man/grub-mknetdir.h2m | 2 ++ docs/man/grub-mkpasswd-pbkdf2.h2m | 2 ++ docs/man/grub-mkrelpath.h2m | 2 ++ docs/man/grub-mkrescue.h2m | 2 ++ docs/man/grub-ofpathname.h2m | 2 ++ docs/man/grub-pe2elf.h2m | 2 ++ docs/man/grub-probe.h2m | 2 ++ docs/man/grub-reboot.h2m | 3 +++ docs/man/grub-script-check.h2m | 2 ++ docs/man/grub-set-default.h2m | 3 +++ docs/man/grub-setup.h2m | 4 ++++ 23 files changed, 85 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1142cf81d..3b98caba3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2011-04-21 Colin Watson + + Add "SEE ALSO" sections to most man pages. Fixes Debian bug + #551428. + + * docs/man/grub-editenv.h2m (SEE ALSO): New section. + * docs/man/grub-emu.h2m (SEE ALSO): Likewise. + * docs/man/grub-fstest.h2m (SEE ALSO): Likewise. + * docs/man/grub-install.h2m (SEE ALSO): Likewise. + * docs/man/grub-macho2img.h2m (SEE ALSO): Likewise. + * docs/man/grub-menulst2cfg.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkconfig.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkdevicemap.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkfont.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkimage.h2m (SEE ALSO): Likewise. + * docs/man/grub-mklayout.h2m (SEE ALSO): Likewise. + * docs/man/grub-mknetdir.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkpasswd-pbkdf2.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkrelpath.h2m (SEE ALSO): Likewise. + * docs/man/grub-mkrescue.h2m (SEE ALSO): Likewise. + * docs/man/grub-ofpathname.h2m (SEE ALSO): Likewise. + * docs/man/grub-pe2elf.h2m (SEE ALSO): Likewise. + * docs/man/grub-probe.h2m (SEE ALSO): Likewise. + * docs/man/grub-reboot.h2m (SEE ALSO): Likewise. + * docs/man/grub-script-check.h2m (SEE ALSO): Likewise. + * docs/man/grub-set-default.h2m (SEE ALSO): Likewise. + * docs/man/grub-setup.h2m (SEE ALSO): Likewise. + 2011-04-21 Colin Watson * grub-core/kern/emu/getroot.c diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m index efbd79070..3859d3d4c 100644 --- a/docs/man/grub-editenv.h2m +++ b/docs/man/grub-editenv.h2m @@ -1,2 +1,5 @@ [NAME] grub-editenv \- edit GRUB environment block +[SEE ALSO] +.BR grub-reboot (8), +.BR grub-set-default (8) diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m index 09a1f88c1..ef1c00065 100644 --- a/docs/man/grub-emu.h2m +++ b/docs/man/grub-emu.h2m @@ -1,2 +1,6 @@ [NAME] grub-emu \- GRUB emulator +[SEE ALSO] +If you are trying to install GRUB, then you should use +.BR grub-install (8) +rather than this program. diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m index be39429b5..9676b159a 100644 --- a/docs/man/grub-fstest.h2m +++ b/docs/man/grub-fstest.h2m @@ -1,2 +1,4 @@ [NAME] grub-fstest \- debug tool for GRUB filesystem drivers +[SEE ALSO] +.BR grub-probe (8) diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m index 65252155c..2de371a3f 100644 --- a/docs/man/grub-install.h2m +++ b/docs/man/grub-install.h2m @@ -1,2 +1,7 @@ [NAME] grub-install \- install GRUB to a device +[SEE ALSO] +.BR grub-mkconfig (8), +.BR grub-mkimage (1), +.BR grub-setup (8), +.BR grub-mkrescue (1) diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m index 412bf926a..d79aaeed8 100644 --- a/docs/man/grub-macho2img.h2m +++ b/docs/man/grub-macho2img.h2m @@ -1,2 +1,4 @@ [NAME] grub-macho2img \- convert Mach-O to raw image +[SEE ALSO] +.BR grub-mkimage (1) diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m index 0c0570f27..c2e0055ed 100644 --- a/docs/man/grub-menulst2cfg.h2m +++ b/docs/man/grub-menulst2cfg.h2m @@ -1,3 +1,4 @@ [NAME] grub-menulst2cfg \- transform legacy menu.lst into grub.cfg - +[SEE ALSO] +.BR grub-mkconfig (8) diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m index b0d33ec61..9b42f8130 100644 --- a/docs/man/grub-mkconfig.h2m +++ b/docs/man/grub-mkconfig.h2m @@ -1,2 +1,4 @@ [NAME] grub-mkconfig \- generate a GRUB configuration file +[SEE ALSO] +.BR grub-install (8) diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m index 8ab34ac86..3ef8e9712 100644 --- a/docs/man/grub-mkdevicemap.h2m +++ b/docs/man/grub-mkdevicemap.h2m @@ -1,2 +1,4 @@ [NAME] grub-mkdevicemap \- generate a GRUB device map file automatically +[SEE ALSO] +.BR grub-install (8) diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m index d8580186f..d46fe600e 100644 --- a/docs/man/grub-mkfont.h2m +++ b/docs/man/grub-mkfont.h2m @@ -1,2 +1,4 @@ [NAME] grub-mkfont \- make GRUB font files +[SEE ALSO] +.BR grub-mkconfig (8) diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m index 71f270940..ca08b0c5c 100644 --- a/docs/man/grub-mkimage.h2m +++ b/docs/man/grub-mkimage.h2m @@ -1,2 +1,7 @@ [NAME] grub-mkimage \- make a bootable image of GRUB +[SEE ALSO] +.BR grub-install (8), +.BR grub-setup (8), +.BR grub-mkrescue (1), +.BR grub-mknetdir (8) diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m index e0ae9dedb..cda6f3676 100644 --- a/docs/man/grub-mklayout.h2m +++ b/docs/man/grub-mklayout.h2m @@ -1,2 +1,4 @@ [NAME] grub-mklayout \- generate a GRUB keyboard layout file +[SEE ALSO] +.BR grub-mkconfig (8) diff --git a/docs/man/grub-mknetdir.h2m b/docs/man/grub-mknetdir.h2m index 26defe876..a2ef13ec1 100644 --- a/docs/man/grub-mknetdir.h2m +++ b/docs/man/grub-mknetdir.h2m @@ -1,2 +1,4 @@ [NAME] grub-mknetdir \- prepare a GRUB netboot directory. +[SEE ALSO] +.BR grub-mkimage (1) diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m index 5b2b2ef7f..4d202f3da 100644 --- a/docs/man/grub-mkpasswd-pbkdf2.h2m +++ b/docs/man/grub-mkpasswd-pbkdf2.h2m @@ -1,2 +1,4 @@ [NAME] grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB +[SEE ALSO] +.BR grub-mkconfig (8) diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m index ccc0880fa..d01f3961e 100644 --- a/docs/man/grub-mkrelpath.h2m +++ b/docs/man/grub-mkrelpath.h2m @@ -1,2 +1,4 @@ [NAME] grub-mkrelpath \- make a system path relative to its root +[SEE ALSO] +.BR grub-probe (8) diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m index 5e92e0d99..a427f02e3 100644 --- a/docs/man/grub-mkrescue.h2m +++ b/docs/man/grub-mkrescue.h2m @@ -1,2 +1,4 @@ [NAME] grub-mkrescue \- make a GRUB rescue image +[SEE ALSO] +.BR grub-mkimage (1) diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m index f07158cb3..74b43eea0 100644 --- a/docs/man/grub-ofpathname.h2m +++ b/docs/man/grub-ofpathname.h2m @@ -1,2 +1,4 @@ [NAME] grub-ofpathname \- find OpenBOOT path for a device +[SEE ALSO] +.BR grub-probe (8) diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m index 3fdb88b43..7ca29bd70 100644 --- a/docs/man/grub-pe2elf.h2m +++ b/docs/man/grub-pe2elf.h2m @@ -1,2 +1,4 @@ [NAME] grub-pe2elf \- convert PE image to ELF +[SEE ALSO] +.BR grub-mkimage (1) diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m index 817ba8ef6..6e1ffdcf9 100644 --- a/docs/man/grub-probe.h2m +++ b/docs/man/grub-probe.h2m @@ -1,2 +1,4 @@ [NAME] grub-probe \- probe device information for GRUB +[SEE ALSO] +.BR grub-fstest (1) diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m index 957e4b797..e4acace65 100644 --- a/docs/man/grub-reboot.h2m +++ b/docs/man/grub-reboot.h2m @@ -1,2 +1,5 @@ [NAME] grub-reboot \- set the default boot entry for GRUB, for the next boot only +[SEE ALSO] +.BR grub-set-default (8), +.BR grub-editenv (1) diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m index 39c0a3ef6..365368267 100644 --- a/docs/man/grub-script-check.h2m +++ b/docs/man/grub-script-check.h2m @@ -1,2 +1,4 @@ [NAME] grub-script-check \- check grub.cfg for syntax errors +[SEE ALSO] +.BR grub-mkconfig (8) diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m index dd0793cfd..7945001c1 100644 --- a/docs/man/grub-set-default.h2m +++ b/docs/man/grub-set-default.h2m @@ -1,2 +1,5 @@ [NAME] grub-set-default \- set the saved default boot entry for GRUB +[SEE ALSO] +.BR grub-reboot (8), +.BR grub-editenv (1) diff --git a/docs/man/grub-setup.h2m b/docs/man/grub-setup.h2m index e70e465a4..eebe3ef38 100644 --- a/docs/man/grub-setup.h2m +++ b/docs/man/grub-setup.h2m @@ -1,2 +1,6 @@ [NAME] grub-setup \- set up a device to boot using GRUB +[SEE ALSO] +.BR grub-install (8), +.BR grub-mkimage (1), +.BR grub-mkrescue (1) From e91dba5b13c564a5fbfc2b9d070ad9e87cb1bae5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 21 Apr 2011 15:47:58 +0100 Subject: [PATCH 0898/1414] * po/README: Add instructions for creating po/LINGUAS. --- ChangeLog | 4 ++++ po/README | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3b98caba3..cd791308c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-04-21 Colin Watson + + * po/README: Add instructions for creating po/LINGUAS. + 2011-04-21 Colin Watson Add "SEE ALSO" sections to most man pages. Fixes Debian bug diff --git a/po/README b/po/README index 801599583..5541f4229 100644 --- a/po/README +++ b/po/README @@ -8,6 +8,10 @@ that will hopefully clarify the situation. rsync -Lrtvz translationproject.org::tp/latest/grub/ po + Then create a po/LINGUAS file listing all the language codes: + + (cd po && ls *.po | cut -d. -f1 | xargs) >po/LINGUAS + GRUB's build system will automatically detect those and include them in your install. From 24b905a11c90e47cb271397bd507e0496fe130e7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 00:09:07 +0200 Subject: [PATCH 0899/1414] Lazy LVM and RAID assembly --- grub-core/disk/ata.c | 9 +- grub-core/disk/host.c | 9 +- grub-core/disk/i386/pc/biosdisk.c | 56 ++++++---- grub-core/disk/loopback.c | 8 +- grub-core/disk/lvm.c | 139 ++++++++++++++++++++--- grub-core/disk/memdisk.c | 9 +- grub-core/disk/raid.c | 178 ++++++++++++++++++++++-------- grub-core/disk/scsi.c | 9 +- grub-core/fs/i386/pc/pxe.c | 9 +- grub-core/kern/disk.c | 31 ++++-- grub-core/kern/emu/hostdisk.c | 6 +- include/grub/disk.h | 15 ++- include/grub/raid.h | 1 + 13 files changed, 365 insertions(+), 114 deletions(-) diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 7f261560d..3a43a8cae 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -666,10 +666,14 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, static int -grub_ata_iterate (int (*hook) (const char *name)) +grub_ata_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_ata_device *dev; + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (dev = grub_ata_devices; dev; dev = dev->next) { char devname[10]; @@ -696,7 +700,8 @@ grub_ata_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_ata_open (const char *name, grub_disk_t disk) +grub_ata_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { struct grub_ata_device *dev; grub_err_t err; diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c index c51966293..5376cc6ce 100644 --- a/grub-core/disk/host.c +++ b/grub-core/disk/host.c @@ -27,15 +27,20 @@ int grub_disk_host_i_want_a_reference; static int -grub_host_iterate (int (*hook) (const char *name)) +grub_host_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + if (hook ("host")) return 1; return 0; } static grub_err_t -grub_host_open (const char *name, grub_disk_t disk) +grub_host_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { if (grub_strcmp (name, "host")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk"); diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 1d47dc727..e75ab184b 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -284,42 +284,52 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) } static int -grub_biosdisk_iterate (int (*hook) (const char *name)) +grub_biosdisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull __attribute__ ((unused))) { - int drive; int num_floppies; + int drive; /* For hard disks, attempt to read the MBR. */ - for (drive = 0x80; drive < 0x90; drive++) + switch (pull) { - if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, - GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) + case GRUB_DISK_PULL_NONE: + for (drive = 0x80; drive < 0x90; drive++) { - grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); - break; + if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, + GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) + { + grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); + break; + } + + if (grub_biosdisk_call_hook (hook, drive)) + return 1; + } + return 0; + + case GRUB_DISK_PULL_REMOVABLE: + if (cd_drive) + { + if (grub_biosdisk_call_hook (hook, cd_drive)) + return 1; } - if (grub_biosdisk_call_hook (hook, drive)) - return 1; + /* For floppy disks, we can get the number safely. */ + num_floppies = grub_biosdisk_get_num_floppies (); + for (drive = 0; drive < num_floppies; drive++) + if (grub_biosdisk_call_hook (hook, drive)) + return 1; + return 0; + default: + return 0; } - - if (cd_drive) - { - if (grub_biosdisk_call_hook (hook, cd_drive)) - return 1; - } - - /* For floppy disks, we can get the number safely. */ - num_floppies = grub_biosdisk_get_num_floppies (); - for (drive = 0; drive < num_floppies; drive++) - if (grub_biosdisk_call_hook (hook, drive)) - return 1; - return 0; } static grub_err_t -grub_biosdisk_open (const char *name, grub_disk_t disk) +grub_biosdisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { grub_uint64_t total_sectors = 0; int drive; diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index d50f353b1..21345af57 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -133,9 +133,12 @@ fail: static int -grub_loopback_iterate (int (*hook) (const char *name)) +grub_loopback_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_loopback *d; + if (pull != GRUB_DISK_PULL_NONE) + return 0; for (d = loopback_list; d; d = d->next) { if (hook (d->devname)) @@ -145,7 +148,8 @@ grub_loopback_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_loopback_open (const char *name, grub_disk_t disk) +grub_loopback_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { struct grub_loopback *dev; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 206e3e220..72f493540 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -32,7 +32,12 @@ GRUB_MOD_LICENSE ("GPLv3+"); static struct grub_lvm_vg *vg_list; static int lv_count; +static int scan_depth = 0; +static int is_lv_readable (struct grub_lvm_lv *lv); + +static int +grub_lvm_scan_device (const char *name); /* Go the string STR and return the number after STR. *P will point at the number. In case STR is not found, *P will be NULL and the @@ -96,16 +101,39 @@ grub_lvm_check_flag (char *p, char *str, char *flag) } static int -grub_lvm_iterate (int (*hook) (const char *name)) +grub_lvm_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_lvm_vg *vg; + unsigned old_count = 0; + if (pull == GRUB_DISK_PULL_RESCAN && scan_depth) + return 0; + + if (pull == GRUB_DISK_PULL_RESCAN) + { + old_count = lv_count; + if (!scan_depth) + { + scan_depth++; + grub_device_iterate (&grub_lvm_scan_device); + scan_depth--; + } + } + if (pull != GRUB_DISK_PULL_RESCAN && pull != GRUB_DISK_PULL_NONE) + return GRUB_ERR_NONE; for (vg = vg_list; vg; vg = vg->next) { struct grub_lvm_lv *lv; if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (lv->visible && hook (lv->name)) - return 1; + if (lv->visible && lv->number >= old_count) + { + char lvname[sizeof ("lvm/") + grub_strlen (lv->name)]; + grub_memcpy (lvname, "lvm/", sizeof ("lvm/") - 1); + grub_strcpy (lvname + sizeof ("lvm/") - 1, lv->name); + if (hook (lvname)) + return 1; + } } return 0; @@ -135,8 +163,8 @@ grub_lvm_memberlist (grub_disk_t disk) } #endif -static grub_err_t -grub_lvm_open (const char *name, grub_disk_t disk) +static struct grub_lvm_lv * +find_lv (const char *name) { struct grub_lvm_vg *vg; struct grub_lvm_lv *lv = NULL; @@ -144,11 +172,43 @@ grub_lvm_open (const char *name, grub_disk_t disk) { if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (! grub_strcmp (lv->name, name)) - break; + if (! grub_strcmp (lv->name, name) && is_lv_readable (lv)) + return lv; + } + return NULL; +} - if (lv) - break; +static const char *scan_for = NULL; + +static grub_err_t +grub_lvm_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull) +{ + struct grub_lvm_lv *lv = NULL; + int explicit = 0; + + if (grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0) + { + name += sizeof ("lvm/") - 1; + explicit = 1; + } + + lv = find_lv (name); + + if (! lv && !scan_depth && + pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) + { + scan_for = name; + scan_depth++; + grub_device_iterate (&grub_lvm_scan_device); + scan_depth--; + scan_for = NULL; + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + lv = find_lv (name); } if (! lv) @@ -285,6 +345,49 @@ read_lv (struct grub_lvm_lv *lv, grub_disk_addr_t sector, return grub_error (GRUB_ERR_IO, "unknown LVM segment"); } +static grub_err_t +is_node_readable (const struct grub_lvm_node *node) +{ + /* Check whether we actually know the physical volume we want to + read from. */ + if (node->pv) + return !!(node->pv->disk); + if (node->lv) + return is_lv_readable (node->lv); + return 0; +} + +static int +is_lv_readable (struct grub_lvm_lv *lv) +{ + unsigned int i, j; + + if (!lv) + return 0; + + /* Find the right segment. */ + for (i = 0; i < lv->segment_count; i++) + switch (lv->segments[i].type) + { + case GRUB_LVM_STRIPED: + for (j = 0; j < lv->segments[i].node_count; j++) + if (!is_node_readable (lv->segments[i].nodes + j)) + return 0; + break; + case GRUB_LVM_MIRROR: + for (j = 0; j < lv->segments[i].node_count; j++) + if (is_node_readable (lv->segments[i].nodes + j)) + break; + if (j == lv->segments[i].node_count) + return 0; + default: + return 0; + } + + return 1; +} + + static grub_err_t grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) @@ -332,6 +435,15 @@ grub_lvm_scan_device (const char *name) return 0; } + for (vg = vg_list; vg; vg = vg->next) + for (pv = vg->pvs; pv; pv = pv->next) + if (pv->disk && pv->disk->id == disk->id + && pv->disk->dev->id == disk->dev->id) + { + grub_disk_close (disk); + return 0; + } + /* Search for label. */ for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++) { @@ -857,6 +969,8 @@ grub_lvm_scan_device (const char *name) if (grub_errno == GRUB_ERR_OUT_OF_RANGE) grub_errno = GRUB_ERR_NONE; grub_print_error (); + if (scan_for && find_lv (scan_for)) + return 1; return 0; } @@ -878,13 +992,6 @@ static struct grub_disk_dev grub_lvm_dev = GRUB_MOD_INIT(lvm) { - grub_device_iterate (&grub_lvm_scan_device); - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - grub_disk_dev_register (&grub_lvm_dev); } diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index 114ac0d9e..775234055 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -30,13 +30,18 @@ static char *memdisk_addr; static grub_off_t memdisk_size = 0; static int -grub_memdisk_iterate (int (*hook) (const char *name)) +grub_memdisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + return hook ("memdisk"); } static grub_err_t -grub_memdisk_open (const char *name, grub_disk_t disk) +grub_memdisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { if (grub_strcmp (name, "memdisk")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk"); diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 946e6d2c2..78453ac88 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -33,6 +33,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); static struct grub_raid_array *array_list; grub_raid5_recover_func_t grub_raid5_recover_func; grub_raid6_recover_func_t grub_raid6_recover_func; +static grub_raid_t grub_raid_list; +static int inscnt = 0; + +static struct grub_raid_array * +find_array (const char *name); static char @@ -78,14 +83,98 @@ grub_is_array_readable (struct grub_raid_array *array) return 0; } +static grub_err_t +insert_array (grub_disk_t disk, struct grub_raid_array *new_array, + grub_disk_addr_t start_sector, const char *scanner_name, + grub_raid_t raid __attribute__ ((unused))); + +static int scan_depth = 0; + +static void +scan_devices (const char *arname) +{ + grub_raid_t raid; + + auto int hook (const char *name); + int hook (const char *name) + { + grub_disk_t disk; + struct grub_raid_array array; + struct grub_raid_array *arr; + grub_disk_addr_t start_sector; + + grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n", + raid->name, name); +#ifdef GRUB_UTIL + grub_util_info ("Scanning for %s RAID devices on disk %s", + raid->name, name); +#endif + + disk = grub_disk_open (name); + if (!disk) + return 0; + + for (arr = array_list; arr != NULL; arr = arr->next) + { + struct grub_raid_member *m; + for (m = arr->members; m < arr->members + arr->nr_devs; m++) + if (m->device && m->device->id == disk->id + && m->device->dev->id == m->device->dev->id) + { + grub_disk_close (disk); + return 0; + } + } + + if ((disk->total_sectors != GRUB_ULONG_MAX) && + (! raid->detect (disk, &array, &start_sector)) && + (! insert_array (disk, &array, start_sector, raid->name, + raid))) + return 0; + + /* This error usually means it's not raid, no need to display + it. */ + if (grub_errno != GRUB_ERR_OUT_OF_RANGE) + grub_print_error (); + + grub_errno = GRUB_ERR_NONE; + + grub_disk_close (disk); + + if (arname && find_array (arname)) + return 1; + + return 0; + } + + if (scan_depth) + return; + + scan_depth++; + for (raid = grub_raid_list; raid; raid = raid->next) + grub_device_iterate (&hook); + scan_depth--; +} + static int -grub_raid_iterate (int (*hook) (const char *name)) +grub_raid_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { struct grub_raid_array *array; + int islcnt = 0; + + if (pull == GRUB_DISK_PULL_RESCAN) + { + islcnt = inscnt; + scan_devices (NULL); + } + + if (pull != GRUB_DISK_PULL_NONE && pull != GRUB_DISK_PULL_RESCAN) + return 0; for (array = array_list; array != NULL; array = array->next) { - if (grub_is_array_readable (array)) + if (grub_is_array_readable (array) && array->became_readable_at >= islcnt) if (hook (array->name)) return 1; } @@ -134,11 +223,10 @@ ascii2hex (char c) return 0; } -static grub_err_t -grub_raid_open (const char *name, grub_disk_t disk) +static struct grub_raid_array * +find_array (const char *name) { struct grub_raid_array *array; - unsigned n; if (grub_memcmp (name, "mduuid/", sizeof ("mduuid/") - 1) == 0) { @@ -155,7 +243,7 @@ grub_raid_open (const char *name, grub_disk_t disk) if (uuid_len == (unsigned) array->uuid_len && grub_memcmp (uuidbin, array->uuid, uuid_len) == 0) if (grub_is_array_readable (array)) - break; + return array; } } else @@ -163,8 +251,33 @@ grub_raid_open (const char *name, grub_disk_t disk) { if (!grub_strcmp (array->name, name)) if (grub_is_array_readable (array)) - break; + return array; } + return NULL; +} + +static grub_err_t +grub_raid_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull) +{ + struct grub_raid_array *array; + unsigned n; + + if (grub_memcmp (name, "md", sizeof ("md") - 1) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", + name); + + array = find_array (name); + + if (! array && pull == GRUB_DISK_PULL_RESCAN) + { + scan_devices (name); + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + array = find_array (name); + } if (!array) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", @@ -690,15 +803,19 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } /* Add the device to the array. */ - array->members[new_array->index].device = disk; - array->members[new_array->index].start_sector = start_sector; - array->nr_devs++; + { + int was_readable = grub_is_array_readable (array); + + array->members[new_array->index].device = disk; + array->members[new_array->index].start_sector = start_sector; + array->nr_devs++; + if (!was_readable && grub_is_array_readable (array)) + array->became_readable_at = inscnt++; + } return 0; } -static grub_raid_t grub_raid_list; - static void free_array (void) { @@ -729,45 +846,8 @@ free_array (void) void grub_raid_register (grub_raid_t raid) { - auto int hook (const char *name); - int hook (const char *name) - { - grub_disk_t disk; - struct grub_raid_array array; - grub_disk_addr_t start_sector; - - grub_dprintf ("raid", "Scanning for %s RAID devices on disk %s\n", - grub_raid_list->name, name); -#ifdef GRUB_UTIL - grub_util_info ("Scanning for %s RAID devices on disk %s", - grub_raid_list->name, name); -#endif - - disk = grub_disk_open (name); - if (!disk) - return 0; - - if ((disk->total_sectors != GRUB_ULONG_MAX) && - (! grub_raid_list->detect (disk, &array, &start_sector)) && - (! insert_array (disk, &array, start_sector, grub_raid_list->name, - grub_raid_list))) - return 0; - - /* This error usually means it's not raid, no need to display - it. */ - if (grub_errno != GRUB_ERR_OUT_OF_RANGE) - grub_print_error (); - - grub_errno = GRUB_ERR_NONE; - - grub_disk_close (disk); - - return 0; - } - raid->next = grub_raid_list; grub_raid_list = raid; - grub_device_iterate (&hook); } void diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 25f0e3aea..e85036860 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -316,7 +316,8 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, static int -grub_scsi_iterate (int (*hook) (const char *name)) +grub_scsi_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { grub_scsi_dev_t p; @@ -356,6 +357,9 @@ grub_scsi_iterate (int (*hook) (const char *name)) return 0; } + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (p = grub_scsi_dev_list; p; p = p->next) if (p->iterate && (p->iterate) (scsi_iterate)) return 1; @@ -364,7 +368,8 @@ grub_scsi_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_scsi_open (const char *name, grub_disk_t disk) +grub_scsi_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { grub_scsi_dev_t p; grub_scsi_t scsi; diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index d6dc2c22d..929f44587 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -104,8 +104,12 @@ grub_pxe_scan (void) } static int -grub_pxe_iterate (int (*hook) (const char *name)) +grub_pxe_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + if (hook ("pxe")) return 1; return 0; @@ -139,7 +143,8 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) } static grub_err_t -grub_pxe_open (const char *name, grub_disk_t disk) +grub_pxe_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { struct grub_pxe_disk_data *data; diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 807ee4277..9c2c70b80 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -207,10 +207,16 @@ int grub_disk_dev_iterate (int (*hook) (const char *name)) { grub_disk_dev_t p; + grub_disk_pull_t pull; - for (p = grub_disk_dev_list; p; p = p->next) - if (p->iterate && (p->iterate) (hook)) - return 1; + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + { + if (pull == GRUB_DISK_PULL_RESCAN_UNTYPED) + continue; + for (p = grub_disk_dev_list; p; p = p->next) + if (p->iterate && (p->iterate) (hook, pull)) + return 1; + } return 0; } @@ -241,6 +247,7 @@ grub_disk_open (const char *name) grub_disk_dev_t dev; char *raw = (char *) name; grub_uint64_t current_time; + grub_disk_pull_t pull; grub_dprintf ("disk", "Opening `%s'...\n", name); @@ -266,15 +273,19 @@ grub_disk_open (const char *name) if (! disk->name) goto fail; - - for (dev = grub_disk_dev_list; dev; dev = dev->next) + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) { - if ((dev->open) (raw, disk) == GRUB_ERR_NONE) + for (dev = grub_disk_dev_list; dev; dev = dev->next) + { + if ((dev->open) (raw, disk, pull) == GRUB_ERR_NONE) + break; + else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + grub_errno = GRUB_ERR_NONE; + else + goto fail; + } + if (dev) break; - else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - grub_errno = GRUB_ERR_NONE; - else - goto fail; } if (! dev) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 63bca37ee..3ee6174d0 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -212,7 +212,8 @@ find_free_slot (void) } static int -grub_util_biosdisk_iterate (int (*hook) (const char *name)) +grub_util_biosdisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) { unsigned i; @@ -224,7 +225,8 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name)) } static grub_err_t -grub_util_biosdisk_open (const char *name, grub_disk_t disk) +grub_util_biosdisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) { int drive; struct stat st; diff --git a/include/grub/disk.h b/include/grub/disk.h index 66db1149a..2678ad5eb 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -50,6 +50,15 @@ struct grub_disk; struct grub_disk_memberlist; #endif +typedef enum + { + GRUB_DISK_PULL_NONE, + GRUB_DISK_PULL_REMOVABLE, + GRUB_DISK_PULL_RESCAN, + GRUB_DISK_PULL_RESCAN_UNTYPED, + GRUB_DISK_PULL_MAX + } grub_disk_pull_t; + /* Disk device. */ struct grub_disk_dev { @@ -60,10 +69,12 @@ struct grub_disk_dev enum grub_disk_dev_id id; /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (int (*hook) (const char *name)); + int (*iterate) (int (*hook) (const char *name), + grub_disk_pull_t pull); /* Open the device named NAME, and set up DISK. */ - grub_err_t (*open) (const char *name, struct grub_disk *disk); + grub_err_t (*open) (const char *name, struct grub_disk *disk, + grub_disk_pull_t pull); /* Close the disk DISK. */ void (*close) (struct grub_disk *disk); diff --git a/include/grub/raid.h b/include/grub/raid.h index d5853639d..1eb43721a 100644 --- a/include/grub/raid.h +++ b/include/grub/raid.h @@ -42,6 +42,7 @@ struct grub_raid_array int number; /* The device number, taken from md_minor so we are consistent with the device name in Linux. */ + int became_readable_at; int level; /* RAID levels, only 0, 1 or 5 at the moment. */ int layout; /* Layout for RAID 5/6. */ unsigned int total_devs; /* Total number of devices in the array. */ From 5dad99b7304b4b2bb0daaa0c379420b4dd1955d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 01:10:24 +0200 Subject: [PATCH 0900/1414] more linux-like name for LVM volumes --- grub-core/disk/lvm.c | 42 +++++++++++++++++++++++++++--------- grub-core/kern/emu/getroot.c | 10 +++------ include/grub/lvm.h | 2 ++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 72f493540..c430f596d 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -172,7 +172,9 @@ find_lv (const char *name) { if (vg->lvs) for (lv = vg->lvs; lv; lv = lv->next) - if (! grub_strcmp (lv->name, name) && is_lv_readable (lv)) + if ((grub_strcmp (lv->fullname, name) == 0 + || grub_strcmp (lv->compatname, name) == 0) + && is_lv_readable (lv)) return lv; } return NULL; @@ -188,10 +190,7 @@ grub_lvm_open (const char *name, grub_disk_t disk, int explicit = 0; if (grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0) - { - name += sizeof ("lvm/") - 1; - explicit = 1; - } + explicit = 1; lv = find_lv (name); @@ -685,11 +684,34 @@ grub_lvm_scan_device (const char *name) q++; s = q - p; - lv->name = grub_malloc (vgname_len + 1 + s + 1); - grub_memcpy (lv->name, vgname, vgname_len); - lv->name[vgname_len] = '-'; - grub_memcpy (lv->name + vgname_len + 1, p, s); - lv->name[vgname_len + 1 + s] = '\0'; + lv->name = grub_strndup (p, s); + lv->compatname = grub_malloc (vgname_len + 1 + s + 1); + grub_memcpy (lv->compatname, vgname, vgname_len); + lv->compatname[vgname_len] = '-'; + grub_memcpy (lv->compatname + vgname_len + 1, p, s); + lv->compatname[vgname_len + 1 + s] = '\0'; + + { + const char *iptr; + char *optr; + lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len + + 1 + 2 * s + 1); + optr = lv->fullname; + for (iptr = vgname; iptr < vgname + vgname_len; iptr++) + { + *optr++ = *iptr; + if (*iptr == '-') + *optr++ = '-'; + } + *optr++ = '-'; + for (iptr = p; iptr < p + s; iptr++) + { + *optr++ = *iptr; + if (*iptr == '-') + *optr++ = '-'; + } + *optr++ = 0; + } lv->size = 0; diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index f836a6625..c780fd94d 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -783,14 +783,10 @@ grub_util_get_grub_dev (const char *os_dev) grub_size_t offset = sizeof ("/dev/mapper/") - 1; len = strlen (os_dev) - offset + 1; - grub_dev = xmalloc (len); + grub_dev = xmalloc (len + sizeof ("lvm/")); - for (i = 0; i < len; i++, offset++) - { - grub_dev[i] = os_dev[offset]; - if (os_dev[offset] == '-' && os_dev[offset + 1] == '-') - offset++; - } + grub_memcpy (grub_dev, "lvm/", sizeof ("lvm/") - 1); + grub_memcpy (grub_dev + sizeof ("lvm/") - 1, os_dev + offset, len); } break; diff --git a/include/grub/lvm.h b/include/grub/lvm.h index b962dfd6c..b5352c75c 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -44,6 +44,8 @@ struct grub_lvm_pv { struct grub_lvm_lv { char *name; + char *fullname; + char *compatname; unsigned int number; unsigned int segment_count; grub_uint64_t size; From 65b4742cd70d15d41483582b454f21144b9ba60e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 02:46:36 +0200 Subject: [PATCH 0901/1414] Add lost lvm/ prefix. Autoadd lvm subdevices. --- grub-core/disk/lvm.c | 20 ++++++ grub-core/kern/emu/getroot.c | 120 ++++++++++++++++++++++++++--------- include/grub/emu/hostdisk.h | 1 + 3 files changed, 111 insertions(+), 30 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index c430f596d..d104be750 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -26,6 +26,7 @@ #ifdef GRUB_UTIL #include +#include #endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -197,6 +198,16 @@ grub_lvm_open (const char *name, grub_disk_t disk, if (! lv && !scan_depth && pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) { +#ifdef GRUB_UTIL + if (explicit) + { + char buf[grub_strlen (name) + sizeof ("/dev/mapper/")]; + grub_memcpy (buf, "/dev/mapper/", sizeof ("/dev/mapper/")); + grub_strcpy (buf + sizeof ("/dev/mapper/") - 1, + name + sizeof ("lvm/") - 1); + grub_util_pull_device (buf); + } +#endif scan_for = name; scan_depth++; grub_device_iterate (&grub_lvm_scan_device); @@ -685,7 +696,11 @@ grub_lvm_scan_device (const char *name) s = q - p; lv->name = grub_strndup (p, s); + if (!lv->name) + goto lvs_fail; lv->compatname = grub_malloc (vgname_len + 1 + s + 1); + if (!lv->compatname) + goto lvs_fail; grub_memcpy (lv->compatname, vgname, vgname_len); lv->compatname[vgname_len] = '-'; grub_memcpy (lv->compatname + vgname_len + 1, p, s); @@ -696,7 +711,12 @@ grub_lvm_scan_device (const char *name) char *optr; lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len + 1 + 2 * s + 1); + if (!lv->fullname) + goto lvs_fail; + optr = lv->fullname; + grub_memcpy (optr, "lvm/", sizeof ("lvm/") - 1); + optr += sizeof ("lvm/") - 1; for (iptr = vgname; iptr < vgname + vgname_len; iptr++) { *optr++ = *iptr; diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index dd277d705..474bb42bc 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -640,6 +640,56 @@ grub_guess_root_device (const char *dir) return os_dev; } +#ifdef HAVE_DEVICE_MAPPER + +static int +grub_util_open_dm (const char *os_dev, struct dm_tree **tree, + struct dm_tree_node **node) +{ + uint32_t maj, min; + struct stat st; + + *node = NULL; + *tree = NULL; + + if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) + 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); + *tree = NULL; + 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); + *tree = NULL; + return 0; + } + return 1; +} + +#endif + static int grub_util_is_lvm (const char *os_dev) { @@ -648,40 +698,13 @@ grub_util_is_lvm (const char *os_dev) #ifdef HAVE_DEVICE_MAPPER { - struct dm_tree *tree; - uint32_t maj, min; - struct dm_tree_node *node = NULL; const char *node_uuid; - struct stat st; + struct dm_tree *tree; + struct dm_tree_node *node; - if (stat (os_dev, &st) < 0) + if (!grub_util_open_dm (os_dev, &tree, &node)) 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) { @@ -804,6 +827,43 @@ out: } #endif /* __linux__ */ +void +grub_util_pull_device (const char *os_dev) +{ + switch (grub_util_get_dev_abstraction (os_dev)) + { + case GRUB_DEV_ABSTRACTION_LVM: +#ifdef HAVE_DEVICE_MAPPER + { + struct dm_tree *tree; + struct dm_tree_node *node; + struct dm_tree_node *child; + void *handle = NULL; + + if (!grub_util_open_dm (os_dev, &tree, &node)) + return; + + while ((child = dm_tree_next_child (&handle, node, 0))) + { + const struct dm_info *dm = dm_tree_node_get_info (child); + char *subdev; + if (!dm) + continue; + subdev = grub_find_device ("/dev", makedev (dm->major, dm->minor)); + if (subdev) + grub_util_pull_device (subdev); + } + dm_tree_free (tree); + return; + } +#endif + + default: /* GRUB_DEV_ABSTRACTION_NONE */ + grub_util_biosdisk_get_grub_dev (os_dev); + return; + } +} + char * grub_util_get_grub_dev (const char *os_dev) { diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 842dff496..803c0f755 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -29,5 +29,6 @@ const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); int grub_util_biosdisk_is_present (const char *name); int grub_util_biosdisk_is_floppy (grub_disk_t disk); grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); +void grub_util_pull_device (const char *osname); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ From 4defebbec8eeae0909c6912d757e2a2f510dae78 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 13:55:30 +0200 Subject: [PATCH 0902/1414] automatic raid members addition --- Makefile.util.def | 2 +- grub-core/Makefile.core.def | 1 + grub-core/disk/lvm.c | 10 ---------- grub-core/kern/emu/getroot.c | 15 ++++++++++++++- {util => grub-core/kern/emu}/raid.c | 12 +++++++++--- include/grub/emu/getroot.h | 3 +++ include/grub/util/raid.h | 27 --------------------------- util/grub-setup.c | 5 ++--- 8 files changed, 30 insertions(+), 45 deletions(-) rename {util => grub-core/kern/emu}/raid.c (84%) delete mode 100644 include/grub/util/raid.h diff --git a/Makefile.util.def b/Makefile.util.def index 058572f06..40c67c233 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -10,6 +10,7 @@ library = { common = grub-core/kern/device.c; common = grub-core/kern/disk.c; common = grub-core/kern/emu/getroot.c; + common = grub-core/kern/emu/raid.c; common = grub-core/kern/emu/hostdisk.c; common = grub-core/kern/emu/misc.c; common = grub-core/kern/emu/mm.c; @@ -265,7 +266,6 @@ program = { installdir = sbin; mansection = 8; common = util/grub-setup.c; - common = util/raid.c; common = util/lvm.c; common = grub-core/lib/reed_solomon.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f4d38149d..4146e3841 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -165,6 +165,7 @@ kernel = { emu = kern/emu/cache.S; emu = kern/emu/console.c; emu = kern/emu/getroot.c; + emu = kern/emu/raid.c; emu = kern/emu/hostdisk.c; emu = kern/emu/hostfs.c; emu = kern/emu/main.c; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index d104be750..b86cd8023 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -198,16 +198,6 @@ grub_lvm_open (const char *name, grub_disk_t disk, if (! lv && !scan_depth && pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) { -#ifdef GRUB_UTIL - if (explicit) - { - char buf[grub_strlen (name) + sizeof ("/dev/mapper/")]; - grub_memcpy (buf, "/dev/mapper/", sizeof ("/dev/mapper/")); - grub_strcpy (buf + sizeof ("/dev/mapper/") - 1, - name + sizeof ("lvm/") - 1); - grub_util_pull_device (buf); - } -#endif scan_for = name; scan_depth++; grub_device_iterate (&grub_lvm_scan_device); diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 474bb42bc..d9c1c9e08 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -854,9 +854,20 @@ grub_util_pull_device (const char *os_dev) grub_util_pull_device (subdev); } dm_tree_free (tree); - return; } #endif + return; + case GRUB_DEV_ABSTRACTION_RAID: +#ifdef __linux__ + { + char **devicelist = grub_util_raid_getmembers (os_dev, 0); + int i; + for (i = 0; devicelist[i];i++) + grub_util_pull_device (devicelist[i]); + free (devicelist); + } +#endif + return; default: /* GRUB_DEV_ABSTRACTION_NONE */ grub_util_biosdisk_get_grub_dev (os_dev); @@ -869,6 +880,8 @@ grub_util_get_grub_dev (const char *os_dev) { char *grub_dev = NULL; + grub_util_pull_device (os_dev); + switch (grub_util_get_dev_abstraction (os_dev)) { case GRUB_DEV_ABSTRACTION_LVM: diff --git a/util/raid.c b/grub-core/kern/emu/raid.c similarity index 84% rename from util/raid.c rename to grub-core/kern/emu/raid.c index a6aa5f95e..1371117da 100644 --- a/util/raid.c +++ b/grub-core/kern/emu/raid.c @@ -21,7 +21,6 @@ #ifdef __linux__ #include #include -#include #include #include @@ -36,7 +35,7 @@ #include char ** -grub_util_raid_getmembers (const char *name) +grub_util_raid_getmembers (const char *name, int bootable) { int fd, ret, i, j; char **devicelist; @@ -53,7 +52,14 @@ grub_util_raid_getmembers (const char *name) if (ret != 0) grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno)); - if (version.major != 0 || version.minor != 90) + if ((version.major != 0 || version.minor != 90) + && (version.major != 1 || version.minor != 0) + && (version.major != 1 || version.minor != 1) + && (version.major != 1 || version.minor != 2)) + grub_util_error ("unsupported RAID version: %d.%d", + version.major, version.minor); + + if (bootable && (version.major != 0 || version.minor != 90)) grub_util_error ("unsupported RAID version: %d.%d", version.major, version.minor); diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 581ea8056..702903ee6 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -34,5 +34,8 @@ char *grub_util_get_grub_dev (const char *os_dev); char *grub_make_system_path_relative_to_its_root (const char *path); const char *grub_util_check_block_device (const char *blk_dev); const char *grub_util_check_char_device (const char *blk_dev); +#ifdef __linux__ +char **grub_util_raid_getmembers (const char *name, int bootable); +#endif #endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h deleted file mode 100644 index 4da5eaaa8..000000000 --- a/include/grub/util/raid.h +++ /dev/null @@ -1,27 +0,0 @@ -/* raid.h - RAID support for GRUB utils. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,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_RAID_UTIL_HEADER -#define GRUB_RAID_UTIL_HEADER 1 - -#ifdef __linux__ -char** grub_util_raid_getmembers (const char *name); -#endif - -#endif /* ! GRUB_RAID_UTIL_HEADER */ diff --git a/util/grub-setup.c b/util/grub-setup.c index 7d47fa654..8482e11c9 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #ifdef GRUB_MACHINE_IEEE1275 #include @@ -972,12 +971,12 @@ main (int argc, char *argv[]) int i; if (arguments.device[0] == '/') - devicelist = grub_util_raid_getmembers (arguments.device); + devicelist = grub_util_raid_getmembers (arguments.device, 1); else { char *devname; devname = xasprintf ("/dev/%s", dest_dev); - devicelist = grub_util_raid_getmembers (dest_dev); + devicelist = grub_util_raid_getmembers (dest_dev, 1); free (devname); } From 716aa45e40c96ddbe01403faa42355b22a4d4b96 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 14:58:12 +0200 Subject: [PATCH 0903/1414] Fix LVM listing --- grub-core/disk/lvm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index b86cd8023..ec1780e32 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -129,10 +129,7 @@ grub_lvm_iterate (int (*hook) (const char *name), for (lv = vg->lvs; lv; lv = lv->next) if (lv->visible && lv->number >= old_count) { - char lvname[sizeof ("lvm/") + grub_strlen (lv->name)]; - grub_memcpy (lvname, "lvm/", sizeof ("lvm/") - 1); - grub_strcpy (lvname + sizeof ("lvm/") - 1, lv->name); - if (hook (lvname)) + if (hook (lv->fullname)) return 1; } } From f3470f4eb51026e410c687f10065a1fc797ba384 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 16:32:27 +0200 Subject: [PATCH 0904/1414] restructure prior to adding cheatmounts --- grub-core/disk/luks.c | 302 +++++++++++++++++++++++------------------- 1 file changed, 166 insertions(+), 136 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 12a37b98b..4d907b4c6 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -75,6 +75,7 @@ struct grub_luks int ref; grub_crypto_cipher_handle_t cipher; grub_crypto_cipher_handle_t essiv_cipher; + const gcry_md_spec_t *essiv_hash, *hash; luks_mode_t mode; unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; @@ -154,45 +155,28 @@ luks_decrypt (grub_crypto_cipher_handle_t cipher, luks_mode_t mode, static int check_uuid, have_it; static char *search_uuid; -static grub_err_t -grub_luks_scan_device_real (const char *name, grub_disk_t source) +static grub_luks_t +configure_ciphers (const struct grub_luks_phdr *header) { - grub_err_t err; - struct grub_luks_phdr header; + grub_luks_t newdev; + const char *iptr; + char *optr; + char uuid[sizeof (header->uuid) + 1]; + char ciphername[sizeof (header->cipherName) + 1]; + char ciphermode[sizeof (header->cipherMode) + 1]; + char hashspec[sizeof (header->hashSpec) + 1]; grub_crypto_cipher_handle_t cipher = NULL, essiv_cipher = NULL; const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; - grub_size_t keysize; - /* GCC thinks we may use this variable uninitialised. Silence the warning. */ - grub_size_t essiv_keysize = 0; - grub_uint8_t *hashed_key = NULL; - luks_mode_t mode; - grub_uint8_t *split_key = NULL; - unsigned i; - grub_size_t length; const struct gcry_cipher_spec *ciph; - char passphrase[MAX_PASSPHRASE] = ""; - grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; - char uuid[sizeof (header.uuid) + 1]; - char *iptr, *optr; - - /* Read the LUKS header. */ - err = grub_disk_read (source, 0, 0, sizeof (header), &header); - if (err) - return err; - + luks_mode_t mode; + /* Look for LUKS magic sequence. */ - if (grub_memcmp (header.magic, LUKS_MAGIC, sizeof (header.magic)) - || grub_be_to_cpu16 (header.version) != 1) - return GRUB_ERR_NONE; - - /* Make sure that strings are null terminated. */ - header.cipherName[sizeof (header.cipherName) - 1] = 0; - header.cipherMode[sizeof (header.cipherMode) - 1] = 0; - header.hashSpec[sizeof (header.hashSpec) - 1] = 0; - header.uuid[sizeof (header.uuid) - 1] = 0; + if (grub_memcmp (header->magic, LUKS_MAGIC, sizeof (header->magic)) + || grub_be_to_cpu16 (header->version) != 1) + return NULL; optr = uuid; - for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)]; + for (iptr = header->uuid; iptr < &header->uuid[ARRAY_SIZE (header->uuid)]; iptr++) { if (*iptr != '-') @@ -203,126 +187,163 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) { grub_dprintf ("luks", "%s != %s", uuid, search_uuid); - return 0; + return NULL; } - ciph = grub_crypto_lookup_cipher_by_name (header.cipherName); + /* Make sure that strings are null terminated. */ + grub_memcpy (ciphername, header->cipherName, sizeof (header->cipherName)); + ciphername[sizeof (header->cipherName)] = 0; + grub_memcpy (ciphermode, header->cipherMode, sizeof (header->cipherMode)); + ciphermode[sizeof (header->cipherMode)] = 0; + grub_memcpy (hashspec, header->hashSpec, sizeof (header->hashSpec)); + hashspec[sizeof (header->hashSpec)] = 0; + + ciph = grub_crypto_lookup_cipher_by_name (ciphername); if (!ciph) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", - header.cipherName); + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", + ciphername); + return NULL; + } /* Configure the cipher used for the bulk data. */ cipher = grub_crypto_cipher_open (ciph); if (!cipher) - return grub_errno; + return NULL; - keysize = grub_be_to_cpu32 (header.keyBytes); - if (keysize > 1024) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", keysize); + if (grub_be_to_cpu32 (header->keyBytes) > 1024) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", + grub_be_to_cpu32 (header->keyBytes)); + return NULL; + } /* Configure the cipher mode. */ - if (grub_strncmp (header.cipherMode, "ecb", 3) == 0) + if (grub_strncmp (ciphermode, "ecb", 3) == 0) mode = GRUB_LUKS_MODE_ECB; - else if (grub_strncmp (header.cipherMode, "cbc-plain", 9) == 0 - || grub_strncmp (header.cipherMode, "plain", 5) == 0) + else if (grub_strncmp (ciphermode, "cbc-plain", 9) == 0 + || grub_strncmp (ciphermode, "plain", 5) == 0) mode = GRUB_LUKS_MODE_CBC_PLAIN; - else if (grub_strncmp (header.cipherMode, "cbc-essiv", 9) == 0) + else if (grub_strncmp (ciphermode, "cbc-essiv", 9) == 0) { mode = GRUB_LUKS_MODE_CBC_ESSIV; - char *hash_str = header.cipherMode + 10; + char *hash_str = ciphermode + 10; /* Configure the hash and cipher used for ESSIV. */ essiv_hash = grub_crypto_lookup_md_by_name (hash_str); if (!essiv_hash) { grub_crypto_cipher_close (cipher); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load %s hash", hash_str); + grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load %s hash", hash_str); + return NULL; } essiv_cipher = grub_crypto_cipher_open (ciph); if (!cipher) { grub_crypto_cipher_close (cipher); - return grub_errno; - } - - essiv_keysize = essiv_hash->mdlen; - hashed_key = grub_malloc (essiv_hash->mdlen); - if (!hashed_key) - { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); - return grub_errno; + return NULL; } } else { grub_crypto_cipher_close (cipher); - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", - header.cipherMode); + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", + ciphermode); + return NULL; } /* Configure the hash used for the AF splitter and HMAC. */ - hash = grub_crypto_lookup_md_by_name (header.hashSpec); + hash = grub_crypto_lookup_md_by_name (hashspec); if (!hash) { grub_crypto_cipher_close (cipher); grub_crypto_cipher_close (essiv_cipher); - grub_free (hashed_key); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", - header.hashSpec); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", + hashspec); + return NULL; + } + + newdev = grub_zalloc (sizeof (struct grub_luks)); + if (!newdev) + return NULL; + newdev->cipher = cipher; + newdev->offset = grub_be_to_cpu32 (header->payloadOffset); + newdev->source_disk = NULL; + newdev->mode = mode; + newdev->essiv_cipher = essiv_cipher; + newdev->essiv_hash = essiv_hash; + newdev->hash = hash; + newdev->id = n++; + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); + return newdev; +} + +static grub_err_t +luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, + const char *name, grub_disk_t source) +{ + grub_size_t keysize = grub_be_to_cpu32 (header->keyBytes); + grub_uint8_t candidate_key[keysize]; + grub_uint8_t digest[keysize]; + grub_uint8_t *hashed_key = NULL; + grub_uint8_t *split_key = NULL; + char passphrase[MAX_PASSPHRASE] = ""; + grub_uint8_t candidate_digest[sizeof (header->mkDigest)]; + unsigned i; + grub_size_t essiv_keysize = 0; + grub_size_t length; + grub_err_t err; + + if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) + essiv_keysize = dev->essiv_hash->mdlen; + hashed_key = grub_malloc (dev->essiv_hash->mdlen); + if (!hashed_key) + { + return grub_errno; } grub_printf ("Attempting to decrypt master key...\n"); - grub_uint8_t candidate_key[keysize]; - grub_uint8_t digest[keysize]; - split_key = grub_malloc (keysize * LUKS_STRIPES); if (!split_key) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); return grub_errno; } /* Get the passphrase from the user. */ - grub_printf ("Enter passphrase for %s (%s): ", name, uuid); + grub_printf ("Enter passphrase for %s (%s): ", name, dev->uuid); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); } /* Try to recover master key from each active keyslot. */ - for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) + for (i = 0; i < ARRAY_SIZE (header->keyblock); i++) { gcry_err_code_t gcry_err; /* Check if keyslot is enabled. */ - if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) + if (grub_be_to_cpu32 (header->keyblock[i].active) != LUKS_KEY_ENABLED) continue; grub_dprintf ("luks", "Trying keyslot %d\n", i); /* Calculate the PBKDF2 of the user supplied passphrase. */ - gcry_err = grub_crypto_pbkdf2 (hash, (grub_uint8_t *) passphrase, + gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, grub_strlen (passphrase), - header.keyblock[i].passwordSalt, - sizeof (header. + header->keyblock[i].passwordSalt, + sizeof (header-> keyblock[i].passwordSalt), - grub_be_to_cpu32 (header.keyblock[i]. + grub_be_to_cpu32 (header->keyblock[i]. passwordIterations), digest, keysize); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); @@ -331,60 +352,52 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) grub_dprintf ("luks", "PBKDF2 done\n"); /* Set the PBKDF2 output as the cipher key. */ - gcry_err = grub_crypto_cipher_set_key (cipher, digest, keysize); + gcry_err = grub_crypto_cipher_set_key (dev->cipher, digest, keysize); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } /* Configure ESSIV if necessary. */ - if (mode == GRUB_LUKS_MODE_CBC_ESSIV) + if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) { - grub_crypto_hash (essiv_hash, hashed_key, digest, keysize); - grub_crypto_cipher_set_key (essiv_cipher, hashed_key, + grub_crypto_hash (dev->essiv_hash, hashed_key, digest, keysize); + grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, essiv_keysize); } length = - grub_be_to_cpu32 (header.keyBytes) * - grub_be_to_cpu32 (header.keyblock[i].stripes); + grub_be_to_cpu32 (header->keyBytes) * + grub_be_to_cpu32 (header->keyblock[i].stripes); /* Read and decrypt the key material from the disk. */ err = grub_disk_read (source, - grub_be_to_cpu32 (header.keyblock + grub_be_to_cpu32 (header->keyblock [i].keyMaterialOffset), 0, length, split_key); if (err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return err; } - gcry_err = luks_decrypt (cipher, mode, split_key, - length, 0, essiv_cipher); + gcry_err = luks_decrypt (dev->cipher, dev->mode, split_key, + length, 0, dev->essiv_cipher); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } /* Merge the decrypted key material to get the candidate master key. */ - gcry_err = AF_merge (hash, split_key, candidate_key, keysize, - grub_be_to_cpu32 (header.keyblock[i].stripes)); + gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, + grub_be_to_cpu32 (header->keyblock[i].stripes)); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); @@ -393,18 +406,16 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) grub_dprintf ("luks", "candidate key recovered\n"); /* Calculate the PBKDF2 of the candidate master key. */ - gcry_err = grub_crypto_pbkdf2 (hash, candidate_key, - grub_be_to_cpu32 (header.keyBytes), - header.mkDigestSalt, - sizeof (header.mkDigestSalt), + gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, + grub_be_to_cpu32 (header->keyBytes), + header->mkDigestSalt, + sizeof (header->mkDigestSalt), grub_be_to_cpu32 - (header.mkDigestIterations), + (header->mkDigestIterations), candidate_digest, sizeof (candidate_digest)); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); @@ -412,71 +423,90 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) /* Compare the calculated PBKDF2 to the digest stored in the header to see if it's correct. */ - if (grub_memcmp (candidate_digest, header.mkDigest, - sizeof (header.mkDigest)) != 0) + if (grub_memcmp (candidate_digest, header->mkDigest, + sizeof (header->mkDigest)) != 0) continue; grub_printf ("Slot %d opened\n", i); /* Set the master key. */ - gcry_err = grub_crypto_cipher_set_key (cipher, candidate_key, keysize); + gcry_err = grub_crypto_cipher_set_key (dev->cipher, + candidate_key, keysize); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } /* Configure ESSIV if necessary. */ - if (mode == GRUB_LUKS_MODE_CBC_ESSIV) + if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) { - grub_crypto_hash (essiv_hash, hashed_key, candidate_key, keysize); + grub_crypto_hash (dev->essiv_hash, hashed_key, + candidate_key, keysize); gcry_err = - grub_crypto_cipher_set_key (essiv_cipher, hashed_key, + grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, essiv_keysize); if (gcry_err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } } - { - grub_luks_t newdev; - newdev = grub_zalloc (sizeof (struct grub_luks)); - if (!newdev) - return grub_errno; - newdev->id = n; - newdev->source = grub_strdup (name); - newdev->source_id = source->id; - newdev->source_dev_id = source->dev->id; - newdev->cipher = cipher; - newdev->offset = grub_be_to_cpu32 (header.payloadOffset); - newdev->source_disk = NULL; - newdev->mode = mode; - newdev->essiv_cipher = essiv_cipher; - grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); - newdev->next = luks_list; - luks_list = newdev; - n++; - } grub_free (split_key); grub_free (hashed_key); - have_it = 1; - return GRUB_ERR_NONE; } return GRUB_ACCESS_DENIED; } +static void +luks_close (grub_luks_t luks) +{ + grub_crypto_cipher_close (luks->cipher); + grub_crypto_cipher_close (luks->essiv_cipher); + grub_free (luks); +} + +static grub_err_t +grub_luks_scan_device_real (const char *name, grub_disk_t source) +{ + grub_err_t err; + struct grub_luks_phdr header; + grub_luks_t newdev; + + /* Read the LUKS header. */ + err = grub_disk_read (source, 0, 0, sizeof (header), &header); + if (err) + return err; + + newdev = configure_ciphers (&header); + if (!newdev) + return grub_errno; + + err = luks_recover_key (newdev, &header, name, source); + if (err) + { + luks_close (newdev); + return err; + } + + newdev->source = grub_strdup (name); + newdev->source_id = source->id; + newdev->source_dev_id = source->dev->id; + newdev->next = luks_list; + luks_list = newdev; + + have_it = 1; + + return GRUB_ERR_NONE; +} + static int grub_luks_scan_device (const char *name) { From dcd73ec05ef7a98f403860fcf7c9d80ef3c6440b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 19:04:21 +0200 Subject: [PATCH 0905/1414] add gcry to utils --- .bzrignore | 1 + Makefile.util.def | 18 ++++++++++-------- autogen.sh | 2 +- include/grub/crypto.h | 6 ++++++ util/grub-probe.c | 2 ++ util/import_gcry.py | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 56 insertions(+), 9 deletions(-) diff --git a/.bzrignore b/.bzrignore index 55cbdaeeb..204fc182f 100644 --- a/.bzrignore +++ b/.bzrignore @@ -135,3 +135,4 @@ widthspec.bin widthspec.h docs/stamp-1 docs/version-dev.texi +Makefile.utilgcry.def diff --git a/Makefile.util.def b/Makefile.util.def index 40c67c233..693a7d127 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -21,12 +21,16 @@ library = { common = grub-core/kern/list.c; common = grub-core/kern/misc.c; common = grub-core/kern/partition.c; + common = grub-core/lib/crypto.c; + common = grub-core/disk/luks.c; + common = grub-core/disk/AFSplitter.c; + common = grub-core/lib/pbkdf2.c; + common = grub-core/commands/extcmd.c; + common = grub-core/lib/arg.c; }; library = { name = libgrubmods.a; - cflags = '$(CFLAGS_GCRY)'; - cppflags = '$(CPPFLAGS_GCRY)'; common_nodist = grub_script.tab.c; common_nodist = grub_script.yy.c; @@ -35,7 +39,6 @@ library = { common_nodist = grub_script.tab.h; common = grub-core/commands/blocklist.c; - common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; common = grub-core/disk/dmraid_nvidia.c; common = grub-core/disk/loopback.c; @@ -75,15 +78,10 @@ library = { common = grub-core/fs/zfs/zfs_lzjb.c; common = grub-core/fs/zfs/zfs_sha256.c; common = grub-core/fs/zfs/zfs_fletcher.c; - common = grub-core/lib/arg.c; - common = grub-core/lib/crypto.c; common = grub-core/lib/envblk.c; common = grub-core/lib/hexdump.c; - common = grub-core/lib/libgcrypt-grub/cipher/sha512.c; - common = grub-core/lib/libgcrypt-grub/cipher/crc.c; common = grub-core/lib/LzFind.c; common = grub-core/lib/LzmaEnc.c; - common = grub-core/lib/pbkdf2.c; common = grub-core/lib/crc.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; @@ -123,6 +121,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBLZMA)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; @@ -173,6 +172,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cflags = '$(CFLAGS_GCRY)'; @@ -211,6 +211,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -257,6 +258,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; diff --git a/autogen.sh b/autogen.sh index d14707aad..db719cd1d 100755 --- a/autogen.sh +++ b/autogen.sh @@ -26,7 +26,7 @@ if [ "x${GRUB_CONTRIB}" != x ]; then [ "${GRUB_CONTRIB}" = grub-core/contrib ] || ln -s ../contrib grub-core/contrib fi -UTIL_DEFS=Makefile.util.def +UTIL_DEFS='Makefile.util.def Makefile.utilgcry.def' CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def' for extra in contrib/*/Makefile.util.def; do diff --git a/include/grub/crypto.h b/include/grub/crypto.h index ebe78e7a1..a8ca2106d 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -274,4 +274,10 @@ grub_password_get (char buf[], unsigned buf_size); extern void (*grub_crypto_autoload_hook) (const char *name); +#ifdef GRUB_UTIL +void grub_gcry_init_all (void); +void grub_gcry_fini_all (void); +#endif + + #endif diff --git a/util/grub-probe.c b/util/grub-probe.c index 0d5dac902..6c6220b8b 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -393,6 +393,7 @@ main (int argc, char *argv[]) /* Initialize all modules. */ grub_init_all (); + grub_gcry_init_all (); grub_lvm_fini (); grub_mdraid09_fini (); @@ -410,6 +411,7 @@ main (int argc, char *argv[]) probe (argument, NULL); /* Free resources. */ + grub_gcry_fini_all (); grub_fini_all (); grub_util_biosdisk_fini (); diff --git a/util/import_gcry.py b/util/import_gcry.py index b2a0a5451..3a110f028 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -42,7 +42,15 @@ except: cipher_files = os.listdir (cipher_dir_in) conf = open (os.path.join ("grub-core", "Makefile.gcry.def"), "w") conf.write ("AutoGen definitions Makefile.tpl;\n\n") +confutil = open ("Makefile.utilgcry.def", "w") +confutil.write ("AutoGen definitions Makefile.tpl;\n\n") +confutil.write ("library = {\n"); +confutil.write (" name = libgrubgcry.a;\n"); +confutil.write (" cflags = '$(CFLAGS_GCRY)';\n"); +confutil.write (" cppflags = '$(CPPFLAGS_GCRY)';\n"); +confutil.write ("\n"); chlog = "" +modules = [] # Strictly speaking CRC32/CRC24 work on bytes so this value should be 1 # But libgcrypt uses 64. Let's keep the value for compatibility. Since @@ -249,6 +257,7 @@ for cipher_file in cipher_files: % (cipher_file, cipher_file.replace ("-glue.c", ".c")) else: modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file + modules.append (modname) chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) @@ -283,6 +292,7 @@ for cipher_file in cipher_files: conf.write (" name = %s;\n" % modname) for src in modfiles.split(): conf.write (" common = %s;\n" % src) + confutil.write (" common = grub-core/%s;\n" % src) conf.write (" cflags = '$(CFLAGS_GCRY)';\n"); conf.write (" cppflags = '$(CPPFLAGS_GCRY)';\n"); conf.write ("};\n\n") @@ -329,6 +339,32 @@ fw.close () infile = os.path.join (cipher_dir_in, "ChangeLog") outfile = os.path.join (cipher_dir_out, "ChangeLog") +conf.close (); + +initfile = open (os.path.join (cipher_dir_out, "init.c"), "w") +for module in modules: + initfile.write ("extern void grub_%s_init (void);\n" % module) + initfile.write ("extern void grub_%s_fini (void);\n" % module) +initfile.write ("\n") +initfile.write ("void\n") +initfile.write ("grub_gcry_init_all (void)\n") +initfile.write ("{\n") +for module in modules: + initfile.write (" grub_%s_init ();\n" % module) +initfile.write ("}\n") +initfile.write ("\n") +initfile.write ("void\n") +initfile.write ("grub_gcry_fini_all (void)\n") +initfile.write ("{\n") +for module in modules: + initfile.write (" grub_%s_fini ();\n" % module) +initfile.write ("}\n") +initfile.close () + +confutil.write (" common = grub-core/lib/libgcrypt-grub/cipher/init.c;\n") +confutil.write ("};\n"); +confutil.close (); + f=open (infile, "r") fw=open (outfile, "w") From 24089d19e2dde4e72d8c783a3f1a607f5a8e7729 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 19:20:46 +0200 Subject: [PATCH 0906/1414] Add cheatmounting --- grub-core/disk/luks.c | 99 +++++++++++++++++++++++++++++++++-- grub-core/kern/emu/getroot.c | 26 +++++++-- grub-core/kern/emu/hostdisk.c | 75 ++++++++++++++------------ include/grub/emu/hostdisk.h | 6 +++ 4 files changed, 166 insertions(+), 40 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 4d907b4c6..99dd3a8e6 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -25,6 +25,15 @@ #include #include #include +#ifdef GRUB_UTIL +#include +#include +#include +#include +#include +#include +#include +#endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -80,6 +89,10 @@ struct grub_luks unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; +#ifdef GRUB_UTIL + char *cheat; + int cheat_fd; +#endif struct grub_luks *next; }; typedef struct grub_luks *grub_luks_t; @@ -497,6 +510,12 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) } newdev->source = grub_strdup (name); + if (!newdev->source) + { + grub_free (newdev); + return grub_errno; + } + newdev->source_id = source->id; newdev->source_dev_id = source->dev->id; newdev->next = luks_list; @@ -507,6 +526,48 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) return GRUB_ERR_NONE; } +#ifdef GRUB_UTIL +grub_err_t +grub_luks_cheat_mount (const char *sourcedev, const char *cheat) +{ + grub_err_t err; + struct grub_luks_phdr header; + grub_luks_t newdev; + grub_disk_t source; + + /* Try to open disk. */ + source = grub_disk_open (sourcedev); + if (!source) + return grub_errno; + + /* Read the LUKS header. */ + err = grub_disk_read (source, 0, 0, sizeof (header), &header); + if (err) + return err; + + newdev = configure_ciphers (&header); + grub_disk_close (source); + if (!newdev) + return grub_errno; + + newdev->cheat = grub_strdup (cheat); + newdev->source = grub_strdup (sourcedev); + if (!newdev->source || !newdev->cheat) + { + grub_free (newdev->source); + grub_free (newdev->cheat); + grub_free (newdev); + return grub_errno; + } + newdev->cheat_fd = -1; + newdev->source_id = source->id; + newdev->source_dev_id = source->dev->id; + newdev->next = luks_list; + luks_list = newdev; + return GRUB_ERR_NONE; +} +#endif + static int grub_luks_scan_device (const char *name) { @@ -575,6 +636,17 @@ grub_luks_open (const char *name, grub_disk_t disk, if (!dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); +#ifdef GRUB_UTIL + if (dev->cheat) + { + if (dev->cheat_fd == -1) + dev->cheat_fd = open (dev->cheat, O_RDONLY); + if (dev->cheat_fd == -1) + return grub_error (GRUB_ERR_IO, "couldn't open %s: %s", + dev->cheat, strerror (errno)); + } +#endif + if (!dev->source_disk) { grub_dprintf ("luks", "Opening device %s\n", name); @@ -599,11 +671,17 @@ grub_luks_close (grub_disk_t disk) dev->ref--; - if (dev->ref == 0) + if (dev->ref != 0) + return; +#ifdef GRUB_UTIL + if (dev->cheat) { - grub_disk_close (dev->source_disk); - dev->source_disk = NULL; + close (dev->cheat_fd); + dev->cheat_fd = -1; } +#endif + grub_disk_close (dev->source_disk); + dev->source_disk = NULL; } static grub_err_t @@ -612,6 +690,21 @@ grub_luks_read (grub_disk_t disk, grub_disk_addr_t sector, { grub_luks_t dev = (grub_luks_t) disk->data; grub_err_t err; + +#ifdef GRUB_UTIL + if (dev->cheat) + { + err = grub_util_fd_sector_seek (dev->cheat_fd, dev->cheat, sector); + if (err) + return err; + if (grub_util_fd_read (dev->cheat_fd, buf, size << GRUB_DISK_SECTOR_BITS) + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + return grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", + dev->cheat); + return GRUB_ERR_NONE; + } +#endif + grub_dprintf ("luks", "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%" PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT32_T "\n", diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 6cc745833..c3a971689 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -865,7 +865,9 @@ out: void grub_util_pull_device (const char *os_dev) { - switch (grub_util_get_dev_abstraction (os_dev)) + int ab; + ab = grub_util_get_dev_abstraction (os_dev); + switch (ab) { case GRUB_DEV_ABSTRACTION_LVM: case GRUB_DEV_ABSTRACTION_LUKS: @@ -875,6 +877,7 @@ grub_util_pull_device (const char *os_dev) struct dm_tree_node *node; struct dm_tree_node *child; void *handle = NULL; + char *lastsubdev = NULL; if (!grub_util_open_dm (os_dev, &tree, &node)) return; @@ -887,9 +890,26 @@ grub_util_pull_device (const char *os_dev) continue; subdev = grub_find_device ("/dev", makedev (dm->major, dm->minor)); if (subdev) - grub_util_pull_device (subdev); + { + lastsubdev = subdev; + grub_util_pull_device (subdev); + } } - dm_tree_free (tree); + if (ab == GRUB_DEV_ABSTRACTION_LUKS && lastsubdev) + { + char *grdev = grub_util_get_grub_dev (lastsubdev); + dm_tree_free (tree); + if (grdev) + { + grub_err_t err; + err = grub_luks_cheat_mount (grdev, os_dev); + if (err) + grub_util_error ("Can't mount LUKS: %s", grub_errmsg); + } + grub_free (grdev); + } + else + dm_tree_free (tree); } #endif return; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 9b65d417e..110d3e291 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -631,6 +631,37 @@ linux_find_partition (char *dev, unsigned long sector) } #endif /* __linux__ */ +#if defined(__linux__) && (!defined(__GLIBC__) || \ + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) + /* Maybe libc doesn't have large file support. */ +grub_err_t +grub_util_fd_sector_seek (int fd, const char *name, grub_disk_addr_t sector) +{ + loff_t offset, result; + static int _llseek (uint filedes, ulong hi, ulong lo, + loff_t *res, uint wh); + _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, + loff_t *, res, uint, wh); + + offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS; + if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) + { + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", name); + } + return GRUB_ERR_NONE; +} +#else +grub_err_t +grub_util_fd_sector_seek (int fd, const char *name, grub_disk_addr_t sector) +{ + off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS; + + if (lseek (fd, offset, SEEK_SET) != offset) + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", name); + return 0; +} +#endif + static int open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { @@ -781,44 +812,19 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) configure_device_driver (fd); #endif /* defined(__NetBSD__) */ -#if defined(__linux__) && (!defined(__GLIBC__) || \ - ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) - /* Maybe libc doesn't have large file support. */ - { - loff_t offset, result; - static int _llseek (uint filedes, ulong hi, ulong lo, - loff_t *res, uint wh); - _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, - loff_t *, res, uint, wh); - - offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS; - if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) - { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); - close (fd); - return -1; - } - } -#else - { - off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS; - - if (lseek (fd, offset, SEEK_SET) != offset) - { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); - close (fd); - return -1; - } - } -#endif + if (grub_util_fd_sector_seek (fd, map[disk->id].device, sector)) + { + close (fd); + return -1; + } return fd; } /* Read LEN bytes from FD in BUF. Return less than or equal to zero if an error occurs, otherwise return LEN. */ -static ssize_t -nread (int fd, char *buf, size_t len) +ssize_t +grub_util_fd_read (int fd, char *buf, size_t len) { ssize_t size = len; @@ -901,7 +907,8 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, sectors that are read together with the MBR in one read. It should only remap the MBR, so we split the read in two parts. -jochen */ - if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) + if (grub_util_fd_read (fd, buf, GRUB_DISK_SECTOR_SIZE) + != GRUB_DISK_SECTOR_SIZE) { grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device); return grub_errno; @@ -912,7 +919,7 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, } #endif /* __linux__ */ - if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS) + if (grub_util_fd_read (fd, buf, size << GRUB_DISK_SECTOR_BITS) != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device); diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 803c0f755..c7a794d68 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -21,6 +21,7 @@ #define GRUB_BIOSDISK_MACHINE_UTIL_HEADER 1 #include +#include void grub_util_biosdisk_init (const char *dev_map); void grub_util_biosdisk_fini (void); @@ -30,5 +31,10 @@ int grub_util_biosdisk_is_present (const char *name); int grub_util_biosdisk_is_floppy (grub_disk_t disk); grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); void grub_util_pull_device (const char *osname); +grub_err_t +grub_util_fd_sector_seek (int fd, const char *name, grub_disk_addr_t sector); +ssize_t grub_util_fd_read (int fd, char *buf, size_t len); +grub_err_t +grub_luks_cheat_mount (const char *sourcedev, const char *cheat); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ From 4169260830d30fca23af54441bfd3ea749b7c006 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 19:44:41 +0200 Subject: [PATCH 0907/1414] grub-fstest luks support --- grub-core/disk/luks.c | 28 ++++++++++++++++++++++++---- util/grub-fstest.c | 15 +++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 99dd3a8e6..eb9dd050e 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -107,6 +107,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, static const struct grub_arg_option options[] = { {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, + {"all", 'a', 0, N_("Mount all."), 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -491,7 +492,11 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) { grub_err_t err; struct grub_luks_phdr header; - grub_luks_t newdev; + grub_luks_t newdev, dev; + + for (dev = luks_list; dev != NULL; dev = dev->next) + if (dev->source_id == source->id && dev->source_dev_id == source->dev->id) + return GRUB_ERR_NONE; /* Read the LUKS header. */ err = grub_disk_read (source, 0, 0, sizeof (header), &header); @@ -532,7 +537,7 @@ grub_luks_cheat_mount (const char *sourcedev, const char *cheat) { grub_err_t err; struct grub_luks_phdr header; - grub_luks_t newdev; + grub_luks_t newdev, dev; grub_disk_t source; /* Try to open disk. */ @@ -540,6 +545,13 @@ grub_luks_cheat_mount (const char *sourcedev, const char *cheat) if (!source) return grub_errno; + for (dev = luks_list; dev != NULL; dev = dev->next) + if (dev->source_id == source->id && dev->source_dev_id == source->dev->id) + { + grub_disk_close (source); + return GRUB_ERR_NONE; + } + /* Read the LUKS header. */ err = grub_disk_read (source, 0, 0, sizeof (header), &header); if (err) @@ -755,7 +767,7 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; - if (argc < 1) + if (argc < 1 && !state[1].set) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); have_it = 0; @@ -779,6 +791,14 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); return GRUB_ERR_NONE; } + else if (state[1].set) + { + check_uuid = 0; + search_uuid = NULL; + grub_device_iterate (&grub_luks_scan_device); + search_uuid = NULL; + return GRUB_ERR_NONE; + } else { grub_err_t err; @@ -823,7 +843,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (luks) { cmd = grub_register_extcmd ("luksmount", grub_cmd_luksmount, 0, - N_("SOURCE|-u UUID"), + N_("SOURCE|-u UUID|-a"), N_("Mount a LUKS device."), options); grub_disk_dev_register (&grub_luks_dev); } diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 293bdf74a..2adb2331d 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -275,6 +275,7 @@ static char **images = NULL; static int cmd = 0; static char *debug_str = NULL; static char **args = NULL; +static int mount_crypt = 0; static void fstest (int n, char **args) @@ -304,6 +305,13 @@ fstest (int n, char **args) grub_free (host_file); } + { + char *argv[2] = { "-a", NULL}; + if (mount_crypt) + if (execute_command ("luksmount", 1, argv)) + grub_util_error (_("luksmount command fails: %s"), grub_errmsg); + } + grub_lvm_fini (); grub_mdraid09_fini (); grub_mdraid1x_fini (); @@ -366,6 +374,7 @@ static struct argp_option options[] = { {"length", 'n', "N", 0, N_("Handle N bytes in output file."), 2}, {"diskcount", 'c', "N", 0, N_("N input files."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, + {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {0, 0, 0, 0, 0, 0} }; @@ -389,6 +398,10 @@ argp_parser (int key, char *arg, struct argp_state *state) root = arg; return 0; + case 'C': + mount_crypt = 1; + return 0; + case 's': skip = grub_strtoul (arg, &p, 0); if (*p == 's') @@ -523,6 +536,7 @@ main (int argc, char *argv[]) /* Initialize all modules. */ grub_init_all (); + grub_gcry_init_all (); if (debug_str) grub_env_set ("debug", debug_str); @@ -551,6 +565,7 @@ main (int argc, char *argv[]) fstest (args_count - 1 - num_disks, args); /* Free resources. */ + grub_gcry_fini_all (); grub_fini_all (); return 0; From 84a411c0c3b17ba1a67ef30a94134bb8c8a9266a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 19:51:06 +0200 Subject: [PATCH 0908/1414] small argument revamp --- grub-core/disk/luks.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index eb9dd050e..8bf07903c 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -112,27 +112,26 @@ static const struct grub_arg_option options[] = }; static gcry_err_code_t -luks_decrypt (grub_crypto_cipher_handle_t cipher, luks_mode_t mode, - grub_uint8_t * data, grub_size_t len, - grub_size_t sector, grub_crypto_cipher_handle_t essiv_cipher) +luks_decrypt (const struct grub_luks *dev, + grub_uint8_t * data, grub_size_t len, grub_size_t sector) { grub_size_t i; gcry_err_code_t err; - switch (mode) + switch (dev->mode) { case GRUB_LUKS_MODE_ECB: - return grub_crypto_ecb_decrypt (cipher, data, data, len); + return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); case GRUB_LUKS_MODE_CBC_PLAIN: for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) { - grub_uint32_t iv[(cipher->cipher->blocksize + grub_uint32_t iv[(dev->cipher->cipher->blocksize + sizeof (grub_uint32_t) - 1) / sizeof (grub_uint32_t)]; - grub_memset (iv, 0, cipher->cipher->blocksize); + grub_memset (iv, 0, dev->cipher->cipher->blocksize); iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); - err = grub_crypto_cbc_decrypt (cipher, data + i, data + i, + err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, GRUB_DISK_SECTOR_SIZE, iv); if (err) return err; @@ -143,17 +142,17 @@ luks_decrypt (grub_crypto_cipher_handle_t cipher, luks_mode_t mode, case GRUB_LUKS_MODE_CBC_ESSIV: for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) { - grub_uint32_t iv[(cipher->cipher->blocksize + grub_uint32_t iv[(dev->cipher->cipher->blocksize + sizeof (grub_uint32_t) - 1) / sizeof (grub_uint32_t)]; - grub_memset (iv, 0, cipher->cipher->blocksize); + grub_memset (iv, 0, dev->cipher->cipher->blocksize); iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); err = - grub_crypto_ecb_encrypt (essiv_cipher, iv, iv, - cipher->cipher->blocksize); + grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv, + dev->cipher->cipher->blocksize); if (err) return err; - err = grub_crypto_cbc_decrypt (cipher, data + i, data + i, + err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, GRUB_DISK_SECTOR_SIZE, iv); if (err) return err; @@ -398,8 +397,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, return err; } - gcry_err = luks_decrypt (dev->cipher, dev->mode, split_key, - length, 0, dev->essiv_cipher); + gcry_err = luks_decrypt (dev, split_key, length, 0); if (gcry_err) { grub_free (hashed_key); @@ -729,11 +727,9 @@ grub_luks_read (grub_disk_t disk, grub_disk_addr_t sector, grub_dprintf ("luks", "grub_disk_read failed with error %d\n", err); return err; } - return grub_crypto_gcry_error (luks_decrypt (dev->cipher, - dev->mode, - (grub_uint8_t *) buf, + return grub_crypto_gcry_error (luks_decrypt (dev, (grub_uint8_t *) buf, size << GRUB_DISK_SECTOR_BITS, - sector, dev->essiv_cipher)); + sector)); } static grub_err_t From 2cb55e6f7356d82f826e65577373167a46b73f8d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 21:46:00 +0200 Subject: [PATCH 0909/1414] make grub_password_get work in userland --- grub-core/lib/crypto.c | 44 ++++++++++++++++++++- util/grub-mkpasswd-pbkdf2.c | 76 ++++++------------------------------- 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index ad1bfc4d3..2f172ebf8 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -23,6 +23,13 @@ #include #include +#ifdef GRUB_UTIL +#include +#include +#include +#include +#endif + GRUB_MOD_LICENSE ("GPLv3+"); struct grub_crypto_hmac_handle @@ -414,10 +421,43 @@ grub_crypto_memcmp (const void *a, const void *b, grub_size_t n) return !!counter; } -#ifndef GRUB_MKPASSWD int grub_password_get (char buf[], unsigned buf_size) { +#ifdef GRUB_UTIL + FILE *in; + struct termios s, t; + int tty_changed = 0; + char *ptr; + + /* Disable echoing. Based on glibc. */ + in = fopen ("/dev/tty", "w+c"); + if (in == NULL) + in = stdin; + + if (tcgetattr (fileno (in), &t) == 0) + { + /* Save the old one. */ + s = t; + /* Tricky, tricky. */ + t.c_lflag &= ~(ECHO|ISIG); + tty_changed = (tcsetattr (fileno (in), TCSAFLUSH, &t) == 0); + } + else + tty_changed = 0; + fgets (buf, buf_size, stdin); + ptr = buf + strlen (buf) - 1; + while (buf <= ptr && (*ptr == '\n' || *ptr == '\r')) + *ptr-- = 0; + /* Restore the original setting. */ + if (tty_changed) + (void) tcsetattr (fileno (in), TCSAFLUSH, &s); + + grub_xputs ("\n"); + grub_refresh (); + + return 1; +#else unsigned cur_len = 0; int key; @@ -452,5 +492,5 @@ grub_password_get (char buf[], unsigned buf_size) grub_refresh (); return (key != '\e'); -} #endif +} diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index fe1887f8f..032a8b586 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include "progname.h" @@ -85,14 +85,12 @@ int main (int argc, char *argv[]) { unsigned int count = 10000, buflen = 64, saltlen = 64; - char *pass1, *pass2; char *bufhex, *salthex; gcry_err_code_t gcry_err; grub_uint8_t *buf, *salt; ssize_t nr; - FILE *in, *out; - struct termios s, t; - int tty_changed; + char pass1[GRUB_AUTH_MAX_PASSLEN]; + char pass2[GRUB_AUTH_MAX_PASSLEN]; set_program_name (argv[0]); @@ -160,86 +158,37 @@ main (int argc, char *argv[]) free (buf); grub_util_error ("out of memory"); } - - /* Disable echoing. Based on glibc. */ - in = fopen ("/dev/tty", "w+c"); - if (in == NULL) - { - in = stdin; - out = stderr; - } - else - out = in; - - if (tcgetattr (fileno (in), &t) == 0) - { - /* Save the old one. */ - s = t; - /* Tricky, tricky. */ - t.c_lflag &= ~(ECHO|ISIG); - tty_changed = (tcsetattr (fileno (in), TCSAFLUSH, &t) == 0); - } - else - tty_changed = 0; printf ("Enter password: "); - pass1 = NULL; - { - grub_size_t n; - nr = getline (&pass1, &n, stdin); - } - if (nr < 0 || !pass1) + if (!grub_password_get (pass1, GRUB_AUTH_MAX_PASSLEN)) { free (buf); free (bufhex); free (salthex); free (salt); - /* Restore the original setting. */ - if (tty_changed) - (void) tcsetattr (fileno (in), TCSAFLUSH, &s); grub_util_error ("failure to read password"); } - if (nr >= 1 && pass1[nr-1] == '\n') - pass1[nr-1] = 0; - printf ("\nReenter password: "); - pass2 = NULL; - { - grub_size_t n; - nr = getline (&pass2, &n, stdin); - } - /* Restore the original setting. */ - if (tty_changed) - (void) tcsetattr (fileno (in), TCSAFLUSH, &s); - printf ("\n"); - - if (nr < 0 || !pass2) + if (!grub_password_get (pass2, GRUB_AUTH_MAX_PASSLEN)) { - memset (pass1, 0, strlen (pass1)); - free (pass1); free (buf); free (bufhex); free (salthex); free (salt); grub_util_error ("failure to read password"); } - if (nr >= 1 && pass2[nr-1] == '\n') - pass2[nr-1] = 0; if (strcmp (pass1, pass2) != 0) { - memset (pass1, 0, strlen (pass1)); - memset (pass2, 0, strlen (pass2)); - free (pass1); - free (pass2); + memset (pass1, 0, sizeof (pass1)); + memset (pass2, 0, sizeof (pass2)); free (buf); free (bufhex); free (salthex); free (salt); grub_util_error ("passwords don't match"); } - memset (pass2, 0, strlen (pass2)); - free (pass2); + memset (pass2, 0, sizeof (pass2)); #if ! defined (__linux__) && ! defined (__FreeBSD__) printf ("WARNING: your random generator isn't known to be secure\n"); @@ -251,8 +200,7 @@ main (int argc, char *argv[]) f = fopen ("/dev/random", "rb"); if (!f) { - memset (pass1, 0, strlen (pass1)); - free (pass1); + memset (pass1, 0, sizeof (pass1)); free (buf); free (bufhex); free (salthex); @@ -264,8 +212,7 @@ main (int argc, char *argv[]) if (rd != saltlen) { fclose (f); - memset (pass1, 0, strlen (pass1)); - free (pass1); + memset (pass1, 0, sizeof (pass1)); free (buf); free (bufhex); free (salthex); @@ -280,8 +227,7 @@ main (int argc, char *argv[]) (grub_uint8_t *) pass1, strlen (pass1), salt, saltlen, count, buf, buflen); - memset (pass1, 0, strlen (pass1)); - free (pass1); + memset (pass1, 0, sizeof (pass1)); if (gcry_err) { From fe32915a5ebc39f21524547c6a7ec6d123534828 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 21:48:32 +0200 Subject: [PATCH 0910/1414] XTS support --- grub-core/disk/luks.c | 192 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 157 insertions(+), 35 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 8bf07903c..0098c9d49 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -73,7 +73,8 @@ typedef enum { GRUB_LUKS_MODE_ECB, GRUB_LUKS_MODE_CBC_PLAIN, - GRUB_LUKS_MODE_CBC_ESSIV + GRUB_LUKS_MODE_CBC_ESSIV, + GRUB_LUKS_MODE_XTS } luks_mode_t; struct grub_luks @@ -83,7 +84,7 @@ struct grub_luks grub_disk_t source_disk; int ref; grub_crypto_cipher_handle_t cipher; - grub_crypto_cipher_handle_t essiv_cipher; + grub_crypto_cipher_handle_t secondary_cipher; const gcry_md_spec_t *essiv_hash, *hash; luks_mode_t mode; unsigned long id, source_id; @@ -111,6 +112,33 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; +static inline void +make_iv (grub_uint32_t *iv, grub_size_t sz, grub_disk_addr_t sector) +{ + grub_memset (iv, 0, sz * sizeof (iv[0])); + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); +} + +/* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ +#define POLYNOM 0x87 + +static void +gf_mul_x (grub_uint8_t *g) +{ + int over = 0, over2 = 0; + int j; + + for (j = 0; j < 16; j++) + { + over2 = !!(g[j] & 0x80); + g[j] <<= 1; + g[j] |= over; + over = over2; + } + if (over) + g[0] ^= POLYNOM; +} + static gcry_err_code_t luks_decrypt (const struct grub_luks *dev, grub_uint8_t * data, grub_size_t len, grub_size_t sector) @@ -126,11 +154,11 @@ luks_decrypt (const struct grub_luks *dev, case GRUB_LUKS_MODE_CBC_PLAIN: for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) { - grub_uint32_t iv[(dev->cipher->cipher->blocksize + grub_size_t sz = ((dev->cipher->cipher->blocksize + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)]; - grub_memset (iv, 0, dev->cipher->cipher->blocksize); - iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + / sizeof (grub_uint32_t)); + grub_uint32_t iv[sz]; + make_iv (iv, sz, sector); err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, GRUB_DISK_SECTOR_SIZE, iv); if (err) @@ -142,14 +170,14 @@ luks_decrypt (const struct grub_luks *dev, case GRUB_LUKS_MODE_CBC_ESSIV: for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) { - grub_uint32_t iv[(dev->cipher->cipher->blocksize + grub_size_t sz = ((dev->cipher->cipher->blocksize + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)]; - grub_memset (iv, 0, dev->cipher->cipher->blocksize); - iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); - err = - grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv, - dev->cipher->cipher->blocksize); + / sizeof (grub_uint32_t)); + grub_uint32_t iv[sz]; + make_iv (iv, sz, sector); + + err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, + dev->cipher->cipher->blocksize); if (err) return err; err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, @@ -160,6 +188,39 @@ luks_decrypt (const struct grub_luks *dev, } return GPG_ERR_NO_ERROR; + case GRUB_LUKS_MODE_XTS: + for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) + { + grub_size_t sz = ((dev->cipher->cipher->blocksize + + sizeof (grub_uint32_t) - 1) + / sizeof (grub_uint32_t)); + grub_uint32_t iv[sz]; + int j; + make_iv (iv, sz, sector); + + err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, + dev->cipher->cipher->blocksize); + if (err) + return err; + + for (j = 0; j < GRUB_DISK_SECTOR_SIZE; + j += dev->cipher->cipher->blocksize) + { + grub_crypto_xor (data + i + j, data + i + j, iv, + dev->cipher->cipher->blocksize); + err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, + data + i + j, + dev->cipher->cipher->blocksize); + if (err) + return err; + grub_crypto_xor (data + i + j, data + i + j, iv, + dev->cipher->cipher->blocksize); + gf_mul_x ((grub_uint8_t *) iv); + } + sector++; + } + return GPG_ERR_NO_ERROR; + default: return GPG_ERR_NOT_IMPLEMENTED; } @@ -178,7 +239,7 @@ configure_ciphers (const struct grub_luks_phdr *header) char ciphername[sizeof (header->cipherName) + 1]; char ciphermode[sizeof (header->cipherMode) + 1]; char hashspec[sizeof (header->hashSpec) + 1]; - grub_crypto_cipher_handle_t cipher = NULL, essiv_cipher = NULL; + grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; const struct gcry_cipher_spec *ciph; luks_mode_t mode; @@ -232,12 +293,13 @@ configure_ciphers (const struct grub_luks_phdr *header) } /* Configure the cipher mode. */ - if (grub_strncmp (ciphermode, "ecb", 3) == 0) + if (grub_strcmp (ciphermode, "ecb") == 0) mode = GRUB_LUKS_MODE_ECB; - else if (grub_strncmp (ciphermode, "cbc-plain", 9) == 0 - || grub_strncmp (ciphermode, "plain", 5) == 0) + else if (grub_strcmp (ciphermode, "cbc-plain") == 0 + || grub_strcmp (ciphermode, "plain") == 0) mode = GRUB_LUKS_MODE_CBC_PLAIN; - else if (grub_strncmp (ciphermode, "cbc-essiv", 9) == 0) + else if (grub_memcmp (ciphermode, "cbc-essiv:", sizeof ("cbc-essiv:") - 1) + == 0) { mode = GRUB_LUKS_MODE_CBC_ESSIV; char *hash_str = ciphermode + 10; @@ -251,13 +313,35 @@ configure_ciphers (const struct grub_luks_phdr *header) "Couldn't load %s hash", hash_str); return NULL; } - essiv_cipher = grub_crypto_cipher_open (ciph); - if (!cipher) + secondary_cipher = grub_crypto_cipher_open (ciph); + if (!secondary_cipher) { grub_crypto_cipher_close (cipher); return NULL; } } + else if (grub_strcmp (ciphermode, "xts-plain") == 0) + { + mode = GRUB_LUKS_MODE_XTS; + secondary_cipher = grub_crypto_cipher_open (ciph); + if (!secondary_cipher) + { + grub_crypto_cipher_close (cipher); + return NULL; + } + if (cipher->cipher->blocksize != 16) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", + cipher->cipher->blocksize); + return NULL; + } + if (secondary_cipher->cipher->blocksize != 16) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", + secondary_cipher->cipher->blocksize); + return NULL; + } + } else { grub_crypto_cipher_close (cipher); @@ -271,7 +355,7 @@ configure_ciphers (const struct grub_luks_phdr *header) if (!hash) { grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); + grub_crypto_cipher_close (secondary_cipher); grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", hashspec); return NULL; @@ -284,7 +368,7 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->offset = grub_be_to_cpu32 (header->payloadOffset); newdev->source_disk = NULL; newdev->mode = mode; - newdev->essiv_cipher = essiv_cipher; + newdev->secondary_cipher = secondary_cipher; newdev->essiv_hash = essiv_hash; newdev->hash = hash; newdev->id = n++; @@ -309,11 +393,11 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_err_t err; if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) - essiv_keysize = dev->essiv_hash->mdlen; - hashed_key = grub_malloc (dev->essiv_hash->mdlen); - if (!hashed_key) { - return grub_errno; + essiv_keysize = dev->essiv_hash->mdlen; + hashed_key = grub_malloc (dev->essiv_hash->mdlen); + if (!hashed_key) + return grub_errno; } grub_printf ("Attempting to decrypt master key...\n"); @@ -365,7 +449,9 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_dprintf ("luks", "PBKDF2 done\n"); /* Set the PBKDF2 output as the cipher key. */ - gcry_err = grub_crypto_cipher_set_key (dev->cipher, digest, keysize); + gcry_err = grub_crypto_cipher_set_key (dev->cipher, digest, + (dev->mode == GRUB_LUKS_MODE_XTS) + ? (keysize / 2) : keysize); if (gcry_err) { grub_free (hashed_key); @@ -377,8 +463,28 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) { grub_crypto_hash (dev->essiv_hash, hashed_key, digest, keysize); - grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, - essiv_keysize); + gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, + hashed_key, + essiv_keysize); + if (gcry_err) + { + grub_free (hashed_key); + grub_free (split_key); + return grub_crypto_gcry_error (gcry_err); + } + } + + if (dev->mode == GRUB_LUKS_MODE_XTS) + { + gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, + digest + (keysize / 2), + keysize / 2); + if (gcry_err) + { + grub_free (hashed_key); + grub_free (split_key); + return grub_crypto_gcry_error (gcry_err); + } } length = @@ -437,13 +543,17 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, in the header to see if it's correct. */ if (grub_memcmp (candidate_digest, header->mkDigest, sizeof (header->mkDigest)) != 0) - continue; + { + grub_dprintf ("luks", "bad digest\n"); + continue; + } grub_printf ("Slot %d opened\n", i); /* Set the master key. */ - gcry_err = grub_crypto_cipher_set_key (dev->cipher, - candidate_key, keysize); + gcry_err = grub_crypto_cipher_set_key (dev->cipher, candidate_key, + (dev->mode == GRUB_LUKS_MODE_XTS) + ? (keysize / 2) : keysize); if (gcry_err) { grub_free (hashed_key); @@ -457,7 +567,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_crypto_hash (dev->essiv_hash, hashed_key, candidate_key, keysize); gcry_err = - grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, + grub_crypto_cipher_set_key (dev->secondary_cipher, hashed_key, essiv_keysize); if (gcry_err) { @@ -467,6 +577,18 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, } } + if (dev->mode == GRUB_LUKS_MODE_XTS) + { + gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, + candidate_key + (keysize / 2), + keysize / 2); + if (gcry_err) + { + grub_free (hashed_key); + grub_free (split_key); + return grub_crypto_gcry_error (gcry_err); + } + } grub_free (split_key); grub_free (hashed_key); @@ -481,7 +603,7 @@ static void luks_close (grub_luks_t luks) { grub_crypto_cipher_close (luks->cipher); - grub_crypto_cipher_close (luks->essiv_cipher); + grub_crypto_cipher_close (luks->secondary_cipher); grub_free (luks); } @@ -751,7 +873,7 @@ luks_cleanup (void) { grub_free (dev->source); grub_free (dev->cipher); - grub_free (dev->essiv_cipher); + grub_free (dev->secondary_cipher); tmp = dev->next; grub_free (dev); dev = tmp; From 50ad7d9cae1c31bbcd2ec776083f5ca59f01c06a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 23:39:36 +0200 Subject: [PATCH 0911/1414] luks grub-probe support --- grub-core/disk/luks.c | 35 ++++++++++ include/grub/crypto.h | 6 ++ include/grub/emu/hostdisk.h | 1 + util/grub-probe.c | 136 +++++++++++++++--------------------- util/import_gcry.py | 22 ++++-- 5 files changed, 116 insertions(+), 84 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 0098c9d49..ce1f1bfc6 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -863,6 +863,38 @@ grub_luks_write (grub_disk_t disk __attribute ((unused)), return GRUB_ERR_NOT_IMPLEMENTED_YET; } +#ifdef GRUB_UTIL +static grub_disk_memberlist_t +grub_luks_memberlist (grub_disk_t disk) +{ + grub_luks_t dev = (grub_luks_t) disk->data; + grub_disk_memberlist_t list = NULL; + + list = grub_malloc (sizeof (*list)); + if (list) + { + list->disk = dev->source_disk; + list->next = NULL; + } + + return list; +} + +void +grub_util_luks_print_ciphers (grub_disk_t disk) +{ + grub_luks_t dev = (grub_luks_t) disk->data; + if (dev->cipher) + grub_printf ("%s ", dev->cipher->cipher->modname); + if (dev->secondary_cipher) + grub_printf ("%s ", dev->secondary_cipher->cipher->modname); + if (dev->hash) + grub_printf ("%s ", dev->hash->modname); + if (dev->essiv_hash) + grub_printf ("%s ", dev->essiv_hash->modname); +} +#endif + static void luks_cleanup (void) { @@ -953,6 +985,9 @@ static struct grub_disk_dev grub_luks_dev = { .close = grub_luks_close, .read = grub_luks_read, .write = grub_luks_write, +#ifdef GRUB_UTIL + .memberlist = grub_luks_memberlist, +#endif .next = 0 }; diff --git a/include/grub/crypto.h b/include/grub/crypto.h index a8ca2106d..62ed2015c 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -126,6 +126,9 @@ typedef struct gcry_cipher_spec gcry_cipher_decrypt_t decrypt; gcry_cipher_stencrypt_t stencrypt; gcry_cipher_stdecrypt_t stdecrypt; +#ifdef GRUB_UTIL + const char *modname; +#endif struct gcry_cipher_spec *next; } gcry_cipher_spec_t; @@ -161,6 +164,9 @@ typedef struct gcry_md_spec grub_size_t contextsize; /* allocate this amount of context */ /* Block size, needed for HMAC. */ grub_size_t blocksize; +#ifdef GRUB_UTIL + const char *modname; +#endif struct gcry_md_spec *next; } gcry_md_spec_t; diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index c7a794d68..2be24cc3f 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -36,5 +36,6 @@ grub_util_fd_sector_seek (int fd, const char *name, grub_disk_addr_t sector); ssize_t grub_util_fd_read (int fd, char *buf, size_t len); grub_err_t grub_luks_cheat_mount (const char *sourcedev, const char *cheat); +void grub_util_luks_print_ciphers (grub_disk_t disk); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/grub-probe.c b/util/grub-probe.c index 6c6220b8b..68d9b06f1 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -63,15 +64,28 @@ static void probe_partmap (grub_disk_t disk) { grub_partition_t part; + grub_disk_memberlist_t list = NULL, tmp; if (disk->partition == NULL) { grub_util_info ("no partition map found for %s", disk->name); - return; } for (part = disk->partition; part; part = part->parent) - printf ("%s\n", part->partmap->name); + printf ("%s ", part->partmap->name); + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->memberlist) + { + list = disk->dev->memberlist (disk); + } + while (list) + { + probe_partmap (list->disk); + tmp = list->next; + free (list); + list = tmp; + } } static int @@ -88,6 +102,45 @@ probe_raid_level (grub_disk_t disk) return ((struct grub_raid_array *) disk->data)->level; } +static void +probe_abstraction (grub_disk_t disk) +{ + grub_disk_memberlist_t list = NULL, tmp; + int raid_level; + + if (disk->dev->memberlist) + list = disk->dev->memberlist (disk); + while (list) + { + probe_abstraction (list->disk); + + tmp = list->next; + free (list); + list = tmp; + } + + if (disk->dev->id == GRUB_DISK_DEVICE_LVM_ID) + printf ("lvm "); + + if (disk->dev->id == GRUB_DISK_DEVICE_LUKS_ID) + { + printf ("luks "); + grub_util_luks_print_ciphers (disk); + } + + raid_level = probe_raid_level (disk); + if (raid_level >= 0) + { + printf ("raid "); + if (disk->dev->raidname) + printf ("%s ", disk->dev->raidname (disk)); + } + if (raid_level == 5) + printf ("raid5rec "); + if (raid_level == 6) + printf ("raid6rec "); +} + static void probe (const char *path, char *device_name) { @@ -136,91 +189,16 @@ probe (const char *path, char *device_name) if (print == PRINT_ABSTRACTION) { - grub_disk_memberlist_t list = NULL, tmp; - const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID); - int is_raid = 0; - int is_raid5 = 0; - int is_raid6 = 0; - int raid_level; - grub_disk_t raid_disk; - - raid_level = probe_raid_level (dev->disk); - if (raid_level >= 0) - { - is_raid = 1; - is_raid5 |= (raid_level == 5); - is_raid6 |= (raid_level == 6); - raid_disk = dev->disk; - } - - if ((is_lvm) && (dev->disk->dev->memberlist)) - list = dev->disk->dev->memberlist (dev->disk); - while (list) - { - raid_level = probe_raid_level (list->disk); - if (raid_level >= 0) - { - is_raid = 1; - is_raid5 |= (raid_level == 5); - is_raid6 |= (raid_level == 6); - raid_disk = list->disk; - } - - tmp = list->next; - free (list); - list = tmp; - } - - if (is_raid) - { - printf ("raid "); - if (is_raid5) - printf ("raid5rec "); - if (is_raid6) - printf ("raid6rec "); - if (raid_disk->dev->raidname) - printf ("%s ", raid_disk->dev->raidname (raid_disk)); - } - - if (is_lvm) - printf ("lvm "); - + probe_abstraction (dev->disk); printf ("\n"); - goto end; } if (print == PRINT_PARTMAP) { - grub_disk_memberlist_t list = NULL, tmp; - /* Check if dev->disk itself is contained in a partmap. */ probe_partmap (dev->disk); - - /* In case of LVM/RAID, check the member devices as well. */ - if (dev->disk->dev->memberlist) - list = dev->disk->dev->memberlist (dev->disk); - while (list) - { - probe_partmap (list->disk); - /* LVM on RAID */ - if (list->disk->dev->memberlist) - { - grub_disk_memberlist_t sub_list; - - sub_list = list->disk->dev->memberlist (list->disk); - while (sub_list) - { - probe_partmap (sub_list->disk); - tmp = sub_list->next; - free (sub_list); - sub_list = tmp; - } - } - tmp = list->next; - free (list); - list = tmp; - } + printf ("\n"); goto end; } diff --git a/util/import_gcry.py b/util/import_gcry.py index 3a110f028..0ebfd1f56 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -111,6 +111,7 @@ for cipher_file in cipher_files: skip = False skip2 = False ismd = False + iscipher = False iscryptostart = False iscomma = False isglue = False @@ -140,15 +141,22 @@ for cipher_file in cipher_files: sg = s.groups()[0] cryptolist.write (("%s: %s\n") % (sg, modname)) iscryptostart = False - if ismd: + if ismd or iscipher: if not re.search (" *};", line) is None: - if not mdblocksizes.has_key (mdname): - print ("ERROR: Unknown digest blocksize: %s\n" % mdname) - exit (1) if not iscomma: fw.write (" ,\n") - fw.write (" .blocksize = %s\n" % mdblocksizes [mdname]) + fw.write ("#ifdef GRUB_UTIL\n"); + fw.write (" .modname = \"%s\",\n" % modname); + fw.write ("#endif\n"); + if ismd: + if not mdblocksizes.has_key (mdname): + print ("ERROR: Unknown digest blocksize: %s\n" + % mdname) + exit (1) + fw.write (" .blocksize = %s\n" + % mdblocksizes [mdname]) ismd = False + iscipher = False iscomma = not re.search (",$", line) is None # Used only for selftests. m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line) @@ -189,14 +197,18 @@ for cipher_file in cipher_files: continue m = re.match ("gcry_cipher_spec_t", line) if isc and not m is None: + assert (not iscryptostart) + assert (not iscipher) assert (not iscryptostart) ciphername = line [len ("gcry_cipher_spec_t"):].strip () ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group () ciphernames.append (ciphername) + iscipher = True iscryptostart = True m = re.match ("gcry_md_spec_t", line) if isc and not m is None: assert (not ismd) + assert (not iscipher) assert (not iscryptostart) mdname = line [len ("gcry_md_spec_t"):].strip () mdname = re.match("[a-zA-Z0-9_]*",mdname).group () From 9d647e4e181b0f88b5107b3f00e4f7d3bb9a1686 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 23:51:16 +0200 Subject: [PATCH 0912/1414] New -t luks_uuid --- grub-core/disk/luks.c | 7 +++++++ include/grub/emu/hostdisk.h | 1 + util/grub-probe.c | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index ce1f1bfc6..997e2eb30 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -893,6 +893,13 @@ grub_util_luks_print_ciphers (grub_disk_t disk) if (dev->essiv_hash) grub_printf ("%s ", dev->essiv_hash->modname); } + +void +grub_util_luks_print_uuid (grub_disk_t disk) +{ + grub_luks_t dev = (grub_luks_t) disk->data; + grub_printf ("%s ", dev->uuid); +} #endif static void diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 2be24cc3f..7541308e6 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -37,5 +37,6 @@ ssize_t grub_util_fd_read (int fd, char *buf, size_t len); grub_err_t grub_luks_cheat_mount (const char *sourcedev, const char *cheat); void grub_util_luks_print_ciphers (grub_disk_t disk); +void grub_util_luks_print_uuid (grub_disk_t disk); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/grub-probe.c b/util/grub-probe.c index 68d9b06f1..21fc21b02 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -55,6 +55,7 @@ enum { PRINT_DEVICE, PRINT_PARTMAP, PRINT_ABSTRACTION, + PRINT_LUKS_UUID }; int print = PRINT_FS; @@ -88,6 +89,27 @@ probe_partmap (grub_disk_t disk) } } +static void +probe_luks_uuid (grub_disk_t disk) +{ + grub_disk_memberlist_t list = NULL, tmp; + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->memberlist) + { + list = disk->dev->memberlist (disk); + } + while (list) + { + probe_luks_uuid (list->disk); + tmp = list->next; + free (list); + list = tmp; + } + if (disk->dev->id == GRUB_DISK_DEVICE_LUKS_ID) + grub_util_luks_print_uuid (disk); +} + static int probe_raid_level (grub_disk_t disk) { @@ -194,6 +216,13 @@ probe (const char *path, char *device_name) goto end; } + if (print == PRINT_LUKS_UUID) + { + probe_luks_uuid (dev->disk); + printf ("\n"); + goto end; + } + if (print == PRINT_PARTMAP) { /* Check if dev->disk itself is contained in a partmap. */ @@ -267,8 +296,8 @@ Probe device information for a given path (or device, if the -d option is given) \n\ -d, --device given argument is a system device, not a path\n\ -m, --device-map=FILE use FILE as the device map [default=%s]\n\ - -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction)\n\ - print filesystem module, GRUB drive, system device, partition map module or abstraction module [default=fs]\n\ + -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|luks_uuid)\n\ + print filesystem module, GRUB drive, system device, partition map module, abstraction module or LUKS UUID [default=fs]\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ @@ -326,6 +355,8 @@ main (int argc, char *argv[]) print = PRINT_PARTMAP; else if (!strcmp (optarg, "abstraction")) print = PRINT_ABSTRACTION; + else if (!strcmp (optarg, "luks_uuid")) + print = PRINT_LUKS_UUID; else usage (1); break; From 8306591ff30a94c5f9dfcaa4ee02a06a8c0021a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 00:13:56 +0200 Subject: [PATCH 0913/1414] support LUKS in shell libraries --- util/grub-install.in | 8 ++++++++ util/grub-mkconfig.in | 1 + util/grub-mkconfig_lib.in | 20 +++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/util/grub-install.in b/util/grub-install.in index ff8bea87c..3b3383ab4 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -456,6 +456,8 @@ for dir in "${localedir}"/*; do fi done +is_path_readable_by_grub "${grubdir}" || (echo "${grubdir}" not readable 1>&2 ; exit 1) + # Write device to a variable so we don't have to traverse /dev every time. grub_device="`"$grub_probe" --device-map="${device_map}" --target=device "${grubdir}"`" || exit 1 @@ -536,6 +538,12 @@ if [ "x${devabstraction_module}" = "x" ] ; then exit 1 fi + if [ x$GRUB_LUKS_ENABLE = xy ]; then + for uuid in "`"${grub_probe}" --device "${device}" --target=luks_uuid`"; do + echo "luksmount -u $uuid" + done + fi + echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg" echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index afc66f886..41e68bc1b 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -254,6 +254,7 @@ export GRUB_DEFAULT \ GRUB_DISABLE_OS_PROBER \ GRUB_INIT_TUNE \ GRUB_SAVEDEFAULT \ + GRUB_ENABLE_LUKS \ GRUB_BADRAM if test "x${grub_cfg}" != "x"; then diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 2c5fd8c6f..1664b6bbe 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -63,10 +63,22 @@ is_path_readable_by_grub () # ... or if we can't figure out the abstraction module, for example if # memberlist fails on an LVM volume group. - if ${grub_probe} -t abstraction $path > /dev/null 2>&1 ; then : ; else + if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2>&1 ; then + : + else return 1 fi + if [ x$GRUB_LUKS_ENABLE = xy ]; then + return 0 + fi + + for abstraction in $abstractions; do + if [ "x$abstraction" = xluks ]; then + return 1 + fi + done + return 0 } @@ -126,6 +138,12 @@ prepare_grub_to_access_device () echo "insmod ${module}" done + if [ x$GRUB_LUKS_ENABLE = xy ]; then + for uuid in "`"${grub_probe}" --device "${device}" --target=luks_uuid`"; do + echo "luksmount -u $uuid" + done + fi + # If there's a filesystem UUID that GRUB is capable of identifying, use it; # otherwise set root as per value in device.map. echo "set root='`"${grub_probe}" --device "${device}" --target=drive`'" From 4879d87871dceba99558c7911cc15b9ddee4b4bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 02:01:39 +0200 Subject: [PATCH 0914/1414] fix bug caused by import_gcry modifications --- util/import_gcry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/import_gcry.py b/util/import_gcry.py index 0ebfd1f56..727492f10 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -153,8 +153,8 @@ for cipher_file in cipher_files: print ("ERROR: Unknown digest blocksize: %s\n" % mdname) exit (1) - fw.write (" .blocksize = %s\n" - % mdblocksizes [mdname]) + fw.write (" .blocksize = %s\n" + % mdblocksizes [mdname]) ismd = False iscipher = False iscomma = not re.search (",$", line) is None From 95172af9fa30d41b6f37e32ee9e0e79a2e10930d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 02:04:40 +0200 Subject: [PATCH 0915/1414] Better IV modes support --- grub-core/disk/luks.c | 266 ++++++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 115 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 997e2eb30..8f8b8dbe4 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -70,12 +70,20 @@ struct grub_luks_phdr typedef struct grub_luks_phdr *grub_luks_phdr_t; typedef enum -{ - GRUB_LUKS_MODE_ECB, - GRUB_LUKS_MODE_CBC_PLAIN, - GRUB_LUKS_MODE_CBC_ESSIV, - GRUB_LUKS_MODE_XTS -} luks_mode_t; + { + GRUB_LUKS_MODE_ECB, + GRUB_LUKS_MODE_CBC, + GRUB_LUKS_MODE_XTS + } luks_mode_t; + +typedef enum + { + GRUB_LUKS_MODE_IV_NULL, + GRUB_LUKS_MODE_IV_PLAIN, + GRUB_LUKS_MODE_IV_PLAIN64, + GRUB_LUKS_MODE_IV_ESSIV, + GRUB_LUKS_MODE_IV_BENBI, + } luks_mode_iv_t; struct grub_luks { @@ -85,8 +93,10 @@ struct grub_luks int ref; grub_crypto_cipher_handle_t cipher; grub_crypto_cipher_handle_t secondary_cipher; + grub_crypto_cipher_handle_t essiv_cipher; const gcry_md_spec_t *essiv_hash, *hash; luks_mode_t mode; + luks_mode_iv_t mode_iv; unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; @@ -112,13 +122,6 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -static inline void -make_iv (grub_uint32_t *iv, grub_size_t sz, grub_disk_addr_t sector) -{ - grub_memset (iv, 0, sz * sizeof (iv[0])); - iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); -} - /* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ #define POLYNOM 0x87 @@ -141,89 +144,83 @@ gf_mul_x (grub_uint8_t *g) static gcry_err_code_t luks_decrypt (const struct grub_luks *dev, - grub_uint8_t * data, grub_size_t len, grub_size_t sector) + grub_uint8_t * data, grub_size_t len, grub_disk_addr_t sector) { grub_size_t i; gcry_err_code_t err; - switch (dev->mode) + /* The only mode without IV. */ + if (dev->mode == GRUB_LUKS_MODE_ECB) + return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); + + for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) { - case GRUB_LUKS_MODE_ECB: - return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); + grub_size_t sz = ((dev->cipher->cipher->blocksize + + sizeof (grub_uint32_t) - 1) + / sizeof (grub_uint32_t)); + grub_uint32_t iv[sz]; - case GRUB_LUKS_MODE_CBC_PLAIN: - for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) + grub_memset (iv, 0, sz * sizeof (iv[0])); + switch (dev->mode_iv) { - grub_size_t sz = ((dev->cipher->cipher->blocksize - + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)); - grub_uint32_t iv[sz]; - make_iv (iv, sz, sector); + case GRUB_LUKS_MODE_IV_NULL: + break; + case GRUB_LUKS_MODE_IV_PLAIN64: + iv[1] = grub_cpu_to_le32 (sector >> 32); + case GRUB_LUKS_MODE_IV_PLAIN: + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + break; + case GRUB_LUKS_MODE_IV_BENBI: + iv[sz - 2] = grub_cpu_to_be32 (sector >> 32); + iv[sz - 1] = grub_cpu_to_be32 (sector & 0xFFFFFFFF); + break; + case GRUB_LUKS_MODE_IV_ESSIV: + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv, + dev->cipher->cipher->blocksize); + if (err) + return err; + } + + switch (dev->mode) + { + case GRUB_LUKS_MODE_CBC: err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, GRUB_DISK_SECTOR_SIZE, iv); if (err) return err; - sector++; + break; + + case GRUB_LUKS_MODE_XTS: + { + int j; + err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, + dev->cipher->cipher->blocksize); + if (err) + return err; + + for (j = 0; j < GRUB_DISK_SECTOR_SIZE; + j += dev->cipher->cipher->blocksize) + { + grub_crypto_xor (data + i + j, data + i + j, iv, + dev->cipher->cipher->blocksize); + err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, + data + i + j, + dev->cipher->cipher->blocksize); + if (err) + return err; + grub_crypto_xor (data + i + j, data + i + j, iv, + dev->cipher->cipher->blocksize); + gf_mul_x ((grub_uint8_t *) iv); + } + } + break; + default: + return GPG_ERR_NOT_IMPLEMENTED; } - return GPG_ERR_NO_ERROR; - - case GRUB_LUKS_MODE_CBC_ESSIV: - for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) - { - grub_size_t sz = ((dev->cipher->cipher->blocksize - + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)); - grub_uint32_t iv[sz]; - make_iv (iv, sz, sector); - - err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, - dev->cipher->cipher->blocksize); - if (err) - return err; - err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, - GRUB_DISK_SECTOR_SIZE, iv); - if (err) - return err; - sector++; - } - return GPG_ERR_NO_ERROR; - - case GRUB_LUKS_MODE_XTS: - for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) - { - grub_size_t sz = ((dev->cipher->cipher->blocksize - + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)); - grub_uint32_t iv[sz]; - int j; - make_iv (iv, sz, sector); - - err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, - dev->cipher->cipher->blocksize); - if (err) - return err; - - for (j = 0; j < GRUB_DISK_SECTOR_SIZE; - j += dev->cipher->cipher->blocksize) - { - grub_crypto_xor (data + i + j, data + i + j, iv, - dev->cipher->cipher->blocksize); - err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, - data + i + j, - dev->cipher->cipher->blocksize); - if (err) - return err; - grub_crypto_xor (data + i + j, data + i + j, iv, - dev->cipher->cipher->blocksize); - gf_mul_x ((grub_uint8_t *) iv); - } - sector++; - } - return GPG_ERR_NO_ERROR; - - default: - return GPG_ERR_NOT_IMPLEMENTED; + sector++; } + return GPG_ERR_NO_ERROR; } static int check_uuid, have_it; @@ -238,11 +235,14 @@ configure_ciphers (const struct grub_luks_phdr *header) char uuid[sizeof (header->uuid) + 1]; char ciphername[sizeof (header->cipherName) + 1]; char ciphermode[sizeof (header->cipherMode) + 1]; + char *cipheriv = NULL; char hashspec[sizeof (header->hashSpec) + 1]; grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; + grub_crypto_cipher_handle_t essiv_cipher = NULL; const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; const struct gcry_cipher_spec *ciph; luks_mode_t mode; + luks_mode_iv_t mode_iv; /* Look for LUKS magic sequence. */ if (grub_memcmp (header->magic, LUKS_MAGIC, sizeof (header->magic)) @@ -294,35 +294,26 @@ configure_ciphers (const struct grub_luks_phdr *header) /* Configure the cipher mode. */ if (grub_strcmp (ciphermode, "ecb") == 0) - mode = GRUB_LUKS_MODE_ECB; - else if (grub_strcmp (ciphermode, "cbc-plain") == 0 - || grub_strcmp (ciphermode, "plain") == 0) - mode = GRUB_LUKS_MODE_CBC_PLAIN; - else if (grub_memcmp (ciphermode, "cbc-essiv:", sizeof ("cbc-essiv:") - 1) - == 0) { - mode = GRUB_LUKS_MODE_CBC_ESSIV; - char *hash_str = ciphermode + 10; - - /* Configure the hash and cipher used for ESSIV. */ - essiv_hash = grub_crypto_lookup_md_by_name (hash_str); - if (!essiv_hash) - { - grub_crypto_cipher_close (cipher); - grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load %s hash", hash_str); - return NULL; - } - secondary_cipher = grub_crypto_cipher_open (ciph); - if (!secondary_cipher) - { - grub_crypto_cipher_close (cipher); - return NULL; - } + mode = GRUB_LUKS_MODE_ECB; + mode_iv = GRUB_LUKS_MODE_IV_PLAIN; + cipheriv = NULL; } - else if (grub_strcmp (ciphermode, "xts-plain") == 0) + else if (grub_strcmp (ciphermode, "plain") == 0) + { + mode = GRUB_LUKS_MODE_CBC; + mode_iv = GRUB_LUKS_MODE_IV_PLAIN; + cipheriv = NULL; + } + else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0) + { + mode = GRUB_LUKS_MODE_CBC; + cipheriv = ciphermode + sizeof ("cbc-") - 1; + } + else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0) { mode = GRUB_LUKS_MODE_XTS; + cipheriv = ciphermode + sizeof ("xts-") - 1; secondary_cipher = grub_crypto_cipher_open (ciph); if (!secondary_cipher) { @@ -350,11 +341,51 @@ configure_ciphers (const struct grub_luks_phdr *header) return NULL; } + if (cipheriv == NULL); + else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0) + mode_iv = GRUB_LUKS_MODE_IV_PLAIN; + else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) + mode_iv = GRUB_LUKS_MODE_IV_PLAIN64; + else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0) + mode_iv = GRUB_LUKS_MODE_IV_BENBI; + else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0) + mode_iv = GRUB_LUKS_MODE_IV_NULL; + else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0) + { + char *hash_str = cipheriv + 6; + + mode_iv = GRUB_LUKS_MODE_IV_ESSIV; + + /* Configure the hash and cipher used for ESSIV. */ + essiv_hash = grub_crypto_lookup_md_by_name (hash_str); + if (!essiv_hash) + { + grub_crypto_cipher_close (cipher); + grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load %s hash", hash_str); + return NULL; + } + essiv_cipher = grub_crypto_cipher_open (ciph); + if (!essiv_cipher) + { + grub_crypto_cipher_close (cipher); + return NULL; + } + } + else + { + grub_crypto_cipher_close (cipher); + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s", + cipheriv); + return NULL; + } + /* Configure the hash used for the AF splitter and HMAC. */ hash = grub_crypto_lookup_md_by_name (hashspec); if (!hash) { grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (essiv_cipher); grub_crypto_cipher_close (secondary_cipher); grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", hashspec); @@ -368,7 +399,9 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->offset = grub_be_to_cpu32 (header->payloadOffset); newdev->source_disk = NULL; newdev->mode = mode; + newdev->mode_iv = mode_iv; newdev->secondary_cipher = secondary_cipher; + newdev->essiv_cipher = essiv_cipher; newdev->essiv_hash = essiv_hash; newdev->hash = hash; newdev->id = n++; @@ -392,7 +425,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_size_t length; grub_err_t err; - if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) + if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) { essiv_keysize = dev->essiv_hash->mdlen; hashed_key = grub_malloc (dev->essiv_hash->mdlen); @@ -433,8 +466,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, grub_strlen (passphrase), header->keyblock[i].passwordSalt, - sizeof (header-> - keyblock[i].passwordSalt), + sizeof (header->keyblock[i].passwordSalt), grub_be_to_cpu32 (header->keyblock[i]. passwordIterations), digest, keysize); @@ -460,10 +492,10 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, } /* Configure ESSIV if necessary. */ - if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) + if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) { grub_crypto_hash (dev->essiv_hash, hashed_key, digest, keysize); - gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, + gcry_err = grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, essiv_keysize); if (gcry_err) @@ -562,12 +594,12 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, } /* Configure ESSIV if necessary. */ - if (dev->mode == GRUB_LUKS_MODE_CBC_ESSIV) + if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) { grub_crypto_hash (dev->essiv_hash, hashed_key, candidate_key, keysize); gcry_err = - grub_crypto_cipher_set_key (dev->secondary_cipher, hashed_key, + grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, essiv_keysize); if (gcry_err) { @@ -604,6 +636,7 @@ luks_close (grub_luks_t luks) { grub_crypto_cipher_close (luks->cipher); grub_crypto_cipher_close (luks->secondary_cipher); + grub_crypto_cipher_close (luks->essiv_cipher); grub_free (luks); } @@ -888,6 +921,8 @@ grub_util_luks_print_ciphers (grub_disk_t disk) grub_printf ("%s ", dev->cipher->cipher->modname); if (dev->secondary_cipher) grub_printf ("%s ", dev->secondary_cipher->cipher->modname); + if (dev->essiv_cipher) + grub_printf ("%s ", dev->essiv_cipher->cipher->modname); if (dev->hash) grub_printf ("%s ", dev->hash->modname); if (dev->essiv_hash) @@ -913,6 +948,7 @@ luks_cleanup (void) grub_free (dev->source); grub_free (dev->cipher); grub_free (dev->secondary_cipher); + grub_free (dev->essiv_cipher); tmp = dev->next; grub_free (dev); dev = tmp; From ed38c849f4bc6b193431360dd21424c013b594fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 02:27:45 +0200 Subject: [PATCH 0916/1414] pcbc support --- grub-core/disk/luks.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 8f8b8dbe4..ac3b81e99 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -73,6 +73,7 @@ typedef enum { GRUB_LUKS_MODE_ECB, GRUB_LUKS_MODE_CBC, + GRUB_LUKS_MODE_PCBC, GRUB_LUKS_MODE_XTS } luks_mode_t; @@ -142,6 +143,29 @@ gf_mul_x (grub_uint8_t *g) g[0] ^= POLYNOM; } +static gcry_err_code_t +grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher, + void *out, void *in, grub_size_t size, + void *iv) +{ + grub_uint8_t *inptr, *outptr, *end; + grub_uint8_t ivt[cipher->cipher->blocksize]; + if (!cipher->cipher->decrypt) + return GPG_ERR_NOT_SUPPORTED; + if (size % cipher->cipher->blocksize != 0) + return GPG_ERR_INV_ARG; + end = (grub_uint8_t *) in + size; + for (inptr = in, outptr = out; inptr < end; + inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize) + { + grub_memcpy (ivt, inptr, cipher->cipher->blocksize); + cipher->cipher->decrypt (cipher->ctx, outptr, inptr); + grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize); + grub_crypto_xor (iv, ivt, outptr, cipher->cipher->blocksize); + } + return GPG_ERR_NO_ERROR; +} + static gcry_err_code_t luks_decrypt (const struct grub_luks *dev, grub_uint8_t * data, grub_size_t len, grub_disk_addr_t sector) @@ -191,6 +215,12 @@ luks_decrypt (const struct grub_luks *dev, return err; break; + case GRUB_LUKS_MODE_PCBC: + err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, + GRUB_DISK_SECTOR_SIZE, iv); + if (err) + return err; + break; case GRUB_LUKS_MODE_XTS: { int j; @@ -310,6 +340,11 @@ configure_ciphers (const struct grub_luks_phdr *header) mode = GRUB_LUKS_MODE_CBC; cipheriv = ciphermode + sizeof ("cbc-") - 1; } + else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0) + { + mode = GRUB_LUKS_MODE_PCBC; + cipheriv = ciphermode + sizeof ("pcbc-") - 1; + } else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0) { mode = GRUB_LUKS_MODE_XTS; From 4b35060f6fd84a6fc5fb19974098d66e16a44964 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 03:18:07 +0200 Subject: [PATCH 0917/1414] Fix benbi --- grub-core/disk/luks.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index ac3b81e99..8af087eea 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -98,6 +98,7 @@ struct grub_luks const gcry_md_spec_t *essiv_hash, *hash; luks_mode_t mode; luks_mode_iv_t mode_iv; + int benbi_log; unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; @@ -195,8 +196,11 @@ luks_decrypt (const struct grub_luks *dev, iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); break; case GRUB_LUKS_MODE_IV_BENBI: - iv[sz - 2] = grub_cpu_to_be32 (sector >> 32); - iv[sz - 1] = grub_cpu_to_be32 (sector & 0xFFFFFFFF); + { + grub_uint64_t num = (sector << dev->benbi_log) + 1; + iv[sz - 2] = grub_cpu_to_be32 (num >> 32); + iv[sz - 1] = grub_cpu_to_be32 (num & 0xFFFFFFFF); + } break; case GRUB_LUKS_MODE_IV_ESSIV: iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); @@ -273,7 +277,8 @@ configure_ciphers (const struct grub_luks_phdr *header) const struct gcry_cipher_spec *ciph; luks_mode_t mode; luks_mode_iv_t mode_iv; - + int benbi_log = 0; + /* Look for LUKS magic sequence. */ if (grub_memcmp (header->magic, LUKS_MAGIC, sizeof (header->magic)) || grub_be_to_cpu16 (header->version) != 1) @@ -382,7 +387,16 @@ configure_ciphers (const struct grub_luks_phdr *header) else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) mode_iv = GRUB_LUKS_MODE_IV_PLAIN64; else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0) + { + if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1) + || cipher->cipher->blocksize == 0) + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d", + cipher->cipher->blocksize); + for (benbi_log = 0; + (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE; + benbi_log++); mode_iv = GRUB_LUKS_MODE_IV_BENBI; + } else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0) mode_iv = GRUB_LUKS_MODE_IV_NULL; else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0) @@ -433,6 +447,7 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->cipher = cipher; newdev->offset = grub_be_to_cpu32 (header->payloadOffset); newdev->source_disk = NULL; + newdev->benbi_log = benbi_log; newdev->mode = mode; newdev->mode_iv = mode_iv; newdev->secondary_cipher = secondary_cipher; From 2f179c3236573a4aca5816aac4b3bb5ed16f8268 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 04:51:53 +0200 Subject: [PATCH 0918/1414] LRW support --- grub-core/disk/luks.c | 120 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 105 insertions(+), 15 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 8af087eea..775a10f20 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -74,7 +74,8 @@ typedef enum GRUB_LUKS_MODE_ECB, GRUB_LUKS_MODE_CBC, GRUB_LUKS_MODE_PCBC, - GRUB_LUKS_MODE_XTS + GRUB_LUKS_MODE_XTS, + GRUB_LUKS_MODE_LRW } luks_mode_t; typedef enum @@ -86,6 +87,10 @@ typedef enum GRUB_LUKS_MODE_IV_BENBI, } luks_mode_iv_t; +/* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ +#define GF_POLYNOM 0x87 +#define GF_SIZE 128 + struct grub_luks { char *source; @@ -102,6 +107,7 @@ struct grub_luks unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; + grub_uint8_t lrw_key[GF_SIZE / 8]; #ifdef GRUB_UTIL char *cheat; int cheat_fd; @@ -124,16 +130,13 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -/* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ -#define POLYNOM 0x87 - static void gf_mul_x (grub_uint8_t *g) { int over = 0, over2 = 0; int j; - for (j = 0; j < 16; j++) + for (j = 0; j < GF_SIZE / 8; j++) { over2 = !!(g[j] & 0x80); g[j] <<= 1; @@ -141,7 +144,40 @@ gf_mul_x (grub_uint8_t *g) over = over2; } if (over) - g[0] ^= POLYNOM; + g[0] ^= GF_POLYNOM; +} + + +static void +gf_mul_x_be (grub_uint8_t *g) +{ + int over = 0, over2 = 0; + int j; + + for (j = GF_SIZE / 8 - 1; j >= 0; j--) + { + over2 = !!(g[j] & 0x80); + g[j] <<= 1; + g[j] |= over; + over = over2; + } + if (over) + g[GF_SIZE / 8 - 1] ^= GF_POLYNOM; +} + +static void +gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) +{ + int i; + grub_uint8_t t[GF_SIZE / 8]; + grub_memset (o, 0, GF_SIZE / 8); + grub_memcpy (t, b, GF_SIZE / 8); + for (i = 0; i < GF_SIZE; i++) + { + if (((a[GF_SIZE / 8 - i / 8 - 1] >> (i % 8))) & 1) + grub_crypto_xor (o, o, t, GF_SIZE / 8); + gf_mul_x_be (t); + } } static gcry_err_code_t @@ -249,6 +285,34 @@ luks_decrypt (const struct grub_luks *dev, } } break; + case GRUB_LUKS_MODE_LRW: + { + int j, k; + for (j = 0; + j < GRUB_DISK_SECTOR_SIZE; + j += dev->cipher->cipher->blocksize) + { + grub_uint8_t x[sz * sizeof (grub_uint32_t)]; + + gf_mul_be (x, dev->lrw_key, (grub_uint8_t *) iv); + grub_crypto_xor (data + i + j, data + i + j, x, + dev->cipher->cipher->blocksize); + err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, + data + i + j, + dev->cipher->cipher->blocksize); + if (err) + return err; + grub_crypto_xor (data + i + j, data + i + j, x, + dev->cipher->cipher->blocksize); + for (k = sz - 1; k >= 0; k++) + { + iv[k] = grub_cpu_to_be32 (grub_be_to_cpu32 (iv[k]) + 1); + if (iv[k] != 0) + break; + } + } + } + break; default: return GPG_ERR_NOT_IMPLEMENTED; } @@ -360,19 +424,33 @@ configure_ciphers (const struct grub_luks_phdr *header) grub_crypto_cipher_close (cipher); return NULL; } - if (cipher->cipher->blocksize != 16) + if (cipher->cipher->blocksize != GF_SIZE / 8) { + grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", cipher->cipher->blocksize); return NULL; } - if (secondary_cipher->cipher->blocksize != 16) + if (secondary_cipher->cipher->blocksize != GF_SIZE / 8) { + grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", secondary_cipher->cipher->blocksize); return NULL; } } + else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0) + { + mode = GRUB_LUKS_MODE_LRW; + cipheriv = ciphermode + sizeof ("lrw-") - 1; + if (cipher->cipher->blocksize != GF_SIZE / 8) + { + grub_crypto_cipher_close (cipher); + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d", + cipher->cipher->blocksize); + return NULL; + } + } else { grub_crypto_cipher_close (cipher); @@ -505,6 +583,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, for (i = 0; i < ARRAY_SIZE (header->keyblock); i++) { gcry_err_code_t gcry_err; + int real_keysize; /* Check if keyslot is enabled. */ if (grub_be_to_cpu32 (header->keyblock[i].active) != LUKS_KEY_ENABLED) @@ -530,10 +609,14 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_dprintf ("luks", "PBKDF2 done\n"); + real_keysize = keysize; + if (dev->mode == GRUB_LUKS_MODE_XTS) + real_keysize /= 2; + if (dev->mode == GRUB_LUKS_MODE_LRW) + real_keysize -= dev->cipher->cipher->blocksize; + /* Set the PBKDF2 output as the cipher key. */ - gcry_err = grub_crypto_cipher_set_key (dev->cipher, digest, - (dev->mode == GRUB_LUKS_MODE_XTS) - ? (keysize / 2) : keysize); + gcry_err = grub_crypto_cipher_set_key (dev->cipher, digest, real_keysize); if (gcry_err) { grub_free (hashed_key); @@ -559,7 +642,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, if (dev->mode == GRUB_LUKS_MODE_XTS) { gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, - digest + (keysize / 2), + digest + real_keysize, keysize / 2); if (gcry_err) { @@ -569,6 +652,10 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, } } + if (dev->mode == GRUB_LUKS_MODE_LRW) + grub_memcpy (dev->lrw_key, digest + real_keysize, + dev->cipher->cipher->blocksize); + length = grub_be_to_cpu32 (header->keyBytes) * grub_be_to_cpu32 (header->keyblock[i].stripes); @@ -634,8 +721,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, /* Set the master key. */ gcry_err = grub_crypto_cipher_set_key (dev->cipher, candidate_key, - (dev->mode == GRUB_LUKS_MODE_XTS) - ? (keysize / 2) : keysize); + real_keysize); if (gcry_err) { grub_free (hashed_key); @@ -662,7 +748,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, if (dev->mode == GRUB_LUKS_MODE_XTS) { gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, - candidate_key + (keysize / 2), + candidate_key + real_keysize, keysize / 2); if (gcry_err) { @@ -672,6 +758,10 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, } } + if (dev->mode == GRUB_LUKS_MODE_LRW) + grub_memcpy (dev->lrw_key, candidate_key + real_keysize, + dev->cipher->cipher->blocksize); + grub_free (split_key); grub_free (hashed_key); From 6fd80b9ac45df8a5b417f1a215e8cd428ebe8b82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 12:40:43 +0200 Subject: [PATCH 0919/1414] factor luks_set_key out --- grub-core/disk/luks.c | 151 ++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 102 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 775a10f20..b1c738f2a 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -537,6 +537,50 @@ configure_ciphers (const struct grub_luks_phdr *header) return newdev; } +static gcry_err_code_t +luks_setkey (grub_luks_t dev, grub_uint8_t *key, grub_size_t keysize) +{ + gcry_err_code_t err; + int real_keysize; + + real_keysize = keysize; + if (dev->mode == GRUB_LUKS_MODE_XTS) + real_keysize /= 2; + if (dev->mode == GRUB_LUKS_MODE_LRW) + real_keysize -= dev->cipher->cipher->blocksize; + + /* Set the PBKDF2 output as the cipher key. */ + err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize); + if (err) + return err; + + /* Configure ESSIV if necessary. */ + if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) + { + grub_size_t essiv_keysize = dev->essiv_hash->mdlen; + grub_uint8_t hashed_key[essiv_keysize]; + + grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize); + err = grub_crypto_cipher_set_key (dev->essiv_cipher, + hashed_key, essiv_keysize); + if (err) + return err; + } + if (dev->mode == GRUB_LUKS_MODE_XTS) + { + err = grub_crypto_cipher_set_key (dev->secondary_cipher, + key + real_keysize, + keysize / 2); + if (err) + return err; + } + + if (dev->mode == GRUB_LUKS_MODE_LRW) + grub_memcpy (dev->lrw_key, key + real_keysize, + dev->cipher->cipher->blocksize); + return GPG_ERR_NO_ERROR; +} + static grub_err_t luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, const char *name, grub_disk_t source) @@ -544,37 +588,23 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_size_t keysize = grub_be_to_cpu32 (header->keyBytes); grub_uint8_t candidate_key[keysize]; grub_uint8_t digest[keysize]; - grub_uint8_t *hashed_key = NULL; grub_uint8_t *split_key = NULL; char passphrase[MAX_PASSPHRASE] = ""; grub_uint8_t candidate_digest[sizeof (header->mkDigest)]; unsigned i; - grub_size_t essiv_keysize = 0; grub_size_t length; grub_err_t err; - if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) - { - essiv_keysize = dev->essiv_hash->mdlen; - hashed_key = grub_malloc (dev->essiv_hash->mdlen); - if (!hashed_key) - return grub_errno; - } - grub_printf ("Attempting to decrypt master key...\n"); split_key = grub_malloc (keysize * LUKS_STRIPES); if (!split_key) - { - grub_free (hashed_key); - return grub_errno; - } + return grub_errno; /* Get the passphrase from the user. */ grub_printf ("Enter passphrase for %s (%s): ", name, dev->uuid); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) { - grub_free (hashed_key); grub_free (split_key); return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); } @@ -583,7 +613,6 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, for (i = 0; i < ARRAY_SIZE (header->keyblock); i++) { gcry_err_code_t gcry_err; - int real_keysize; /* Check if keyslot is enabled. */ if (grub_be_to_cpu32 (header->keyblock[i].active) != LUKS_KEY_ENABLED) @@ -602,63 +631,21 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, if (gcry_err) { - grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } grub_dprintf ("luks", "PBKDF2 done\n"); - real_keysize = keysize; - if (dev->mode == GRUB_LUKS_MODE_XTS) - real_keysize /= 2; - if (dev->mode == GRUB_LUKS_MODE_LRW) - real_keysize -= dev->cipher->cipher->blocksize; - - /* Set the PBKDF2 output as the cipher key. */ - gcry_err = grub_crypto_cipher_set_key (dev->cipher, digest, real_keysize); + gcry_err = luks_setkey (dev, digest, keysize); if (gcry_err) { - grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } - /* Configure ESSIV if necessary. */ - if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) - { - grub_crypto_hash (dev->essiv_hash, hashed_key, digest, keysize); - gcry_err = grub_crypto_cipher_set_key (dev->essiv_cipher, - hashed_key, - essiv_keysize); - if (gcry_err) - { - grub_free (hashed_key); - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - } - - if (dev->mode == GRUB_LUKS_MODE_XTS) - { - gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, - digest + real_keysize, - keysize / 2); - if (gcry_err) - { - grub_free (hashed_key); - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - } - - if (dev->mode == GRUB_LUKS_MODE_LRW) - grub_memcpy (dev->lrw_key, digest + real_keysize, - dev->cipher->cipher->blocksize); - - length = - grub_be_to_cpu32 (header->keyBytes) * - grub_be_to_cpu32 (header->keyblock[i].stripes); + length = (grub_be_to_cpu32 (header->keyBytes) + * grub_be_to_cpu32 (header->keyblock[i].stripes)); /* Read and decrypt the key material from the disk. */ err = grub_disk_read (source, @@ -667,7 +654,6 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, length, split_key); if (err) { - grub_free (hashed_key); grub_free (split_key); return err; } @@ -675,7 +661,6 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, gcry_err = luks_decrypt (dev, split_key, length, 0); if (gcry_err) { - grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } @@ -685,7 +670,6 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_be_to_cpu32 (header->keyblock[i].stripes)); if (gcry_err) { - grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } @@ -703,7 +687,6 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, sizeof (candidate_digest)); if (gcry_err) { - grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } @@ -720,50 +703,14 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_printf ("Slot %d opened\n", i); /* Set the master key. */ - gcry_err = grub_crypto_cipher_set_key (dev->cipher, candidate_key, - real_keysize); + gcry_err = luks_setkey (dev, candidate_key, keysize); if (gcry_err) { - grub_free (hashed_key); grub_free (split_key); return grub_crypto_gcry_error (gcry_err); } - /* Configure ESSIV if necessary. */ - if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) - { - grub_crypto_hash (dev->essiv_hash, hashed_key, - candidate_key, keysize); - gcry_err = - grub_crypto_cipher_set_key (dev->essiv_cipher, hashed_key, - essiv_keysize); - if (gcry_err) - { - grub_free (hashed_key); - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - } - - if (dev->mode == GRUB_LUKS_MODE_XTS) - { - gcry_err = grub_crypto_cipher_set_key (dev->secondary_cipher, - candidate_key + real_keysize, - keysize / 2); - if (gcry_err) - { - grub_free (hashed_key); - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - } - - if (dev->mode == GRUB_LUKS_MODE_LRW) - grub_memcpy (dev->lrw_key, candidate_key + real_keysize, - dev->cipher->cipher->blocksize); - grub_free (split_key); - grub_free (hashed_key); return GRUB_ERR_NONE; } From 6f33a8eebc99d6b3cb22f17a94779f6171aca17b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 16:41:43 +0200 Subject: [PATCH 0920/1414] optimize LRW --- grub-core/disk/luks.c | 114 +++++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 25 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index b1c738f2a..542ad4c9c 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -108,6 +108,7 @@ struct grub_luks enum grub_disk_dev_id source_dev_id; char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; grub_uint8_t lrw_key[GF_SIZE / 8]; + grub_uint8_t *lrw_precalc; #ifdef GRUB_UTIL char *cheat; int cheat_fd; @@ -203,6 +204,68 @@ grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher, return GPG_ERR_NO_ERROR; } +#define GF_BYTES (GF_SIZE / 8) +#define GF_PER_SECTOR (GRUB_DISK_SECTOR_SIZE / GF_BYTES) + +struct lrw_sector +{ + grub_uint8_t low[GF_BYTES]; + grub_uint8_t high[GF_BYTES]; + grub_uint8_t low_byte, low_byte_c; +}; + +static void +generate_lrw_sector (struct lrw_sector *sec, + const struct grub_luks *dev, + const grub_uint8_t *iv) +{ + grub_uint8_t idx[GF_BYTES]; + grub_uint16_t c; + int j; + grub_memcpy (idx, iv, GF_BYTES); + sec->low_byte = (idx[GF_BYTES - 1] & (GF_PER_SECTOR - 1)); + sec->low_byte_c = (((GF_PER_SECTOR - 1) & ~sec->low_byte) + 1); + idx[GF_BYTES - 1] &= ~(GF_PER_SECTOR - 1); + gf_mul_be (sec->low, dev->lrw_key, idx); + if (!sec->low_byte) + return; + + c = idx[GF_BYTES - 1] + GF_PER_SECTOR; + if (c & 0x100) + { + for (j = GF_BYTES - 2; j >= 0; j--) + { + idx[j]++; + if (idx[j] != 0) + break; + } + } + idx[GF_BYTES - 1] = c; + gf_mul_be (sec->high, dev->lrw_key, idx); +} + +static void __attribute__ ((unused)) +lrw_xor (const struct lrw_sector *sec, + const struct grub_luks *dev, + grub_uint8_t *b) +{ + int i; + + for (i = 0; i < sec->low_byte_c * GF_BYTES; i += GF_BYTES) + grub_crypto_xor (b + i, b + i, sec->low, GF_BYTES); + grub_crypto_xor (b, b, dev->lrw_precalc + GF_BYTES * sec->low_byte, + sec->low_byte_c * GF_BYTES); + if (!sec->low_byte) + return; + + for (i = sec->low_byte_c * GF_BYTES; + i < GRUB_DISK_SECTOR_SIZE; i += GF_BYTES) + grub_crypto_xor (b + i, b + i, sec->high, GF_BYTES); + grub_crypto_xor (b + sec->low_byte_c * GF_BYTES, + b + sec->low_byte_c * GF_BYTES, + dev->lrw_precalc, sec->low_byte * GF_BYTES); +} + static gcry_err_code_t luks_decrypt (const struct grub_luks *dev, grub_uint8_t * data, grub_size_t len, grub_disk_addr_t sector) @@ -287,30 +350,16 @@ luks_decrypt (const struct grub_luks *dev, break; case GRUB_LUKS_MODE_LRW: { - int j, k; - for (j = 0; - j < GRUB_DISK_SECTOR_SIZE; - j += dev->cipher->cipher->blocksize) - { - grub_uint8_t x[sz * sizeof (grub_uint32_t)]; + struct lrw_sector sec; - gf_mul_be (x, dev->lrw_key, (grub_uint8_t *) iv); - grub_crypto_xor (data + i + j, data + i + j, x, - dev->cipher->cipher->blocksize); - err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, - data + i + j, - dev->cipher->cipher->blocksize); - if (err) - return err; - grub_crypto_xor (data + i + j, data + i + j, x, - dev->cipher->cipher->blocksize); - for (k = sz - 1; k >= 0; k++) - { - iv[k] = grub_cpu_to_be32 (grub_be_to_cpu32 (iv[k]) + 1); - if (iv[k] != 0) - break; - } - } + generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv); + lrw_xor (&sec, dev, data + i); + + err = grub_crypto_ecb_decrypt (dev->cipher, data + i, + data + i, GRUB_DISK_SECTOR_SIZE); + if (err) + return err; + lrw_xor (&sec, dev, data + i); } break; default: @@ -576,8 +625,23 @@ luks_setkey (grub_luks_t dev, grub_uint8_t *key, grub_size_t keysize) } if (dev->mode == GRUB_LUKS_MODE_LRW) - grub_memcpy (dev->lrw_key, key + real_keysize, - dev->cipher->cipher->blocksize); + { + int i; + grub_uint8_t idx[GF_SIZE / 8]; + + grub_free (dev->lrw_precalc); + grub_memcpy (dev->lrw_key, key + real_keysize, + dev->cipher->cipher->blocksize); + dev->lrw_precalc = grub_malloc (GRUB_DISK_SECTOR_SIZE); + if (!dev->lrw_precalc) + return GPG_ERR_OUT_OF_MEMORY; + grub_memset (idx, 0, GF_SIZE / 8); + for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i += GF_SIZE / 8) + { + idx[15] = i / (GF_SIZE / 8); + gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key); + } + } return GPG_ERR_NO_ERROR; } From b896ae82db4584b29ebbfabac99c02a6abd070d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 16:43:55 +0200 Subject: [PATCH 0921/1414] small readability improvement --- grub-core/disk/luks.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 542ad4c9c..4a35ef011 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -90,6 +90,8 @@ typedef enum /* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ #define GF_POLYNOM 0x87 #define GF_SIZE 128 +#define GF_BYTES (GF_SIZE / 8) +#define GF_PER_SECTOR (GRUB_DISK_SECTOR_SIZE / GF_BYTES) struct grub_luks { @@ -107,7 +109,7 @@ struct grub_luks unsigned long id, source_id; enum grub_disk_dev_id source_dev_id; char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; - grub_uint8_t lrw_key[GF_SIZE / 8]; + grub_uint8_t lrw_key[GF_BYTES]; grub_uint8_t *lrw_precalc; #ifdef GRUB_UTIL char *cheat; @@ -137,7 +139,7 @@ gf_mul_x (grub_uint8_t *g) int over = 0, over2 = 0; int j; - for (j = 0; j < GF_SIZE / 8; j++) + for (j = 0; j < GF_BYTES; j++) { over2 = !!(g[j] & 0x80); g[j] <<= 1; @@ -155,7 +157,7 @@ gf_mul_x_be (grub_uint8_t *g) int over = 0, over2 = 0; int j; - for (j = GF_SIZE / 8 - 1; j >= 0; j--) + for (j = GF_BYTES - 1; j >= 0; j--) { over2 = !!(g[j] & 0x80); g[j] <<= 1; @@ -163,20 +165,20 @@ gf_mul_x_be (grub_uint8_t *g) over = over2; } if (over) - g[GF_SIZE / 8 - 1] ^= GF_POLYNOM; + g[GF_BYTES - 1] ^= GF_POLYNOM; } static void gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) { int i; - grub_uint8_t t[GF_SIZE / 8]; - grub_memset (o, 0, GF_SIZE / 8); - grub_memcpy (t, b, GF_SIZE / 8); + grub_uint8_t t[GF_BYTES]; + grub_memset (o, 0, GF_BYTES); + grub_memcpy (t, b, GF_BYTES); for (i = 0; i < GF_SIZE; i++) { - if (((a[GF_SIZE / 8 - i / 8 - 1] >> (i % 8))) & 1) - grub_crypto_xor (o, o, t, GF_SIZE / 8); + if (((a[GF_BYTES - i / 8 - 1] >> (i % 8))) & 1) + grub_crypto_xor (o, o, t, GF_BYTES); gf_mul_x_be (t); } } @@ -204,9 +206,6 @@ grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher, return GPG_ERR_NO_ERROR; } -#define GF_BYTES (GF_SIZE / 8) -#define GF_PER_SECTOR (GRUB_DISK_SECTOR_SIZE / GF_BYTES) - struct lrw_sector { grub_uint8_t low[GF_BYTES]; @@ -473,14 +472,14 @@ configure_ciphers (const struct grub_luks_phdr *header) grub_crypto_cipher_close (cipher); return NULL; } - if (cipher->cipher->blocksize != GF_SIZE / 8) + if (cipher->cipher->blocksize != GF_BYTES) { grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", cipher->cipher->blocksize); return NULL; } - if (secondary_cipher->cipher->blocksize != GF_SIZE / 8) + if (secondary_cipher->cipher->blocksize != GF_BYTES) { grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", @@ -492,7 +491,7 @@ configure_ciphers (const struct grub_luks_phdr *header) { mode = GRUB_LUKS_MODE_LRW; cipheriv = ciphermode + sizeof ("lrw-") - 1; - if (cipher->cipher->blocksize != GF_SIZE / 8) + if (cipher->cipher->blocksize != GF_BYTES) { grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d", @@ -627,7 +626,7 @@ luks_setkey (grub_luks_t dev, grub_uint8_t *key, grub_size_t keysize) if (dev->mode == GRUB_LUKS_MODE_LRW) { int i; - grub_uint8_t idx[GF_SIZE / 8]; + grub_uint8_t idx[GF_BYTES]; grub_free (dev->lrw_precalc); grub_memcpy (dev->lrw_key, key + real_keysize, @@ -635,10 +634,10 @@ luks_setkey (grub_luks_t dev, grub_uint8_t *key, grub_size_t keysize) dev->lrw_precalc = grub_malloc (GRUB_DISK_SECTOR_SIZE); if (!dev->lrw_precalc) return GPG_ERR_OUT_OF_MEMORY; - grub_memset (idx, 0, GF_SIZE / 8); - for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i += GF_SIZE / 8) + grub_memset (idx, 0, GF_BYTES); + for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i += GF_BYTES) { - idx[15] = i / (GF_SIZE / 8); + idx[15] = i / GF_BYTES; gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key); } } From fcf3bfb6ffcd03e2b134f6b1c09571351793d50b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 16:45:00 +0200 Subject: [PATCH 0922/1414] small readability improvement --- grub-core/disk/luks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 4a35ef011..a9590cab5 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -637,7 +637,7 @@ luks_setkey (grub_luks_t dev, grub_uint8_t *key, grub_size_t keysize) grub_memset (idx, 0, GF_BYTES); for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i += GF_BYTES) { - idx[15] = i / GF_BYTES; + idx[GF_BYTES - 1] = i / GF_BYTES; gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key); } } From 8585e54becc32be8cb8e45b85fd14f5235a5c2dd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Apr 2011 18:00:42 +0200 Subject: [PATCH 0923/1414] factor cryptodisk part out --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/disk/luks.c | 713 ++++------------------------------- grub-core/kern/emu/getroot.c | 2 +- include/grub/disk.h | 2 +- include/grub/emu/hostdisk.h | 1 - util/grub-probe.c | 11 +- 7 files changed, 80 insertions(+), 655 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 693a7d127..ffa7a794f 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -23,6 +23,7 @@ library = { common = grub-core/kern/partition.c; common = grub-core/lib/crypto.c; common = grub-core/disk/luks.c; + common = grub-core/disk/cryptodisk.c; common = grub-core/disk/AFSplitter.c; common = grub-core/lib/pbkdf2.c; common = grub-core/commands/extcmd.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8dc810200..c55fff13a 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -768,6 +768,11 @@ module = { common = disk/loopback.c; }; +module = { + name = cryptodisk; + common = disk/cryptodisk.c; +}; + module = { name = luks; common = disk/luks.c; diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index a9590cab5..361beb756 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -16,6 +16,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include @@ -25,15 +26,6 @@ #include #include #include -#ifdef GRUB_UTIL -#include -#include -#include -#include -#include -#include -#include -#endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -69,59 +61,6 @@ struct grub_luks_phdr typedef struct grub_luks_phdr *grub_luks_phdr_t; -typedef enum - { - GRUB_LUKS_MODE_ECB, - GRUB_LUKS_MODE_CBC, - GRUB_LUKS_MODE_PCBC, - GRUB_LUKS_MODE_XTS, - GRUB_LUKS_MODE_LRW - } luks_mode_t; - -typedef enum - { - GRUB_LUKS_MODE_IV_NULL, - GRUB_LUKS_MODE_IV_PLAIN, - GRUB_LUKS_MODE_IV_PLAIN64, - GRUB_LUKS_MODE_IV_ESSIV, - GRUB_LUKS_MODE_IV_BENBI, - } luks_mode_iv_t; - -/* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ -#define GF_POLYNOM 0x87 -#define GF_SIZE 128 -#define GF_BYTES (GF_SIZE / 8) -#define GF_PER_SECTOR (GRUB_DISK_SECTOR_SIZE / GF_BYTES) - -struct grub_luks -{ - char *source; - grub_uint32_t offset; - grub_disk_t source_disk; - int ref; - grub_crypto_cipher_handle_t cipher; - grub_crypto_cipher_handle_t secondary_cipher; - grub_crypto_cipher_handle_t essiv_cipher; - const gcry_md_spec_t *essiv_hash, *hash; - luks_mode_t mode; - luks_mode_iv_t mode_iv; - int benbi_log; - unsigned long id, source_id; - enum grub_disk_dev_id source_dev_id; - char uuid[sizeof (((struct grub_luks_phdr *) 0)->uuid) + 1]; - grub_uint8_t lrw_key[GF_BYTES]; - grub_uint8_t *lrw_precalc; -#ifdef GRUB_UTIL - char *cheat; - int cheat_fd; -#endif - struct grub_luks *next; -}; -typedef struct grub_luks *grub_luks_t; - -static grub_luks_t luks_list = NULL; -static grub_uint8_t n = 0; - gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst, grub_size_t blocksize, grub_size_t blocknumbers); @@ -133,249 +72,13 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -static void -gf_mul_x (grub_uint8_t *g) -{ - int over = 0, over2 = 0; - int j; - - for (j = 0; j < GF_BYTES; j++) - { - over2 = !!(g[j] & 0x80); - g[j] <<= 1; - g[j] |= over; - over = over2; - } - if (over) - g[0] ^= GF_POLYNOM; -} - - -static void -gf_mul_x_be (grub_uint8_t *g) -{ - int over = 0, over2 = 0; - int j; - - for (j = GF_BYTES - 1; j >= 0; j--) - { - over2 = !!(g[j] & 0x80); - g[j] <<= 1; - g[j] |= over; - over = over2; - } - if (over) - g[GF_BYTES - 1] ^= GF_POLYNOM; -} - -static void -gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) -{ - int i; - grub_uint8_t t[GF_BYTES]; - grub_memset (o, 0, GF_BYTES); - grub_memcpy (t, b, GF_BYTES); - for (i = 0; i < GF_SIZE; i++) - { - if (((a[GF_BYTES - i / 8 - 1] >> (i % 8))) & 1) - grub_crypto_xor (o, o, t, GF_BYTES); - gf_mul_x_be (t); - } -} - -static gcry_err_code_t -grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size, - void *iv) -{ - grub_uint8_t *inptr, *outptr, *end; - grub_uint8_t ivt[cipher->cipher->blocksize]; - if (!cipher->cipher->decrypt) - return GPG_ERR_NOT_SUPPORTED; - if (size % cipher->cipher->blocksize != 0) - return GPG_ERR_INV_ARG; - end = (grub_uint8_t *) in + size; - for (inptr = in, outptr = out; inptr < end; - inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize) - { - grub_memcpy (ivt, inptr, cipher->cipher->blocksize); - cipher->cipher->decrypt (cipher->ctx, outptr, inptr); - grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize); - grub_crypto_xor (iv, ivt, outptr, cipher->cipher->blocksize); - } - return GPG_ERR_NO_ERROR; -} - -struct lrw_sector -{ - grub_uint8_t low[GF_BYTES]; - grub_uint8_t high[GF_BYTES]; - grub_uint8_t low_byte, low_byte_c; -}; - -static void -generate_lrw_sector (struct lrw_sector *sec, - const struct grub_luks *dev, - const grub_uint8_t *iv) -{ - grub_uint8_t idx[GF_BYTES]; - grub_uint16_t c; - int j; - grub_memcpy (idx, iv, GF_BYTES); - sec->low_byte = (idx[GF_BYTES - 1] & (GF_PER_SECTOR - 1)); - sec->low_byte_c = (((GF_PER_SECTOR - 1) & ~sec->low_byte) + 1); - idx[GF_BYTES - 1] &= ~(GF_PER_SECTOR - 1); - gf_mul_be (sec->low, dev->lrw_key, idx); - if (!sec->low_byte) - return; - - c = idx[GF_BYTES - 1] + GF_PER_SECTOR; - if (c & 0x100) - { - for (j = GF_BYTES - 2; j >= 0; j--) - { - idx[j]++; - if (idx[j] != 0) - break; - } - } - idx[GF_BYTES - 1] = c; - gf_mul_be (sec->high, dev->lrw_key, idx); -} - -static void __attribute__ ((unused)) -lrw_xor (const struct lrw_sector *sec, - const struct grub_luks *dev, - grub_uint8_t *b) -{ - int i; - - for (i = 0; i < sec->low_byte_c * GF_BYTES; i += GF_BYTES) - grub_crypto_xor (b + i, b + i, sec->low, GF_BYTES); - grub_crypto_xor (b, b, dev->lrw_precalc + GF_BYTES * sec->low_byte, - sec->low_byte_c * GF_BYTES); - if (!sec->low_byte) - return; - - for (i = sec->low_byte_c * GF_BYTES; - i < GRUB_DISK_SECTOR_SIZE; i += GF_BYTES) - grub_crypto_xor (b + i, b + i, sec->high, GF_BYTES); - grub_crypto_xor (b + sec->low_byte_c * GF_BYTES, - b + sec->low_byte_c * GF_BYTES, - dev->lrw_precalc, sec->low_byte * GF_BYTES); -} - -static gcry_err_code_t -luks_decrypt (const struct grub_luks *dev, - grub_uint8_t * data, grub_size_t len, grub_disk_addr_t sector) -{ - grub_size_t i; - gcry_err_code_t err; - - /* The only mode without IV. */ - if (dev->mode == GRUB_LUKS_MODE_ECB) - return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); - - for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) - { - grub_size_t sz = ((dev->cipher->cipher->blocksize - + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)); - grub_uint32_t iv[sz]; - - grub_memset (iv, 0, sz * sizeof (iv[0])); - switch (dev->mode_iv) - { - case GRUB_LUKS_MODE_IV_NULL: - break; - case GRUB_LUKS_MODE_IV_PLAIN64: - iv[1] = grub_cpu_to_le32 (sector >> 32); - case GRUB_LUKS_MODE_IV_PLAIN: - iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); - break; - case GRUB_LUKS_MODE_IV_BENBI: - { - grub_uint64_t num = (sector << dev->benbi_log) + 1; - iv[sz - 2] = grub_cpu_to_be32 (num >> 32); - iv[sz - 1] = grub_cpu_to_be32 (num & 0xFFFFFFFF); - } - break; - case GRUB_LUKS_MODE_IV_ESSIV: - iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); - err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv, - dev->cipher->cipher->blocksize); - if (err) - return err; - } - - switch (dev->mode) - { - case GRUB_LUKS_MODE_CBC: - err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, - GRUB_DISK_SECTOR_SIZE, iv); - if (err) - return err; - break; - - case GRUB_LUKS_MODE_PCBC: - err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, - GRUB_DISK_SECTOR_SIZE, iv); - if (err) - return err; - break; - case GRUB_LUKS_MODE_XTS: - { - int j; - err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, - dev->cipher->cipher->blocksize); - if (err) - return err; - - for (j = 0; j < GRUB_DISK_SECTOR_SIZE; - j += dev->cipher->cipher->blocksize) - { - grub_crypto_xor (data + i + j, data + i + j, iv, - dev->cipher->cipher->blocksize); - err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, - data + i + j, - dev->cipher->cipher->blocksize); - if (err) - return err; - grub_crypto_xor (data + i + j, data + i + j, iv, - dev->cipher->cipher->blocksize); - gf_mul_x ((grub_uint8_t *) iv); - } - } - break; - case GRUB_LUKS_MODE_LRW: - { - struct lrw_sector sec; - - generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv); - lrw_xor (&sec, dev, data + i); - - err = grub_crypto_ecb_decrypt (dev->cipher, data + i, - data + i, GRUB_DISK_SECTOR_SIZE); - if (err) - return err; - lrw_xor (&sec, dev, data + i); - } - break; - default: - return GPG_ERR_NOT_IMPLEMENTED; - } - sector++; - } - return GPG_ERR_NO_ERROR; -} - static int check_uuid, have_it; static char *search_uuid; -static grub_luks_t +static grub_cryptodisk_t configure_ciphers (const struct grub_luks_phdr *header) { - grub_luks_t newdev; + grub_cryptodisk_t newdev; const char *iptr; char *optr; char uuid[sizeof (header->uuid) + 1]; @@ -387,8 +90,8 @@ configure_ciphers (const struct grub_luks_phdr *header) grub_crypto_cipher_handle_t essiv_cipher = NULL; const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; const struct gcry_cipher_spec *ciph; - luks_mode_t mode; - luks_mode_iv_t mode_iv; + grub_cryptodisk_mode_t mode; + grub_cryptodisk_mode_iv_t mode_iv; int benbi_log = 0; /* Look for LUKS magic sequence. */ @@ -442,29 +145,29 @@ configure_ciphers (const struct grub_luks_phdr *header) /* Configure the cipher mode. */ if (grub_strcmp (ciphermode, "ecb") == 0) { - mode = GRUB_LUKS_MODE_ECB; - mode_iv = GRUB_LUKS_MODE_IV_PLAIN; + mode = GRUB_CRYPTODISK_MODE_ECB; + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; cipheriv = NULL; } else if (grub_strcmp (ciphermode, "plain") == 0) { - mode = GRUB_LUKS_MODE_CBC; - mode_iv = GRUB_LUKS_MODE_IV_PLAIN; + mode = GRUB_CRYPTODISK_MODE_CBC; + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; cipheriv = NULL; } else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0) { - mode = GRUB_LUKS_MODE_CBC; + mode = GRUB_CRYPTODISK_MODE_CBC; cipheriv = ciphermode + sizeof ("cbc-") - 1; } else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0) { - mode = GRUB_LUKS_MODE_PCBC; + mode = GRUB_CRYPTODISK_MODE_PCBC; cipheriv = ciphermode + sizeof ("pcbc-") - 1; } else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0) { - mode = GRUB_LUKS_MODE_XTS; + mode = GRUB_CRYPTODISK_MODE_XTS; cipheriv = ciphermode + sizeof ("xts-") - 1; secondary_cipher = grub_crypto_cipher_open (ciph); if (!secondary_cipher) @@ -472,14 +175,14 @@ configure_ciphers (const struct grub_luks_phdr *header) grub_crypto_cipher_close (cipher); return NULL; } - if (cipher->cipher->blocksize != GF_BYTES) + if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) { grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", cipher->cipher->blocksize); return NULL; } - if (secondary_cipher->cipher->blocksize != GF_BYTES) + if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) { grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", @@ -489,9 +192,9 @@ configure_ciphers (const struct grub_luks_phdr *header) } else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0) { - mode = GRUB_LUKS_MODE_LRW; + mode = GRUB_CRYPTODISK_MODE_LRW; cipheriv = ciphermode + sizeof ("lrw-") - 1; - if (cipher->cipher->blocksize != GF_BYTES) + if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) { grub_crypto_cipher_close (cipher); grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d", @@ -509,9 +212,9 @@ configure_ciphers (const struct grub_luks_phdr *header) if (cipheriv == NULL); else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0) - mode_iv = GRUB_LUKS_MODE_IV_PLAIN; + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) - mode_iv = GRUB_LUKS_MODE_IV_PLAIN64; + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0) { if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1) @@ -521,15 +224,15 @@ configure_ciphers (const struct grub_luks_phdr *header) for (benbi_log = 0; (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE; benbi_log++); - mode_iv = GRUB_LUKS_MODE_IV_BENBI; + mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI; } else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0) - mode_iv = GRUB_LUKS_MODE_IV_NULL; + mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL; else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0) { char *hash_str = cipheriv + 6; - mode_iv = GRUB_LUKS_MODE_IV_ESSIV; + mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV; /* Configure the hash and cipher used for ESSIV. */ essiv_hash = grub_crypto_lookup_md_by_name (hash_str); @@ -567,7 +270,7 @@ configure_ciphers (const struct grub_luks_phdr *header) return NULL; } - newdev = grub_zalloc (sizeof (struct grub_luks)); + newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); if (!newdev) return NULL; newdev->cipher = cipher; @@ -580,72 +283,12 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->essiv_cipher = essiv_cipher; newdev->essiv_hash = essiv_hash; newdev->hash = hash; - newdev->id = n++; grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); return newdev; } -static gcry_err_code_t -luks_setkey (grub_luks_t dev, grub_uint8_t *key, grub_size_t keysize) -{ - gcry_err_code_t err; - int real_keysize; - - real_keysize = keysize; - if (dev->mode == GRUB_LUKS_MODE_XTS) - real_keysize /= 2; - if (dev->mode == GRUB_LUKS_MODE_LRW) - real_keysize -= dev->cipher->cipher->blocksize; - - /* Set the PBKDF2 output as the cipher key. */ - err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize); - if (err) - return err; - - /* Configure ESSIV if necessary. */ - if (dev->mode_iv == GRUB_LUKS_MODE_IV_ESSIV) - { - grub_size_t essiv_keysize = dev->essiv_hash->mdlen; - grub_uint8_t hashed_key[essiv_keysize]; - - grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize); - err = grub_crypto_cipher_set_key (dev->essiv_cipher, - hashed_key, essiv_keysize); - if (err) - return err; - } - if (dev->mode == GRUB_LUKS_MODE_XTS) - { - err = grub_crypto_cipher_set_key (dev->secondary_cipher, - key + real_keysize, - keysize / 2); - if (err) - return err; - } - - if (dev->mode == GRUB_LUKS_MODE_LRW) - { - int i; - grub_uint8_t idx[GF_BYTES]; - - grub_free (dev->lrw_precalc); - grub_memcpy (dev->lrw_key, key + real_keysize, - dev->cipher->cipher->blocksize); - dev->lrw_precalc = grub_malloc (GRUB_DISK_SECTOR_SIZE); - if (!dev->lrw_precalc) - return GPG_ERR_OUT_OF_MEMORY; - grub_memset (idx, 0, GF_BYTES); - for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i += GF_BYTES) - { - idx[GF_BYTES - 1] = i / GF_BYTES; - gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key); - } - } - return GPG_ERR_NO_ERROR; -} - static grub_err_t -luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, +luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, const char *name, grub_disk_t source) { grub_size_t keysize = grub_be_to_cpu32 (header->keyBytes); @@ -700,7 +343,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_dprintf ("luks", "PBKDF2 done\n"); - gcry_err = luks_setkey (dev, digest, keysize); + gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); if (gcry_err) { grub_free (split_key); @@ -721,7 +364,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, return err; } - gcry_err = luks_decrypt (dev, split_key, length, 0); + gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0); if (gcry_err) { grub_free (split_key); @@ -766,7 +409,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, grub_printf ("Slot %d opened\n", i); /* Set the master key. */ - gcry_err = luks_setkey (dev, candidate_key, keysize); + gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); if (gcry_err) { grub_free (split_key); @@ -782,7 +425,7 @@ luks_recover_key (grub_luks_t dev, const struct grub_luks_phdr *header, } static void -luks_close (grub_luks_t luks) +luks_close (grub_cryptodisk_t luks) { grub_crypto_cipher_close (luks->cipher); grub_crypto_cipher_close (luks->secondary_cipher); @@ -795,11 +438,12 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) { grub_err_t err; struct grub_luks_phdr header; - grub_luks_t newdev, dev; + grub_cryptodisk_t newdev, dev; - for (dev = luks_list; dev != NULL; dev = dev->next) - if (dev->source_id == source->id && dev->source_dev_id == source->dev->id) - return GRUB_ERR_NONE; + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) + return GRUB_ERR_NONE; /* Read the LUKS header. */ err = grub_disk_read (source, 0, 0, sizeof (header), &header); @@ -817,17 +461,7 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) return err; } - newdev->source = grub_strdup (name); - if (!newdev->source) - { - grub_free (newdev); - return grub_errno; - } - - newdev->source_id = source->id; - newdev->source_dev_id = source->dev->id; - newdev->next = luks_list; - luks_list = newdev; + grub_cryptodisk_insert (newdev, name, source); have_it = 1; @@ -840,7 +474,7 @@ grub_luks_cheat_mount (const char *sourcedev, const char *cheat) { grub_err_t err; struct grub_luks_phdr header; - grub_luks_t newdev, dev; + grub_cryptodisk_t newdev, dev; grub_disk_t source; /* Try to open disk. */ @@ -848,12 +482,13 @@ grub_luks_cheat_mount (const char *sourcedev, const char *cheat) if (!source) return grub_errno; - for (dev = luks_list; dev != NULL; dev = dev->next) - if (dev->source_id == source->id && dev->source_dev_id == source->dev->id) - { - grub_disk_close (source); - return GRUB_ERR_NONE; - } + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) + { + grub_disk_close (source); + return GRUB_ERR_NONE; + } /* Read the LUKS header. */ err = grub_disk_read (source, 0, 0, sizeof (header), &header); @@ -861,25 +496,18 @@ grub_luks_cheat_mount (const char *sourcedev, const char *cheat) return err; newdev = configure_ciphers (&header); - grub_disk_close (source); if (!newdev) - return grub_errno; - - newdev->cheat = grub_strdup (cheat); - newdev->source = grub_strdup (sourcedev); - if (!newdev->source || !newdev->cheat) { - grub_free (newdev->source); - grub_free (newdev->cheat); - grub_free (newdev); + grub_disk_close (source); return grub_errno; } - newdev->cheat_fd = -1; - newdev->source_id = source->id; - newdev->source_dev_id = source->dev->id; - newdev->next = luks_list; - luks_list = newdev; - return GRUB_ERR_NONE; + + err = grub_cryptodisk_cheat_insert (newdev, sourcedev, source, cheat); + grub_disk_close (source); + if (err) + grub_free (newdev); + + return err; } #endif @@ -903,208 +531,16 @@ grub_luks_scan_device (const char *name) return have_it && check_uuid ? 0 : 1; } -static int -grub_luks_iterate (int (*hook) (const char *name), - grub_disk_pull_t pull) -{ - grub_luks_t i; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - for (i = luks_list; i != NULL; i = i->next) - { - char buf[30]; - grub_snprintf (buf, sizeof (buf), "luks%lu", i->id); - if (hook (buf)) - return 1; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_luks_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) -{ - grub_luks_t dev; - - if (grub_memcmp (name, "luks", sizeof ("luks") - 1) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - - if (grub_memcmp (name, "luksuuid/", sizeof ("luksuuid/") - 1) == 0) - { - for (dev = luks_list; dev != NULL; dev = dev->next) - if (grub_strcasecmp (name + sizeof ("luksuuid/") - 1, dev->uuid) == 0) - break; - } - else - { - unsigned long id = grub_strtoul (name + sizeof ("luks") - 1, 0, 0); - if (grub_errno) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - /* Search for requested device in the list of LUKS devices. */ - for (dev = luks_list; dev != NULL; dev = dev->next) - if (dev->id == id) - break; - } - if (!dev) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - #ifdef GRUB_UTIL - if (dev->cheat) - { - if (dev->cheat_fd == -1) - dev->cheat_fd = open (dev->cheat, O_RDONLY); - if (dev->cheat_fd == -1) - return grub_error (GRUB_ERR_IO, "couldn't open %s: %s", - dev->cheat, strerror (errno)); - } -#endif - - if (!dev->source_disk) - { - grub_dprintf ("luks", "Opening device %s\n", name); - /* Try to open the source disk and populate the requested disk. */ - dev->source_disk = grub_disk_open (dev->source); - if (!dev->source_disk) - return grub_errno; - } - - disk->data = dev; - disk->total_sectors = grub_disk_get_size (dev->source_disk) - dev->offset; - disk->id = dev->id; - dev->ref++; - return GRUB_ERR_NONE; -} - -static void -grub_luks_close (grub_disk_t disk) -{ - grub_luks_t dev = (grub_luks_t) disk->data; - grub_dprintf ("luks", "Closing disk\n"); - - dev->ref--; - - if (dev->ref != 0) - return; -#ifdef GRUB_UTIL - if (dev->cheat) - { - close (dev->cheat_fd); - dev->cheat_fd = -1; - } -#endif - grub_disk_close (dev->source_disk); - dev->source_disk = NULL; -} - -static grub_err_t -grub_luks_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_luks_t dev = (grub_luks_t) disk->data; - grub_err_t err; - -#ifdef GRUB_UTIL - if (dev->cheat) - { - err = grub_util_fd_sector_seek (dev->cheat_fd, dev->cheat, sector); - if (err) - return err; - if (grub_util_fd_read (dev->cheat_fd, buf, size << GRUB_DISK_SECTOR_BITS) - != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) - return grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", - dev->cheat); - return GRUB_ERR_NONE; - } -#endif - - grub_dprintf ("luks", - "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%" - PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT32_T "\n", - size, sector, dev->offset); - - err = grub_disk_read (dev->source_disk, sector + dev->offset, 0, - size << GRUB_DISK_SECTOR_BITS, buf); - if (err) - { - grub_dprintf ("luks", "grub_disk_read failed with error %d\n", err); - return err; - } - return grub_crypto_gcry_error (luks_decrypt (dev, (grub_uint8_t *) buf, - size << GRUB_DISK_SECTOR_BITS, - sector)); -} - -static grub_err_t -grub_luks_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; -} - -#ifdef GRUB_UTIL -static grub_disk_memberlist_t -grub_luks_memberlist (grub_disk_t disk) -{ - grub_luks_t dev = (grub_luks_t) disk->data; - grub_disk_memberlist_t list = NULL; - - list = grub_malloc (sizeof (*list)); - if (list) - { - list->disk = dev->source_disk; - list->next = NULL; - } - - return list; -} - -void -grub_util_luks_print_ciphers (grub_disk_t disk) -{ - grub_luks_t dev = (grub_luks_t) disk->data; - if (dev->cipher) - grub_printf ("%s ", dev->cipher->cipher->modname); - if (dev->secondary_cipher) - grub_printf ("%s ", dev->secondary_cipher->cipher->modname); - if (dev->essiv_cipher) - grub_printf ("%s ", dev->essiv_cipher->cipher->modname); - if (dev->hash) - grub_printf ("%s ", dev->hash->modname); - if (dev->essiv_hash) - grub_printf ("%s ", dev->essiv_hash->modname); -} void grub_util_luks_print_uuid (grub_disk_t disk) { - grub_luks_t dev = (grub_luks_t) disk->data; + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; grub_printf ("%s ", dev->uuid); } #endif -static void -luks_cleanup (void) -{ - grub_luks_t dev = luks_list; - grub_luks_t tmp; - - while (dev != NULL) - { - grub_free (dev->source); - grub_free (dev->cipher); - grub_free (dev->secondary_cipher); - grub_free (dev->essiv_cipher); - tmp = dev->next; - grub_free (dev); - dev = tmp; - } -} - static grub_err_t grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) { @@ -1116,14 +552,14 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) have_it = 0; if (state[0].set) { - grub_luks_t dev; + grub_cryptodisk_t dev; - for (dev = luks_list; dev != NULL; dev = dev->next) - if (grub_strcasecmp (dev->uuid, args[0]) == 0) - { - grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); - return GRUB_ERR_NONE; - } + dev = grub_cryptodisk_get_by_uuid (args[0]); + if (dev) + { + grub_dprintf ("luks", "already mounted as crypto%lu\n", dev->id); + return GRUB_ERR_NONE; + } check_uuid = 1; search_uuid = args[0]; @@ -1146,7 +582,7 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) { grub_err_t err; grub_disk_t disk; - grub_luks_t dev; + grub_cryptodisk_t dev; check_uuid = 0; search_uuid = NULL; @@ -1154,13 +590,13 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) if (!disk) return grub_errno; - for (dev = luks_list; dev != NULL; dev = dev->next) - if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id) - { - grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); - grub_disk_close (disk); - return GRUB_ERR_NONE; - } + dev = grub_cryptodisk_get_by_source_disk (disk); + if (dev) + { + grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); + grub_disk_close (disk); + return GRUB_ERR_NONE; + } err = grub_luks_scan_device_real (args[0], disk); @@ -1170,33 +606,18 @@ grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) } } -static struct grub_disk_dev grub_luks_dev = { - .name = "luks", - .id = GRUB_DISK_DEVICE_LUKS_ID, - .iterate = grub_luks_iterate, - .open = grub_luks_open, - .close = grub_luks_close, - .read = grub_luks_read, - .write = grub_luks_write, -#ifdef GRUB_UTIL - .memberlist = grub_luks_memberlist, -#endif - .next = 0 -}; - static grub_extcmd_t cmd; GRUB_MOD_INIT (luks) { + COMPILE_TIME_ASSERT (sizeof (((struct grub_luks_phdr *) 0)->uuid) + < GRUB_CRYPTODISK_MAX_UUID_LENGTH); cmd = grub_register_extcmd ("luksmount", grub_cmd_luksmount, 0, N_("SOURCE|-u UUID|-a"), N_("Mount a LUKS device."), options); - grub_disk_dev_register (&grub_luks_dev); } GRUB_MOD_FINI (luks) { grub_unregister_extcmd (cmd); - grub_disk_dev_unregister (&grub_luks_dev); - luks_cleanup (); } diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index c3a971689..642d77cf0 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -962,7 +962,7 @@ grub_util_get_grub_dev (const char *os_dev) dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-'); if (dash) *dash = 0; - grub_dev = grub_xasprintf ("luksuuid/%s", + grub_dev = grub_xasprintf ("cryptouuid/%s", uuid + sizeof ("CRYPT-LUKS1-") - 1); grub_free (uuid); } diff --git a/include/grub/disk.h b/include/grub/disk.h index 2678ad5eb..52f3e61b0 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -42,7 +42,7 @@ 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_CRYPTODISK_ID }; struct grub_disk; diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 7541308e6..c1350a370 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -36,7 +36,6 @@ grub_util_fd_sector_seek (int fd, const char *name, grub_disk_addr_t sector); ssize_t grub_util_fd_read (int fd, char *buf, size_t len); grub_err_t grub_luks_cheat_mount (const char *sourcedev, const char *cheat); -void grub_util_luks_print_ciphers (grub_disk_t disk); void grub_util_luks_print_uuid (grub_disk_t disk); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/grub-probe.c b/util/grub-probe.c index 21fc21b02..f5d93ac4e 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -106,7 +107,8 @@ probe_luks_uuid (grub_disk_t disk) free (list); list = tmp; } - if (disk->dev->id == GRUB_DISK_DEVICE_LUKS_ID) + /* FIXME: support non-LUKS. */ + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) grub_util_luks_print_uuid (disk); } @@ -144,11 +146,8 @@ probe_abstraction (grub_disk_t disk) if (disk->dev->id == GRUB_DISK_DEVICE_LVM_ID) printf ("lvm "); - if (disk->dev->id == GRUB_DISK_DEVICE_LUKS_ID) - { - printf ("luks "); - grub_util_luks_print_ciphers (disk); - } + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + grub_util_cryptodisk_print_abstraction (disk); raid_level = probe_raid_level (disk); if (raid_level >= 0) From 1a1f408f206f2e29b40b172b0e9857f0137d91a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 00:00:29 +0200 Subject: [PATCH 0924/1414] geli support --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/disk/cryptodisk.c | 643 ++++++++++++++++++++++++++++++++++++ grub-core/disk/geli.c | 515 +++++++++++++++++++++++++++++ grub-core/disk/luks.c | 4 + grub-core/lib/crypto.c | 10 +- include/grub/crypto.h | 4 +- include/grub/cryptodisk.h | 99 ++++++ util/grub-fstest.c | 8 +- 9 files changed, 1281 insertions(+), 8 deletions(-) create mode 100644 grub-core/disk/cryptodisk.c create mode 100644 grub-core/disk/geli.c create mode 100644 include/grub/cryptodisk.h diff --git a/Makefile.util.def b/Makefile.util.def index ffa7a794f..fe9e8c036 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -23,6 +23,7 @@ library = { common = grub-core/kern/partition.c; common = grub-core/lib/crypto.c; common = grub-core/disk/luks.c; + common = grub-core/disk/geli.c; common = grub-core/disk/cryptodisk.c; common = grub-core/disk/AFSplitter.c; common = grub-core/lib/pbkdf2.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c55fff13a..52add9f1b 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -779,6 +779,11 @@ module = { common = disk/AFSplitter.c; }; +module = { + name = geli; + common = disk/geli.c; +}; + module = { name = lvm; common = disk/lvm.c; diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c new file mode 100644 index 000000000..7f3b60bf5 --- /dev/null +++ b/grub-core/disk/cryptodisk.c @@ -0,0 +1,643 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2010,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 + +#ifdef GRUB_UTIL +#include +#include +#include +#include +#include +#include +#include +#endif + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ +#define GF_POLYNOM 0x87 +#define GF_PER_SECTOR (GRUB_DISK_SECTOR_SIZE / GRUB_CRYPTODISK_GF_BYTES) + +static grub_cryptodisk_t cryptodisk_list = NULL; +static grub_uint8_t n = 0; + +static void +gf_mul_x (grub_uint8_t *g) +{ + int over = 0, over2 = 0; + int j; + + for (j = 0; j < GRUB_CRYPTODISK_GF_BYTES; j++) + { + over2 = !!(g[j] & 0x80); + g[j] <<= 1; + g[j] |= over; + over = over2; + } + if (over) + g[0] ^= GF_POLYNOM; +} + + +static void +gf_mul_x_be (grub_uint8_t *g) +{ + int over = 0, over2 = 0; + int j; + + for (j = GRUB_CRYPTODISK_GF_BYTES - 1; j >= 0; j--) + { + over2 = !!(g[j] & 0x80); + g[j] <<= 1; + g[j] |= over; + over = over2; + } + if (over) + g[GRUB_CRYPTODISK_GF_BYTES - 1] ^= GF_POLYNOM; +} + +static void +gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) +{ + int i; + grub_uint8_t t[GRUB_CRYPTODISK_GF_BYTES]; + grub_memset (o, 0, GRUB_CRYPTODISK_GF_BYTES); + grub_memcpy (t, b, GRUB_CRYPTODISK_GF_BYTES); + for (i = 0; i < GRUB_CRYPTODISK_GF_SIZE; i++) + { + if (((a[GRUB_CRYPTODISK_GF_BYTES - i / 8 - 1] >> (i % 8))) & 1) + grub_crypto_xor (o, o, t, GRUB_CRYPTODISK_GF_BYTES); + gf_mul_x_be (t); + } +} + +static gcry_err_code_t +grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher, + void *out, void *in, grub_size_t size, + void *iv) +{ + grub_uint8_t *inptr, *outptr, *end; + grub_uint8_t ivt[cipher->cipher->blocksize]; + if (!cipher->cipher->decrypt) + return GPG_ERR_NOT_SUPPORTED; + if (size % cipher->cipher->blocksize != 0) + return GPG_ERR_INV_ARG; + end = (grub_uint8_t *) in + size; + for (inptr = in, outptr = out; inptr < end; + inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize) + { + grub_memcpy (ivt, inptr, cipher->cipher->blocksize); + cipher->cipher->decrypt (cipher->ctx, outptr, inptr); + grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize); + grub_crypto_xor (iv, ivt, outptr, cipher->cipher->blocksize); + } + return GPG_ERR_NO_ERROR; +} + +struct lrw_sector +{ + grub_uint8_t low[GRUB_CRYPTODISK_GF_BYTES]; + grub_uint8_t high[GRUB_CRYPTODISK_GF_BYTES]; + grub_uint8_t low_byte, low_byte_c; +}; + +static void +generate_lrw_sector (struct lrw_sector *sec, + const struct grub_cryptodisk *dev, + const grub_uint8_t *iv) +{ + grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES]; + grub_uint16_t c; + int j; + grub_memcpy (idx, iv, GRUB_CRYPTODISK_GF_BYTES); + sec->low_byte = (idx[GRUB_CRYPTODISK_GF_BYTES - 1] & (GF_PER_SECTOR - 1)); + sec->low_byte_c = (((GF_PER_SECTOR - 1) & ~sec->low_byte) + 1); + idx[GRUB_CRYPTODISK_GF_BYTES - 1] &= ~(GF_PER_SECTOR - 1); + gf_mul_be (sec->low, dev->lrw_key, idx); + if (!sec->low_byte) + return; + + c = idx[GRUB_CRYPTODISK_GF_BYTES - 1] + GF_PER_SECTOR; + if (c & 0x100) + { + for (j = GRUB_CRYPTODISK_GF_BYTES - 2; j >= 0; j--) + { + idx[j]++; + if (idx[j] != 0) + break; + } + } + idx[GRUB_CRYPTODISK_GF_BYTES - 1] = c; + gf_mul_be (sec->high, dev->lrw_key, idx); +} + +static void __attribute__ ((unused)) +lrw_xor (const struct lrw_sector *sec, + const struct grub_cryptodisk *dev, + grub_uint8_t *b) +{ + int i; + + for (i = 0; i < sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; i += GRUB_CRYPTODISK_GF_BYTES) + grub_crypto_xor (b + i, b + i, sec->low, GRUB_CRYPTODISK_GF_BYTES); + grub_crypto_xor (b, b, dev->lrw_precalc + GRUB_CRYPTODISK_GF_BYTES * sec->low_byte, + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES); + if (!sec->low_byte) + return; + + for (i = sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; + i < GRUB_DISK_SECTOR_SIZE; i += GRUB_CRYPTODISK_GF_BYTES) + grub_crypto_xor (b + i, b + i, sec->high, GRUB_CRYPTODISK_GF_BYTES); + grub_crypto_xor (b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES, + b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES, + dev->lrw_precalc, sec->low_byte * GRUB_CRYPTODISK_GF_BYTES); +} + +gcry_err_code_t +grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, + grub_uint8_t * data, grub_size_t len, + grub_disk_addr_t sector) +{ + grub_size_t i; + gcry_err_code_t err; + + /* The only mode without IV. */ + if (dev->mode == GRUB_CRYPTODISK_MODE_ECB) + return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); + + for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) + { + grub_size_t sz = ((dev->cipher->cipher->blocksize + + sizeof (grub_uint32_t) - 1) + / sizeof (grub_uint32_t)); + grub_uint32_t iv[sz]; + + grub_memset (iv, 0, sz * sizeof (iv[0])); + switch (dev->mode_iv) + { + case GRUB_CRYPTODISK_MODE_IV_NULL: + break; + case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH: + { + grub_uint64_t tmp; + grub_uint64_t ctx[(dev->iv_hash->contextsize + 7) / 8]; + tmp = grub_cpu_to_le64 (sector << GRUB_DISK_SECTOR_BITS); + dev->iv_hash->init (ctx); + dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len); + dev->iv_hash->write (ctx, &tmp, sizeof (tmp)); + dev->iv_hash->final (ctx); + + grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv)); + } + break; + case GRUB_CRYPTODISK_MODE_IV_PLAIN64: + iv[1] = grub_cpu_to_le32 (sector >> 32); + case GRUB_CRYPTODISK_MODE_IV_PLAIN: + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + break; + case GRUB_CRYPTODISK_MODE_IV_BENBI: + { + grub_uint64_t num = (sector << dev->benbi_log) + 1; + iv[sz - 2] = grub_cpu_to_be32 (num >> 32); + iv[sz - 1] = grub_cpu_to_be32 (num & 0xFFFFFFFF); + } + break; + case GRUB_CRYPTODISK_MODE_IV_ESSIV: + iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv, + dev->cipher->cipher->blocksize); + if (err) + return err; + } + + switch (dev->mode) + { + case GRUB_CRYPTODISK_MODE_CBC: + err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, + GRUB_DISK_SECTOR_SIZE, iv); + if (err) + return err; + break; + + case GRUB_CRYPTODISK_MODE_PCBC: + err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, + GRUB_DISK_SECTOR_SIZE, iv); + if (err) + return err; + break; + case GRUB_CRYPTODISK_MODE_XTS: + { + int j; + err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, + dev->cipher->cipher->blocksize); + if (err) + return err; + + for (j = 0; j < GRUB_DISK_SECTOR_SIZE; + j += dev->cipher->cipher->blocksize) + { + grub_crypto_xor (data + i + j, data + i + j, iv, + dev->cipher->cipher->blocksize); + err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, + data + i + j, + dev->cipher->cipher->blocksize); + if (err) + return err; + grub_crypto_xor (data + i + j, data + i + j, iv, + dev->cipher->cipher->blocksize); + gf_mul_x ((grub_uint8_t *) iv); + } + } + break; + case GRUB_CRYPTODISK_MODE_LRW: + { + struct lrw_sector sec; + + generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv); + lrw_xor (&sec, dev, data + i); + + err = grub_crypto_ecb_decrypt (dev->cipher, data + i, + data + i, GRUB_DISK_SECTOR_SIZE); + if (err) + return err; + lrw_xor (&sec, dev, data + i); + } + break; + default: + return GPG_ERR_NOT_IMPLEMENTED; + } + sector++; + } + return GPG_ERR_NO_ERROR; +} + +gcry_err_code_t +grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize) +{ + gcry_err_code_t err; + int real_keysize; + + real_keysize = keysize; + if (dev->mode == GRUB_CRYPTODISK_MODE_XTS) + real_keysize /= 2; + if (dev->mode == GRUB_CRYPTODISK_MODE_LRW) + real_keysize -= dev->cipher->cipher->blocksize; + + /* Set the PBKDF2 output as the cipher key. */ + err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize); + if (err) + return err; + + /* Configure ESSIV if necessary. */ + if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV) + { + grub_size_t essiv_keysize = dev->essiv_hash->mdlen; + grub_uint8_t hashed_key[essiv_keysize]; + + grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize); + err = grub_crypto_cipher_set_key (dev->essiv_cipher, + hashed_key, essiv_keysize); + if (err) + return err; + } + if (dev->mode == GRUB_CRYPTODISK_MODE_XTS) + { + err = grub_crypto_cipher_set_key (dev->secondary_cipher, + key + real_keysize, + keysize / 2); + if (err) + return err; + } + + if (dev->mode == GRUB_CRYPTODISK_MODE_LRW) + { + int i; + grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES]; + + grub_free (dev->lrw_precalc); + grub_memcpy (dev->lrw_key, key + real_keysize, + dev->cipher->cipher->blocksize); + dev->lrw_precalc = grub_malloc (GRUB_DISK_SECTOR_SIZE); + if (!dev->lrw_precalc) + return GPG_ERR_OUT_OF_MEMORY; + grub_memset (idx, 0, GRUB_CRYPTODISK_GF_BYTES); + for (i = 0; i < GRUB_DISK_SECTOR_SIZE; + i += GRUB_CRYPTODISK_GF_BYTES) + { + idx[GRUB_CRYPTODISK_GF_BYTES - 1] = i / GRUB_CRYPTODISK_GF_BYTES; + gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key); + } + } + return GPG_ERR_NO_ERROR; +} + +static int +grub_cryptodisk_iterate (int (*hook) (const char *name), + grub_disk_pull_t pull) +{ + grub_cryptodisk_t i; + + if (pull != GRUB_DISK_PULL_NONE) + return 0; + + for (i = cryptodisk_list; i != NULL; i = i->next) + { + char buf[30]; + grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id); + if (hook (buf)) + return 1; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cryptodisk_open (const char *name, grub_disk_t disk, + grub_disk_pull_t pull __attribute__ ((unused))) +{ + grub_cryptodisk_t dev; + + if (grub_memcmp (name, "crypto", sizeof ("crypto") - 1) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + + if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0) + { + for (dev = cryptodisk_list; dev != NULL; dev = dev->next) + if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0) + break; + } + else + { + unsigned long id = grub_strtoul (name + sizeof ("crypto") - 1, 0, 0); + if (grub_errno) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + /* Search for requested device in the list of CRYPTODISK devices. */ + for (dev = cryptodisk_list; dev != NULL; dev = dev->next) + if (dev->id == id) + break; + } + if (!dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + +#ifdef GRUB_UTIL + if (dev->cheat) + { + if (dev->cheat_fd == -1) + dev->cheat_fd = open (dev->cheat, O_RDONLY); + if (dev->cheat_fd == -1) + return grub_error (GRUB_ERR_IO, "couldn't open %s: %s", + dev->cheat, strerror (errno)); + } +#endif + + if (!dev->source_disk) + { + grub_dprintf ("cryptodisk", "Opening device %s\n", name); + /* Try to open the source disk and populate the requested disk. */ + dev->source_disk = grub_disk_open (dev->source); + if (!dev->source_disk) + return grub_errno; + } + + disk->data = dev; + disk->total_sectors = dev->total_length; + disk->id = dev->id; + dev->ref++; + return GRUB_ERR_NONE; +} + +static void +grub_cryptodisk_close (grub_disk_t disk) +{ + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; + grub_dprintf ("cryptodisk", "Closing disk\n"); + + dev->ref--; + + if (dev->ref != 0) + return; +#ifdef GRUB_UTIL + if (dev->cheat) + { + close (dev->cheat_fd); + dev->cheat_fd = -1; + } +#endif + grub_disk_close (dev->source_disk); + dev->source_disk = NULL; +} + +static grub_err_t +grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; + grub_err_t err; + gcry_err_code_t gcry_err; + +#ifdef GRUB_UTIL + if (dev->cheat) + { + err = grub_util_fd_sector_seek (dev->cheat_fd, dev->cheat, sector); + if (err) + return err; + if (grub_util_fd_read (dev->cheat_fd, buf, size << GRUB_DISK_SECTOR_BITS) + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + return grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", + dev->cheat); + return GRUB_ERR_NONE; + } +#endif + + grub_dprintf ("cryptodisk", + "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%" + PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n", + size, sector, dev->offset); + + err = grub_disk_read (dev->source_disk, sector + dev->offset, 0, + size << GRUB_DISK_SECTOR_BITS, buf); + if (err) + { + grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err); + return err; + } + gcry_err = grub_cryptodisk_decrypt (dev, (grub_uint8_t *) buf, + size << GRUB_DISK_SECTOR_BITS, + sector); + return grub_crypto_gcry_error (gcry_err); +} + +static grub_err_t +grub_cryptodisk_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; +} + +#ifdef GRUB_UTIL +static grub_disk_memberlist_t +grub_cryptodisk_memberlist (grub_disk_t disk) +{ + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; + grub_disk_memberlist_t list = NULL; + + list = grub_malloc (sizeof (*list)); + if (list) + { + list->disk = dev->source_disk; + list->next = NULL; + } + + return list; +} +#endif + +static void +cryptodisk_cleanup (void) +{ + grub_cryptodisk_t dev = cryptodisk_list; + grub_cryptodisk_t tmp; + + while (dev != NULL) + { + grub_free (dev->source); + grub_free (dev->cipher); + grub_free (dev->secondary_cipher); + grub_free (dev->essiv_cipher); + tmp = dev->next; + grub_free (dev); + dev = tmp; + } +} + +grub_err_t +grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, + grub_disk_t source) +{ + newdev->source = grub_strdup (name); + if (!newdev->source) + { + grub_free (newdev); + return grub_errno; + } + + newdev->id = n++; + newdev->source_id = source->id; + newdev->source_dev_id = source->dev->id; + newdev->next = cryptodisk_list; + cryptodisk_list = newdev; + + return GRUB_ERR_NONE; +} + +grub_cryptodisk_t +grub_cryptodisk_get_by_uuid (const char *uuid) +{ + grub_cryptodisk_t dev; + for (dev = cryptodisk_list; dev != NULL; dev = dev->next) + if (grub_strcasecmp (dev->uuid, uuid) == 0) + return dev; + return NULL; +} + +grub_cryptodisk_t +grub_cryptodisk_get_by_source_disk (grub_disk_t disk) +{ + grub_cryptodisk_t dev; + for (dev = cryptodisk_list; dev != NULL; dev = dev->next) + if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id) + return dev; + return NULL; +} + +#ifdef GRUB_UTIL +grub_err_t +grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, + grub_disk_t source, const char *cheat) +{ + newdev->cheat = grub_strdup (cheat); + newdev->source = grub_strdup (name); + if (!newdev->source || !newdev->cheat) + { + grub_free (newdev->source); + grub_free (newdev->cheat); + return grub_errno; + } + + newdev->cheat_fd = -1; + newdev->source_id = source->id; + newdev->source_dev_id = source->dev->id; + newdev->id = n++; + newdev->next = cryptodisk_list; + cryptodisk_list = newdev; + + return GRUB_ERR_NONE; +} + +void +grub_util_cryptodisk_print_abstraction (grub_disk_t disk) +{ + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; + + grub_printf ("luks "); + + if (dev->cipher) + grub_printf ("%s ", dev->cipher->cipher->modname); + if (dev->secondary_cipher) + grub_printf ("%s ", dev->secondary_cipher->cipher->modname); + if (dev->essiv_cipher) + grub_printf ("%s ", dev->essiv_cipher->cipher->modname); + if (dev->hash) + grub_printf ("%s ", dev->hash->modname); + if (dev->essiv_hash) + grub_printf ("%s ", dev->essiv_hash->modname); + if (dev->iv_hash) + grub_printf ("%s ", dev->iv_hash->modname); +} +#endif + +static struct grub_disk_dev grub_cryptodisk_dev = { + .name = "cryptodisk", + .id = GRUB_DISK_DEVICE_CRYPTODISK_ID, + .iterate = grub_cryptodisk_iterate, + .open = grub_cryptodisk_open, + .close = grub_cryptodisk_close, + .read = grub_cryptodisk_read, + .write = grub_cryptodisk_write, +#ifdef GRUB_UTIL + .memberlist = grub_cryptodisk_memberlist, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (cryptodisk) +{ + grub_disk_dev_register (&grub_cryptodisk_dev); +} + +GRUB_MOD_FINI (cryptodisk) +{ + grub_disk_dev_unregister (&grub_cryptodisk_dev); + cryptodisk_cleanup (); +} diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c new file mode 100644 index 000000000..6af1de766 --- /dev/null +++ b/grub-core/disk/geli.c @@ -0,0 +1,515 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2010,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 . + */ + +/* This file is loosely based on FreeBSD geli implementation + (but no code was directly copied). FreeBSD geli is distributed under + following terms: */ +/*- + * Copyright (c) 2005-2006 Pawel Jakub Dawidek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct grub_geli_key +{ + grub_uint8_t iv_key[64]; + grub_uint8_t cipher_key[64]; + grub_uint8_t hmac[64]; +} __attribute__ ((packed)); + +struct grub_geli_phdr +{ + grub_uint8_t magic[16]; +#define GELI_MAGIC "GEOM::ELI" + grub_uint32_t version; + grub_uint32_t unused1; + grub_uint16_t alg; + grub_uint16_t keylen; + grub_uint16_t unused3[7]; + grub_uint8_t keys_used; + grub_uint32_t niter; + grub_uint8_t salt[64]; + struct grub_geli_key keys[2]; +} __attribute__ ((packed)); + +const char *algorithms[] = { + [0x0b] = "aes", +}; + +#define MAX_PASSPHRASE 256 + +static const struct grub_arg_option options[] = + { + {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, + {"all", 'a', 0, N_("Mount all."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static int check_uuid, have_it; +static char *search_uuid; + +static grub_cryptodisk_t +configure_ciphers (const struct grub_geli_phdr *header) +{ + grub_cryptodisk_t newdev; + grub_crypto_cipher_handle_t cipher = NULL; + const struct gcry_cipher_spec *ciph; + const char *ciphername = NULL; + const gcry_md_spec_t *hash = NULL, *iv_hash = NULL; + + /* Look for GELI magic sequence. */ + if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) + || grub_le_to_cpu32 (header->version) != 3) + { + grub_dprintf ("geli", "wrong magic %02x\n", header->magic[0]); + return NULL; + } + +#if 0 + optr = uuid; + for (iptr = header->uuid; iptr < &header->uuid[ARRAY_SIZE (header->uuid)]; + iptr++) + { + if (*iptr != '-') + *optr++ = *iptr; + } + *optr = 0; + + if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) + { + grub_dprintf ("luks", "%s != %s", uuid, search_uuid); + return NULL; + } +#endif + + if (grub_le_to_cpu16 (header->alg) >= ARRAY_SIZE (algorithms) + || algorithms[grub_le_to_cpu16 (header->alg)] == NULL) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher 0x%x unknown", + grub_le_to_cpu16 (header->alg)); + return NULL; + } + + ciphername = algorithms[grub_le_to_cpu16 (header->alg)]; + ciph = grub_crypto_lookup_cipher_by_name (ciphername); + if (!ciph) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", + ciphername); + return NULL; + } + + /* Configure the cipher used for the bulk data. */ + cipher = grub_crypto_cipher_open (ciph); + if (!cipher) + return NULL; + + if (grub_le_to_cpu16 (header->keylen) > 1024) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", + grub_le_to_cpu16 (header->keylen)); + return NULL; + } + + hash = grub_crypto_lookup_md_by_name ("sha512"); + if (!hash) + { + grub_crypto_cipher_close (cipher); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", + "sha512"); + return NULL; + } + + iv_hash = grub_crypto_lookup_md_by_name ("sha256"); + if (!hash) + { + grub_crypto_cipher_close (cipher); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", + "sha512"); + return NULL; + } + + newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); + if (!newdev) + return NULL; + newdev->cipher = cipher; + newdev->offset = 0; + newdev->source_disk = NULL; + newdev->benbi_log = 0; + newdev->mode = GRUB_CRYPTODISK_MODE_CBC; + newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH; + newdev->secondary_cipher = NULL; + newdev->essiv_cipher = NULL; + newdev->essiv_hash = NULL; + newdev->hash = hash; + newdev->iv_hash = iv_hash; +#if 0 + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); +#endif + return newdev; +} + +static grub_err_t +recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, + const char *name, grub_disk_t source __attribute__ ((unused))) +{ + grub_size_t keysize = grub_le_to_cpu16 (header->keylen) / 8; + grub_uint8_t digest[dev->hash->mdlen]; + grub_uint8_t geomkey[dev->hash->mdlen]; + grub_uint8_t verify_key[dev->hash->mdlen]; + grub_uint8_t pbkdf_key[64]; + grub_uint8_t zero[dev->cipher->cipher->blocksize]; + char passphrase[MAX_PASSPHRASE] = ""; + unsigned i; + gcry_err_code_t gcry_err; + + grub_memset (zero, 0, sizeof (zero)); + + grub_printf ("Attempting to decrypt master key...\n"); + + /* Get the passphrase from the user. */ + grub_printf ("Enter passphrase for %s (%s): ", name, dev->uuid); + if (!grub_password_get (passphrase, MAX_PASSPHRASE)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); + + /* Calculate the PBKDF2 of the user supplied passphrase. */ + gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, + grub_strlen (passphrase), + header->salt, + sizeof (header->salt), + grub_le_to_cpu32 (header->niter), + pbkdf_key, sizeof (pbkdf_key)); + + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + gcry_err = grub_crypto_hmac_buffer (dev->hash, NULL, 0, pbkdf_key, + sizeof (pbkdf_key), geomkey); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey, + sizeof (geomkey), "\1", 1, digest); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey, + sizeof (geomkey), "\0", 1, verify_key); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + grub_dprintf ("geli", "keylen = %" PRIuGRUB_SIZE "\n", keysize); + + /* Try to recover master key from each active keyslot. */ + for (i = 0; i < ARRAY_SIZE (header->keys); i++) + { + struct grub_geli_key candidate_key; + grub_uint8_t key_hmac[dev->hash->mdlen]; + + /* Check if keyslot is enabled. */ + if (! (header->keys_used & (1 << i))) + continue; + + grub_dprintf ("geli", "Trying keyslot %d\n", i); + + gcry_err = grub_crypto_cipher_set_key (dev->cipher, + digest, keysize); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + gcry_err = grub_crypto_cbc_decrypt (dev->cipher, &candidate_key, + &header->keys[i], + sizeof (candidate_key), + zero); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + gcry_err = grub_crypto_hmac_buffer (dev->hash, verify_key, + sizeof (verify_key), + &candidate_key, + (sizeof (candidate_key) + - sizeof (candidate_key.hmac)), + key_hmac); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + if (grub_memcmp (candidate_key.hmac, key_hmac, dev->hash->mdlen) != 0) + continue; + grub_printf ("Slot %d opened\n", i); + + /* Set the master key. */ + gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, + keysize); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + dev->iv_prefix_len = sizeof (candidate_key.iv_key); + grub_memcpy (dev->iv_prefix, candidate_key.iv_key, + sizeof (candidate_key.iv_key)); + + COMPILE_TIME_ASSERT (sizeof (dev->iv_prefix) >= sizeof (candidate_key.iv_key)); + + return GRUB_ERR_NONE; + } + + return GRUB_ACCESS_DENIED; +} + +static void +close (grub_cryptodisk_t luks) +{ + grub_crypto_cipher_close (luks->cipher); + grub_crypto_cipher_close (luks->secondary_cipher); + grub_crypto_cipher_close (luks->essiv_cipher); + grub_free (luks); +} + +static grub_err_t +grub_geli_scan_device_real (const char *name, grub_disk_t source) +{ + grub_err_t err; + struct grub_geli_phdr header; + grub_cryptodisk_t newdev, dev; + grub_disk_addr_t sector; + + grub_dprintf ("geli", "scanning %s\n", source->name); + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) + return GRUB_ERR_NONE; + + sector = grub_disk_get_size (source); + if (sector == GRUB_DISK_SIZE_UNKNOWN) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not a geli"); + + /* Read the LUKS header. */ + err = grub_disk_read (source, sector - 1, 0, sizeof (header), &header); + if (err) + return err; + + newdev = configure_ciphers (&header); + if (!newdev) + return grub_errno; + + newdev->total_length = grub_disk_get_size (source) - 1; + + err = recover_key (newdev, &header, name, source); + if (err) + { + close (newdev); + return err; + } + + grub_cryptodisk_insert (newdev, name, source); + + have_it = 1; + + return GRUB_ERR_NONE; +} + +#ifdef GRUB_UTIL +grub_err_t +grub_geli_cheat_mount (const char *sourcedev, const char *cheat) +{ + grub_err_t err; + struct grub_geli_phdr header; + grub_cryptodisk_t newdev, dev; + grub_disk_t source; + grub_disk_addr_t sector; + + /* Try to open disk. */ + source = grub_disk_open (sourcedev); + if (!source) + return grub_errno; + + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) + { + grub_disk_close (source); + return GRUB_ERR_NONE; + } + + sector = grub_disk_get_size (source); + if (sector == GRUB_DISK_SIZE_UNKNOWN) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not a geli"); + + /* Read the LUKS header. */ + err = grub_disk_read (source, sector - 1, 0, sizeof (header), &header); + if (err) + return err; + + newdev = configure_ciphers (&header); + if (!newdev) + { + grub_disk_close (source); + return grub_errno; + } + + newdev->total_length = grub_disk_get_size (source) - 1; + + err = grub_cryptodisk_cheat_insert (newdev, sourcedev, source, cheat); + grub_disk_close (source); + if (err) + grub_free (newdev); + + return err; +} +#endif + +static int +grub_geli_scan_device (const char *name) +{ + grub_err_t err; + grub_disk_t source; + + /* Try to open disk. */ + source = grub_disk_open (name); + if (!source) + return grub_errno; + + err = grub_geli_scan_device_real (name, source); + + grub_disk_close (source); + + if (err) + grub_print_error (); + return have_it && check_uuid ? 0 : 1; +} + +#ifdef GRUB_UTIL + +void +grub_util_geli_print_uuid (grub_disk_t disk) +{ + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; + grub_printf ("%s ", dev->uuid); +} +#endif + +static grub_err_t +grub_cmd_gelimount (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + + if (argc < 1 && !state[1].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + have_it = 0; + if (state[0].set) + { + grub_cryptodisk_t dev; + + dev = grub_cryptodisk_get_by_uuid (args[0]); + if (dev) + { + grub_dprintf ("luks", "already mounted as crypto%lu\n", dev->id); + return GRUB_ERR_NONE; + } + + check_uuid = 1; + search_uuid = args[0]; + grub_device_iterate (&grub_geli_scan_device); + search_uuid = NULL; + + if (!have_it) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); + return GRUB_ERR_NONE; + } + else if (state[1].set) + { + check_uuid = 0; + search_uuid = NULL; + grub_device_iterate (&grub_geli_scan_device); + search_uuid = NULL; + return GRUB_ERR_NONE; + } + else + { + grub_err_t err; + grub_disk_t disk; + grub_cryptodisk_t dev; + + check_uuid = 0; + search_uuid = NULL; + disk = grub_disk_open (args[0]); + if (!disk) + return grub_errno; + + dev = grub_cryptodisk_get_by_source_disk (disk); + if (dev) + { + grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); + grub_disk_close (disk); + return GRUB_ERR_NONE; + } + + err = grub_geli_scan_device_real (args[0], disk); + + grub_disk_close (disk); + + return err; + } +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT (geli) +{ + cmd = grub_register_extcmd ("gelimount", grub_cmd_gelimount, 0, + N_("SOURCE|-u UUID|-a"), + N_("Mount a GELI device."), options); +} + +GRUB_MOD_FINI (geli) +{ + grub_unregister_extcmd (cmd); +} diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 361beb756..0763da011 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -454,6 +454,8 @@ grub_luks_scan_device_real (const char *name, grub_disk_t source) if (!newdev) return grub_errno; + newdev->total_length = grub_disk_get_size (source) - newdev->offset; + err = luks_recover_key (newdev, &header, name, source); if (err) { @@ -502,6 +504,8 @@ grub_luks_cheat_mount (const char *sourcedev, const char *cheat) return grub_errno; } + newdev->total_length = grub_disk_get_size (source) - newdev->offset; + err = grub_cryptodisk_cheat_insert (newdev, sourcedev, source, cheat); grub_disk_close (source); if (err) diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 2f172ebf8..e6f55062b 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -193,9 +193,10 @@ grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size) gcry_err_code_t grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size) + void *out, const void *in, grub_size_t size) { - grub_uint8_t *inptr, *outptr, *end; + const grub_uint8_t *inptr; + grub_uint8_t *outptr, *end; if (!cipher->cipher->decrypt) return GPG_ERR_NOT_SUPPORTED; if (size % cipher->cipher->blocksize != 0) @@ -249,10 +250,11 @@ grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher, gcry_err_code_t grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size, + void *out, const void *in, grub_size_t size, void *iv) { - grub_uint8_t *inptr, *outptr, *end; + const grub_uint8_t *inptr; + grub_uint8_t *outptr, *end; grub_uint8_t ivt[cipher->cipher->blocksize]; if (!cipher->cipher->decrypt) return GPG_ERR_NOT_SUPPORTED; diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 62ed2015c..ab82da862 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -199,7 +199,7 @@ grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size); gcry_err_code_t grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size); + void *out, const void *in, grub_size_t size); gcry_err_code_t grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher, @@ -210,7 +210,7 @@ grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher, void *iv_in); gcry_err_code_t grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size, + void *out, const void *in, grub_size_t size, void *iv); void grub_cipher_register (gcry_cipher_spec_t *cipher); diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h new file mode 100644 index 000000000..284e599f2 --- /dev/null +++ b/include/grub/cryptodisk.h @@ -0,0 +1,99 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,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_CRYPTODISK_HEADER +#define GRUB_CRYPTODISK_HEADER 1 + +#include +#include + +typedef enum + { + GRUB_CRYPTODISK_MODE_ECB, + GRUB_CRYPTODISK_MODE_CBC, + GRUB_CRYPTODISK_MODE_PCBC, + GRUB_CRYPTODISK_MODE_XTS, + GRUB_CRYPTODISK_MODE_LRW + } grub_cryptodisk_mode_t; + +typedef enum + { + GRUB_CRYPTODISK_MODE_IV_NULL, + GRUB_CRYPTODISK_MODE_IV_PLAIN, + GRUB_CRYPTODISK_MODE_IV_PLAIN64, + GRUB_CRYPTODISK_MODE_IV_ESSIV, + GRUB_CRYPTODISK_MODE_IV_BENBI, + GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH + } grub_cryptodisk_mode_iv_t; + +#define GRUB_CRYPTODISK_MAX_UUID_LENGTH 63 + +#define GRUB_CRYPTODISK_GF_SIZE 128 +#define GRUB_CRYPTODISK_GF_BYTES (GRUB_CRYPTODISK_GF_SIZE / 8) + +struct grub_cryptodisk +{ + char *source; + grub_disk_addr_t offset; + grub_disk_addr_t total_length; + grub_disk_t source_disk; + int ref; + grub_crypto_cipher_handle_t cipher; + grub_crypto_cipher_handle_t secondary_cipher; + grub_crypto_cipher_handle_t essiv_cipher; + const gcry_md_spec_t *essiv_hash, *hash, *iv_hash; + grub_cryptodisk_mode_t mode; + grub_cryptodisk_mode_iv_t mode_iv; + int benbi_log; + unsigned long id, source_id; + enum grub_disk_dev_id source_dev_id; + char uuid[GRUB_CRYPTODISK_MAX_UUID_LENGTH + 1]; + grub_uint8_t lrw_key[GRUB_CRYPTODISK_GF_BYTES]; + grub_uint8_t *lrw_precalc; + grub_uint8_t iv_prefix[64]; + grub_size_t iv_prefix_len; +#ifdef GRUB_UTIL + char *cheat; + int cheat_fd; +#endif + struct grub_cryptodisk *next; +}; +typedef struct grub_cryptodisk *grub_cryptodisk_t; + +gcry_err_code_t +grub_cryptodisk_setkey (grub_cryptodisk_t dev, + grub_uint8_t *key, grub_size_t keysize); +gcry_err_code_t +grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, + grub_uint8_t * data, grub_size_t len, + grub_disk_addr_t sector); +grub_err_t +grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, + grub_disk_t source); +#ifdef GRUB_UTIL +grub_err_t +grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, + grub_disk_t source, const char *cheat); +void +grub_util_cryptodisk_print_abstraction (grub_disk_t disk); +#endif + +grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); +grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk); + +#endif diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 2adb2331d..48a5be1ca 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -308,8 +308,12 @@ fstest (int n, char **args) { char *argv[2] = { "-a", NULL}; if (mount_crypt) - if (execute_command ("luksmount", 1, argv)) - grub_util_error (_("luksmount command fails: %s"), grub_errmsg); + { + if (execute_command ("luksmount", 1, argv)) + grub_util_error (_("luksmount command fails: %s"), grub_errmsg); + if (execute_command ("gelimount", 1, argv)) + grub_util_error (_("gelimount command fails: %s"), grub_errmsg); + } } grub_lvm_fini (); From b44cd9e710c0bf0c1d1dfceef5ba883a4eebe98f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:34:32 +0200 Subject: [PATCH 0925/1414] zero-fill hash context for safety --- grub-core/disk/cryptodisk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 7f3b60bf5..dc6ca486e 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -200,6 +200,9 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, { grub_uint64_t tmp; grub_uint64_t ctx[(dev->iv_hash->contextsize + 7) / 8]; + + grub_memset (ctx, 0, sizeof (ctx)); + tmp = grub_cpu_to_le64 (sector << GRUB_DISK_SECTOR_BITS); dev->iv_hash->init (ctx); dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len); From 7ede8f8b5b62f7244f3cc9e9e6927cac43df006b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:36:04 +0200 Subject: [PATCH 0926/1414] support niter == 0 --- grub-core/disk/geli.c | 46 ++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 6af1de766..565498ece 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -205,7 +205,6 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, grub_uint8_t digest[dev->hash->mdlen]; grub_uint8_t geomkey[dev->hash->mdlen]; grub_uint8_t verify_key[dev->hash->mdlen]; - grub_uint8_t pbkdf_key[64]; grub_uint8_t zero[dev->cipher->cipher->blocksize]; char passphrase[MAX_PASSPHRASE] = ""; unsigned i; @@ -220,21 +219,40 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, if (!grub_password_get (passphrase, MAX_PASSPHRASE)) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); - /* Calculate the PBKDF2 of the user supplied passphrase. */ - gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, - grub_strlen (passphrase), - header->salt, - sizeof (header->salt), - grub_le_to_cpu32 (header->niter), - pbkdf_key, sizeof (pbkdf_key)); + /* Calculate the PBKDF2 of the user supplied passphrase. */ + if (grub_le_to_cpu32 (header->niter) != 0) + { + grub_uint8_t pbkdf_key[64]; + gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, + grub_strlen (passphrase), + header->salt, + sizeof (header->salt), + grub_le_to_cpu32 (header->niter), + pbkdf_key, sizeof (pbkdf_key)); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); - gcry_err = grub_crypto_hmac_buffer (dev->hash, NULL, 0, pbkdf_key, - sizeof (pbkdf_key), geomkey); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); + gcry_err = grub_crypto_hmac_buffer (dev->hash, NULL, 0, pbkdf_key, + sizeof (pbkdf_key), geomkey); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + } + else + { + struct grub_crypto_hmac_handle *hnd; + + hnd = grub_crypto_hmac_init (dev->hash, NULL, 0); + if (!hnd) + return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY); + + grub_crypto_hmac_write (hnd, header->salt, sizeof (header->salt)); + grub_crypto_hmac_write (hnd, passphrase, grub_strlen (passphrase)); + + gcry_err = grub_crypto_hmac_fini (hnd, geomkey); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + } gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey, sizeof (geomkey), "\1", 1, digest); From 972d86df5f68efecb9952fa994aa851bae44aa28 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:36:50 +0200 Subject: [PATCH 0927/1414] accept version 2 geli --- grub-core/disk/geli.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 565498ece..7d0c8621f 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -107,7 +107,8 @@ configure_ciphers (const struct grub_geli_phdr *header) /* Look for GELI magic sequence. */ if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header->version) != 3) + || grub_le_to_cpu32 (header->version) > 3 + || grub_le_to_cpu32 (header->version) < 2) { grub_dprintf ("geli", "wrong magic %02x\n", header->magic[0]); return NULL; From b6b4ea5fd1ee71062c05b89bd606d869ebc33517 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:37:23 +0200 Subject: [PATCH 0928/1414] Add IDs for more ciphers --- grub-core/disk/geli.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 7d0c8621f..843eb7d90 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -81,7 +81,14 @@ struct grub_geli_phdr } __attribute__ ((packed)); const char *algorithms[] = { + [0x01] = "des", + [0x02] = "3des", + [0x03] = "blowfish", + [0x04] = "cast5", + /* 0x05 is skipjack, but we don't have it. */ [0x0b] = "aes", + /* 0x10 is null. */ + [0x15] = "camellia128", }; #define MAX_PASSPHRASE 256 From 848c83e75c059b8463788ec1095b84158458c200 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:38:42 +0200 Subject: [PATCH 0929/1414] add few necessarry const qualifiers for pointers --- grub-core/lib/crypto.c | 3 ++- include/grub/crypto.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index e6f55062b..5098f0a66 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -345,7 +345,8 @@ grub_crypto_hmac_init (const struct gcry_md_spec *md, } void -grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data, +grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, + const void *data, grub_size_t datalen) { hnd->md->write (hnd->ctx, data, datalen); diff --git a/include/grub/crypto.h b/include/grub/crypto.h index ab82da862..baccbcd06 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -235,7 +235,8 @@ struct grub_crypto_hmac_handle * grub_crypto_hmac_init (const struct gcry_md_spec *md, const void *key, grub_size_t keylen); void -grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data, +grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, + const void *data, grub_size_t datalen); gcry_err_code_t grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out); From b094f07c2364b616452639db9184d9411f376f38 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 02:39:21 +0200 Subject: [PATCH 0930/1414] Don't set was_readable for new array --- grub-core/disk/raid.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 78453ac88..27a57d7fc 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -637,6 +637,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_raid_t raid __attribute__ ((unused))) { struct grub_raid_array *array = 0, *p; + int was_readable = 0; /* See whether the device is part of an array we have already seen a device from. */ @@ -647,6 +648,8 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, grub_free (new_array->uuid); array = p; + was_readable = grub_is_array_readable (array); + /* Do some checks before adding the device to the array. */ if (new_array->index >= array->allocated_devs) @@ -803,15 +806,11 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } /* Add the device to the array. */ - { - int was_readable = grub_is_array_readable (array); - - array->members[new_array->index].device = disk; - array->members[new_array->index].start_sector = start_sector; - array->nr_devs++; - if (!was_readable && grub_is_array_readable (array)) - array->became_readable_at = inscnt++; - } + array->members[new_array->index].device = disk; + array->members[new_array->index].start_sector = start_sector; + array->nr_devs++; + if (!was_readable && grub_is_array_readable (array)) + array->became_readable_at = inscnt++; return 0; } From 0c512b092c885733eb31aa1a12c6e7289c5e5ea1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 14:52:00 +0200 Subject: [PATCH 0931/1414] Fix a cache retrieving bug --- grub-core/kern/disk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 5439a02f6..30bc604f0 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -571,7 +571,8 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, if (data) { - grub_memcpy (buf, data, GRUB_DISK_CACHE_SIZE); + grub_memcpy (buf, data, + GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); sector += GRUB_DISK_CACHE_SIZE; buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); From 3e90811d884cab7a333ad9a4458732409be9f88f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 14:59:38 +0200 Subject: [PATCH 0932/1414] support non-512B sectors for geli --- grub-core/disk/cryptodisk.c | 50 +++++++++++++++++++++---------------- grub-core/disk/geli.c | 15 ++++++++++- grub-core/disk/luks.c | 1 + include/grub/cryptodisk.h | 7 ++++-- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 6dbd6bac6..4a716602e 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -35,7 +35,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ #define GF_POLYNOM 0x87 -#define GF_PER_SECTOR (GRUB_DISK_SECTOR_SIZE / GRUB_CRYPTODISK_GF_BYTES) +static inline int GF_PER_SECTOR (const struct grub_cryptodisk *dev) +{ + return 1U << (dev->log_sector_size - GRUB_CRYPTODISK_GF_LOG_BYTES); +} static grub_cryptodisk_t cryptodisk_list = NULL; static grub_uint8_t n = 0; @@ -44,7 +47,7 @@ static void gf_mul_x (grub_uint8_t *g) { int over = 0, over2 = 0; - int j; + unsigned j; for (j = 0; j < GRUB_CRYPTODISK_GF_BYTES; j++) { @@ -64,7 +67,7 @@ gf_mul_x_be (grub_uint8_t *g) int over = 0, over2 = 0; int j; - for (j = GRUB_CRYPTODISK_GF_BYTES - 1; j >= 0; j--) + for (j = (int) GRUB_CRYPTODISK_GF_BYTES - 1; j >= 0; j--) { over2 = !!(g[j] & 0x80); g[j] <<= 1; @@ -78,7 +81,7 @@ gf_mul_x_be (grub_uint8_t *g) static void gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) { - int i; + unsigned i; grub_uint8_t t[GRUB_CRYPTODISK_GF_BYTES]; grub_memset (o, 0, GRUB_CRYPTODISK_GF_BYTES); grub_memcpy (t, b, GRUB_CRYPTODISK_GF_BYTES); @@ -129,14 +132,15 @@ generate_lrw_sector (struct lrw_sector *sec, grub_uint16_t c; int j; grub_memcpy (idx, iv, GRUB_CRYPTODISK_GF_BYTES); - sec->low_byte = (idx[GRUB_CRYPTODISK_GF_BYTES - 1] & (GF_PER_SECTOR - 1)); - sec->low_byte_c = (((GF_PER_SECTOR - 1) & ~sec->low_byte) + 1); - idx[GRUB_CRYPTODISK_GF_BYTES - 1] &= ~(GF_PER_SECTOR - 1); + sec->low_byte = (idx[GRUB_CRYPTODISK_GF_BYTES - 1] + & (GF_PER_SECTOR (dev) - 1)); + sec->low_byte_c = (((GF_PER_SECTOR (dev) - 1) & ~sec->low_byte) + 1); + idx[GRUB_CRYPTODISK_GF_BYTES - 1] &= ~(GF_PER_SECTOR (dev) - 1); gf_mul_be (sec->low, dev->lrw_key, idx); if (!sec->low_byte) return; - c = idx[GRUB_CRYPTODISK_GF_BYTES - 1] + GF_PER_SECTOR; + c = idx[GRUB_CRYPTODISK_GF_BYTES - 1] + GF_PER_SECTOR (dev); if (c & 0x100) { for (j = GRUB_CRYPTODISK_GF_BYTES - 2; j >= 0; j--) @@ -155,9 +159,10 @@ lrw_xor (const struct lrw_sector *sec, const struct grub_cryptodisk *dev, grub_uint8_t *b) { - int i; + unsigned i; - for (i = 0; i < sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; i += GRUB_CRYPTODISK_GF_BYTES) + for (i = 0; i < sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; + i += GRUB_CRYPTODISK_GF_BYTES) grub_crypto_xor (b + i, b + i, sec->low, GRUB_CRYPTODISK_GF_BYTES); grub_crypto_xor (b, b, dev->lrw_precalc + GRUB_CRYPTODISK_GF_BYTES * sec->low_byte, sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES); @@ -165,7 +170,7 @@ lrw_xor (const struct lrw_sector *sec, return; for (i = sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; - i < GRUB_DISK_SECTOR_SIZE; i += GRUB_CRYPTODISK_GF_BYTES) + i < (1U << dev->log_sector_size); i += GRUB_CRYPTODISK_GF_BYTES) grub_crypto_xor (b + i, b + i, sec->high, GRUB_CRYPTODISK_GF_BYTES); grub_crypto_xor (b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES, b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES, @@ -184,7 +189,7 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, if (dev->mode == GRUB_CRYPTODISK_MODE_ECB) return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); - for (i = 0; i < len; i += GRUB_DISK_SECTOR_SIZE) + for (i = 0; i < len; i += (1U << dev->log_sector_size)) { grub_size_t sz = ((dev->cipher->cipher->blocksize + sizeof (grub_uint32_t) - 1) @@ -203,7 +208,7 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, grub_memset (ctx, 0, sizeof (ctx)); - tmp = grub_cpu_to_le64 (sector << GRUB_DISK_SECTOR_BITS); + tmp = grub_cpu_to_le64 (sector << dev->log_sector_size); dev->iv_hash->init (ctx); dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len); dev->iv_hash->write (ctx, &tmp, sizeof (tmp)); @@ -236,26 +241,26 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, { case GRUB_CRYPTODISK_MODE_CBC: err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, - GRUB_DISK_SECTOR_SIZE, iv); + (1U << dev->log_sector_size), iv); if (err) return err; break; case GRUB_CRYPTODISK_MODE_PCBC: err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, - GRUB_DISK_SECTOR_SIZE, iv); + (1U << dev->log_sector_size), iv); if (err) return err; break; case GRUB_CRYPTODISK_MODE_XTS: { - int j; + unsigned j; err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, dev->cipher->cipher->blocksize); if (err) return err; - for (j = 0; j < GRUB_DISK_SECTOR_SIZE; + for (j = 0; j < (1U << dev->log_sector_size); j += dev->cipher->cipher->blocksize) { grub_crypto_xor (data + i + j, data + i + j, iv, @@ -279,7 +284,8 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, lrw_xor (&sec, dev, data + i); err = grub_crypto_ecb_decrypt (dev->cipher, data + i, - data + i, GRUB_DISK_SECTOR_SIZE); + data + i, + (1U << dev->log_sector_size)); if (err) return err; lrw_xor (&sec, dev, data + i); @@ -333,17 +339,17 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke if (dev->mode == GRUB_CRYPTODISK_MODE_LRW) { - int i; + unsigned i; grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES]; grub_free (dev->lrw_precalc); grub_memcpy (dev->lrw_key, key + real_keysize, dev->cipher->cipher->blocksize); - dev->lrw_precalc = grub_malloc (GRUB_DISK_SECTOR_SIZE); + dev->lrw_precalc = grub_malloc ((1U << dev->log_sector_size)); if (!dev->lrw_precalc) return GPG_ERR_OUT_OF_MEMORY; grub_memset (idx, 0, GRUB_CRYPTODISK_GF_BYTES); - for (i = 0; i < GRUB_DISK_SECTOR_SIZE; + for (i = 0; i < (1U << dev->log_sector_size); i += GRUB_CRYPTODISK_GF_BYTES) { idx[GRUB_CRYPTODISK_GF_BYTES - 1] = i / GRUB_CRYPTODISK_GF_BYTES; @@ -401,6 +407,8 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk, if (!dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + disk->log_sector_size = dev->log_sector_size; + #ifdef GRUB_UTIL if (dev->cheat) { diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 843eb7d90..3c2cbb9ce 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -73,7 +73,8 @@ struct grub_geli_phdr grub_uint32_t unused1; grub_uint16_t alg; grub_uint16_t keylen; - grub_uint16_t unused3[7]; + grub_uint16_t unused3[5]; + grub_uint32_t sector_size; grub_uint8_t keys_used; grub_uint32_t niter; grub_uint8_t salt[64]; @@ -120,6 +121,14 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_dprintf ("geli", "wrong magic %02x\n", header->magic[0]); return NULL; } + if ((grub_le_to_cpu32 (header->sector_size) + & (grub_le_to_cpu32 (header->sector_size) - 1)) + || grub_le_to_cpu32 (header->sector_size) == 0) + { + grub_dprintf ("geli", "incorrect sector size %d\n", + grub_le_to_cpu32 (header->sector_size)); + return NULL; + } #if 0 optr = uuid; @@ -199,6 +208,10 @@ configure_ciphers (const struct grub_geli_phdr *header) newdev->essiv_hash = NULL; newdev->hash = hash; newdev->iv_hash = iv_hash; + + for (newdev->log_sector_size = 0; + (1U << newdev->log_sector_size) < grub_le_to_cpu32 (header->sector_size); + newdev->log_sector_size++); #if 0 grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); #endif diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 0763da011..7c39002b8 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -283,6 +283,7 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->essiv_cipher = essiv_cipher; newdev->essiv_hash = essiv_hash; newdev->hash = hash; + newdev->log_sector_size = 9; grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); return newdev; } diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 284e599f2..11181f42d 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -43,8 +43,10 @@ typedef enum #define GRUB_CRYPTODISK_MAX_UUID_LENGTH 63 -#define GRUB_CRYPTODISK_GF_SIZE 128 -#define GRUB_CRYPTODISK_GF_BYTES (GRUB_CRYPTODISK_GF_SIZE / 8) +#define GRUB_CRYPTODISK_GF_LOG_SIZE 7 +#define GRUB_CRYPTODISK_GF_SIZE (1U << GRUB_CRYPTODISK_GF_LOG_SIZE) +#define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) +#define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) struct grub_cryptodisk { @@ -71,6 +73,7 @@ struct grub_cryptodisk char *cheat; int cheat_fd; #endif + int log_sector_size; struct grub_cryptodisk *next; }; typedef struct grub_cryptodisk *grub_cryptodisk_t; From 88ac3146d6ad5d17788821fa4aa296271a2c0550 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 17:15:55 +0200 Subject: [PATCH 0933/1414] geli v5 (including rekeying support) --- grub-core/disk/cryptodisk.c | 20 ++++++++++++-- grub-core/disk/geli.c | 53 ++++++++++++++++++++++++++++++++----- grub-core/lib/crypto.c | 2 +- include/grub/crypto.h | 2 +- include/grub/cryptodisk.h | 13 ++++++++- 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 4a716602e..5ab607146 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -178,7 +178,7 @@ lrw_xor (const struct lrw_sector *sec, } gcry_err_code_t -grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, +grub_cryptodisk_decrypt (struct grub_cryptodisk *dev, grub_uint8_t * data, grub_size_t len, grub_disk_addr_t sector) { @@ -186,7 +186,7 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, gcry_err_code_t err; /* The only mode without IV. */ - if (dev->mode == GRUB_CRYPTODISK_MODE_ECB) + if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey) return grub_crypto_ecb_decrypt (dev->cipher, data, data, len); for (i = 0; i < len; i += (1U << dev->log_sector_size)) @@ -196,6 +196,18 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, / sizeof (grub_uint32_t)); grub_uint32_t iv[sz]; + if (dev->rekey) + { + grub_uint64_t zone = sector >> dev->rekey_shift; + if (zone != dev->last_rekey) + { + err = dev->rekey (dev, zone); + if (err) + return err; + dev->last_rekey = zone; + } + } + grub_memset (iv, 0, sz * sizeof (iv[0])); switch (dev->mode_iv) { @@ -291,6 +303,10 @@ grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, lrw_xor (&sec, dev, data + i); } break; + case GRUB_CRYPTODISK_MODE_ECB: + grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i, + (1U << dev->log_sector_size)); + break; default: return GPG_ERR_NOT_IMPLEMENTED; } diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 3c2cbb9ce..b3fa10cc5 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -104,6 +104,28 @@ static const struct grub_arg_option options[] = static int check_uuid, have_it; static char *search_uuid; +static gcry_err_code_t +geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) +{ + gcry_err_code_t gcry_err; + const struct { + char magic[4]; + grub_uint64_t zone; + } __attribute__ ((packed)) tohash + = { {'e', 'k', 'e', 'y'}, grub_cpu_to_le64 (zoneno) }; + grub_uint64_t key[(dev->hash->mdlen + 7) / 8]; + + grub_dprintf ("geli", "rekeying %" PRIuGRUB_UINT64_T " keysize=%d\n", + zoneno, dev->rekey_derived_size); + gcry_err = grub_crypto_hmac_buffer (dev->hash, dev->rekey_key, 64, + &tohash, sizeof (tohash), key); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + + return grub_cryptodisk_setkey (dev, (grub_uint8_t *) key, + dev->rekey_derived_size); +} + static grub_cryptodisk_t configure_ciphers (const struct grub_geli_phdr *header) { @@ -115,8 +137,8 @@ configure_ciphers (const struct grub_geli_phdr *header) /* Look for GELI magic sequence. */ if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header->version) > 3 - || grub_le_to_cpu32 (header->version) < 2) + || grub_le_to_cpu32 (header->version) > 5 + || grub_le_to_cpu32 (header->version) < 1) { grub_dprintf ("geli", "wrong magic %02x\n", header->magic[0]); return NULL; @@ -212,6 +234,12 @@ configure_ciphers (const struct grub_geli_phdr *header) for (newdev->log_sector_size = 0; (1U << newdev->log_sector_size) < grub_le_to_cpu32 (header->sector_size); newdev->log_sector_size++); + + if (grub_le_to_cpu32 (header->version) >= 5) + { + newdev->rekey = geli_rekey; + newdev->rekey_shift = 20; + } #if 0 grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); #endif @@ -325,10 +353,23 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, grub_printf ("Slot %d opened\n", i); /* Set the master key. */ - gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, - keysize); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); + if (!dev->rekey) + { + gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, + keysize); + if (gcry_err) + return grub_crypto_gcry_error (gcry_err); + } + else + { + /* For a reason I don't know, the IV key is used in rekeying. */ + grub_memcpy (dev->rekey_key, candidate_key.iv_key, + sizeof (candidate_key.iv_key)); + dev->rekey_derived_size = keysize; + dev->last_rekey = -1; + COMPILE_TIME_ASSERT (sizeof (dev->rekey_key) + >= sizeof (candidate_key.iv_key)); + } dev->iv_prefix_len = sizeof (candidate_key.iv_key); grub_memcpy (dev->iv_prefix, candidate_key.iv_key, diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 5098f0a66..8876cc326 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -388,7 +388,7 @@ grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out) gcry_err_code_t grub_crypto_hmac_buffer (const struct gcry_md_spec *md, const void *key, grub_size_t keylen, - void *data, grub_size_t datalen, void *out) + const void *data, grub_size_t datalen, void *out) { struct grub_crypto_hmac_handle *hnd; diff --git a/include/grub/crypto.h b/include/grub/crypto.h index baccbcd06..10368d99f 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -244,7 +244,7 @@ grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out); gcry_err_code_t grub_crypto_hmac_buffer (const struct gcry_md_spec *md, const void *key, grub_size_t keylen, - void *data, grub_size_t datalen, void *out); + const void *data, grub_size_t datalen, void *out); extern gcry_md_spec_t _gcry_digest_spec_md5; extern gcry_md_spec_t _gcry_digest_spec_sha1; diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 11181f42d..2da3f76d2 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -48,6 +48,12 @@ typedef enum #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) +struct grub_cryptodisk; + +typedef gcry_err_code_t +(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, + grub_uint64_t zoneno); + struct grub_cryptodisk { char *source; @@ -74,6 +80,11 @@ struct grub_cryptodisk int cheat_fd; #endif int log_sector_size; + grub_cryptodisk_rekey_func_t rekey; + int rekey_shift; + grub_uint8_t rekey_key[64]; + grub_uint64_t last_rekey; + int rekey_derived_size; struct grub_cryptodisk *next; }; typedef struct grub_cryptodisk *grub_cryptodisk_t; @@ -82,7 +93,7 @@ gcry_err_code_t grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize); gcry_err_code_t -grub_cryptodisk_decrypt (const struct grub_cryptodisk *dev, +grub_cryptodisk_decrypt (struct grub_cryptodisk *dev, grub_uint8_t * data, grub_size_t len, grub_disk_addr_t sector); grub_err_t From 574d268020510d7996c1e263f1fac79aefeaf854 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 17:18:18 +0200 Subject: [PATCH 0934/1414] Add few FIXME comments --- grub-core/disk/geli.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index b3fa10cc5..6ffc7c26e 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -81,14 +81,19 @@ struct grub_geli_phdr struct grub_geli_key keys[2]; } __attribute__ ((packed)); +/* FIXME: support big-endian pre-version-4 volumes. */ +/* FIXME: support for keyfiles. */ +/* FIXME: support for HMAC. */ +/* FIXME: support for UUID. */ +/* FIXME: support for mounting all boot volumes. */ const char *algorithms[] = { [0x01] = "des", [0x02] = "3des", [0x03] = "blowfish", [0x04] = "cast5", - /* 0x05 is skipjack, but we don't have it. */ + /* FIXME: 0x05 is skipjack, but we don't have it. */ [0x0b] = "aes", - /* 0x10 is null. */ + /* FIXME: 0x10 is null. */ [0x15] = "camellia128", }; From 171e2be183b086b1560630f02231ee15771176a7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 17:41:50 +0200 Subject: [PATCH 0935/1414] geli xts support --- grub-core/disk/cryptodisk.c | 5 +++++ grub-core/disk/geli.c | 34 ++++++++++++++++++++++++++++------ include/grub/cryptodisk.h | 1 + 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 5ab607146..bf0b1cde2 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -234,6 +234,11 @@ grub_cryptodisk_decrypt (struct grub_cryptodisk *dev, case GRUB_CRYPTODISK_MODE_IV_PLAIN: iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); break; + case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64: + iv[1] = grub_cpu_to_le32 (sector >> (32 - dev->log_sector_size)); + iv[0] = grub_cpu_to_le32 ((sector << dev->log_sector_size) + & 0xFFFFFFFF); + break; case GRUB_CRYPTODISK_MODE_IV_BENBI: { grub_uint64_t num = (sector << dev->benbi_log) + 1; diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 6ffc7c26e..334a06340 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -95,6 +95,7 @@ const char *algorithms[] = { [0x0b] = "aes", /* FIXME: 0x10 is null. */ [0x15] = "camellia128", + [0x16] = "aes" }; #define MAX_PASSPHRASE 256 @@ -135,7 +136,7 @@ static grub_cryptodisk_t configure_ciphers (const struct grub_geli_phdr *header) { grub_cryptodisk_t newdev; - grub_crypto_cipher_handle_t cipher = NULL; + grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; const struct gcry_cipher_spec *ciph; const char *ciphername = NULL; const gcry_md_spec_t *hash = NULL, *iv_hash = NULL; @@ -196,6 +197,13 @@ configure_ciphers (const struct grub_geli_phdr *header) if (!cipher) return NULL; + if (grub_le_to_cpu16 (header->alg) == 0x16) + { + secondary_cipher = grub_crypto_cipher_open (ciph); + if (!secondary_cipher) + return NULL; + } + if (grub_le_to_cpu16 (header->keylen) > 1024) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", @@ -225,12 +233,20 @@ configure_ciphers (const struct grub_geli_phdr *header) if (!newdev) return NULL; newdev->cipher = cipher; + newdev->secondary_cipher = secondary_cipher; newdev->offset = 0; newdev->source_disk = NULL; newdev->benbi_log = 0; - newdev->mode = GRUB_CRYPTODISK_MODE_CBC; - newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH; - newdev->secondary_cipher = NULL; + if (grub_le_to_cpu16 (header->alg) == 0x16) + { + newdev->mode = GRUB_CRYPTODISK_MODE_XTS; + newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64; + } + else + { + newdev->mode = GRUB_CRYPTODISK_MODE_CBC; + newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH; + } newdev->essiv_cipher = NULL; newdev->essiv_hash = NULL; newdev->hash = hash; @@ -360,17 +376,23 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, /* Set the master key. */ if (!dev->rekey) { + grub_size_t real_keysize = keysize; + if (grub_le_to_cpu16 (header->alg) == 0x16) + real_keysize *= 2; gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, - keysize); + real_keysize); if (gcry_err) return grub_crypto_gcry_error (gcry_err); } else { + grub_size_t real_keysize = keysize; + if (grub_le_to_cpu16 (header->alg) == 0x16) + real_keysize *= 2; /* For a reason I don't know, the IV key is used in rekeying. */ grub_memcpy (dev->rekey_key, candidate_key.iv_key, sizeof (candidate_key.iv_key)); - dev->rekey_derived_size = keysize; + dev->rekey_derived_size = real_keysize; dev->last_rekey = -1; COMPILE_TIME_ASSERT (sizeof (dev->rekey_key) >= sizeof (candidate_key.iv_key)); diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 2da3f76d2..1911c04be 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -38,6 +38,7 @@ typedef enum GRUB_CRYPTODISK_MODE_IV_PLAIN64, GRUB_CRYPTODISK_MODE_IV_ESSIV, GRUB_CRYPTODISK_MODE_IV_BENBI, + GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64, GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH } grub_cryptodisk_mode_iv_t; From 371a8f1183f2696b1a58e410d89ff131cfc830a7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 17:50:22 +0200 Subject: [PATCH 0936/1414] Fix a potential buffer overflow --- grub-core/disk/luks.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 7c39002b8..3f98dfc87 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -32,7 +32,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define MAX_PASSPHRASE 256 #define LUKS_KEY_ENABLED 0x00AC71F3 -#define LUKS_STRIPES 4000 /* On disk LUKS header */ struct grub_luks_phdr @@ -301,10 +300,16 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, unsigned i; grub_size_t length; grub_err_t err; + grub_size_t max_stripes = 1; grub_printf ("Attempting to decrypt master key...\n"); - split_key = grub_malloc (keysize * LUKS_STRIPES); + for (i = 0; i < ARRAY_SIZE (header->keyblock); i++) + if (grub_be_to_cpu32 (header->keyblock[i].active) == LUKS_KEY_ENABLED + && grub_be_to_cpu32 (header->keyblock[i].stripes) > max_stripes) + max_stripes = grub_be_to_cpu32 (header->keyblock[i].stripes); + + split_key = grub_malloc (keysize * max_stripes); if (!split_key) return grub_errno; @@ -351,8 +356,7 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, return grub_crypto_gcry_error (gcry_err); } - length = (grub_be_to_cpu32 (header->keyBytes) - * grub_be_to_cpu32 (header->keyblock[i].stripes)); + length = (keysize * grub_be_to_cpu32 (header->keyblock[i].stripes)); /* Read and decrypt the key material from the disk. */ err = grub_disk_read (source, From 7efb5c9eeaad83e8eb2fdcde0fd182828d157610 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 20:37:56 +0200 Subject: [PATCH 0937/1414] Use hardcoded reference to sha512 and sha256 in geli rather than runtime lookup since they are always used --- Makefile.util.def | 12 ++++++++++++ grub-core/disk/geli.c | 23 ++--------------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index fe9e8c036..51771b9fa 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -108,6 +108,7 @@ program = { common = util/bin2h.c; ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; mansection = 1; @@ -138,6 +139,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -150,6 +152,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -162,6 +165,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -195,6 +199,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL)'; condition = COND_GRUB_PE2ELF; @@ -228,6 +233,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; @@ -248,6 +254,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -277,6 +284,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; @@ -292,6 +300,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)'; @@ -306,6 +315,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -616,6 +626,7 @@ program = { cflags = -Wno-format; ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -629,6 +640,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; + ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 334a06340..b86e363c7 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -139,7 +139,6 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; const struct gcry_cipher_spec *ciph; const char *ciphername = NULL; - const gcry_md_spec_t *hash = NULL, *iv_hash = NULL; /* Look for GELI magic sequence. */ if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) @@ -211,24 +210,6 @@ configure_ciphers (const struct grub_geli_phdr *header) return NULL; } - hash = grub_crypto_lookup_md_by_name ("sha512"); - if (!hash) - { - grub_crypto_cipher_close (cipher); - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", - "sha512"); - return NULL; - } - - iv_hash = grub_crypto_lookup_md_by_name ("sha256"); - if (!hash) - { - grub_crypto_cipher_close (cipher); - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", - "sha512"); - return NULL; - } - newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); if (!newdev) return NULL; @@ -249,8 +230,8 @@ configure_ciphers (const struct grub_geli_phdr *header) } newdev->essiv_cipher = NULL; newdev->essiv_hash = NULL; - newdev->hash = hash; - newdev->iv_hash = iv_hash; + newdev->hash = GRUB_MD_SHA512; + newdev->iv_hash = GRUB_MD_SHA256; for (newdev->log_sector_size = 0; (1U << newdev->log_sector_size) < grub_le_to_cpu32 (header->sector_size); From 23432f6542506794cbcf1d3b75b1e9d3fe284ad4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 21:11:14 +0200 Subject: [PATCH 0938/1414] support UUID for geli --- grub-core/disk/geli.c | 41 +++++++++++++++++++++++++++++---------- grub-core/disk/luks.c | 1 + include/grub/cryptodisk.h | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index b86e363c7..104200546 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -84,7 +84,6 @@ struct grub_geli_phdr /* FIXME: support big-endian pre-version-4 volumes. */ /* FIXME: support for keyfiles. */ /* FIXME: support for HMAC. */ -/* FIXME: support for UUID. */ /* FIXME: support for mounting all boot volumes. */ const char *algorithms[] = { [0x01] = "des", @@ -132,6 +131,18 @@ geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) dev->rekey_derived_size); } +static inline int +ascii2hex (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; +} + static grub_cryptodisk_t configure_ciphers (const struct grub_geli_phdr *header) { @@ -139,6 +150,11 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; const struct gcry_cipher_spec *ciph; const char *ciphername = NULL; + char uuid[GRUB_MD_SHA256->mdlen * 2 + 1]; + grub_uint8_t uuidbin[GRUB_MD_SHA256->mdlen]; + grub_uint8_t *iptr; + char *optr; + gcry_err_code_t gcry_err; /* Look for GELI magic sequence. */ if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) @@ -157,13 +173,19 @@ configure_ciphers (const struct grub_geli_phdr *header) return NULL; } -#if 0 - optr = uuid; - for (iptr = header->uuid; iptr < &header->uuid[ARRAY_SIZE (header->uuid)]; - iptr++) + gcry_err = grub_crypto_hmac_buffer (GRUB_MD_SHA256, + header->salt, sizeof (header->salt), + "uuid", sizeof ("uuid") - 1, uuidbin); + if (gcry_err) { - if (*iptr != '-') - *optr++ = *iptr; + grub_crypto_gcry_error (gcry_err); + return NULL; + } + optr = uuid; + for (iptr = uuidbin; iptr < &uuidbin[ARRAY_SIZE (uuidbin)]; iptr++) + { + grub_snprintf (optr, 3, "%02x", *iptr); + optr += 2; } *optr = 0; @@ -172,7 +194,6 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_dprintf ("luks", "%s != %s", uuid, search_uuid); return NULL; } -#endif if (grub_le_to_cpu16 (header->alg) >= ARRAY_SIZE (algorithms) || algorithms[grub_le_to_cpu16 (header->alg)] == NULL) @@ -242,9 +263,9 @@ configure_ciphers (const struct grub_geli_phdr *header) newdev->rekey = geli_rekey; newdev->rekey_shift = 20; } -#if 0 + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); -#endif + COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= 32 * 2 + 1); return newdev; } diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 3f98dfc87..a94b3cc52 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -284,6 +284,7 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->hash = hash; newdev->log_sector_size = 9; grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); + COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); return newdev; } diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 1911c04be..169fb119d 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -42,7 +42,7 @@ typedef enum GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH } grub_cryptodisk_mode_iv_t; -#define GRUB_CRYPTODISK_MAX_UUID_LENGTH 63 +#define GRUB_CRYPTODISK_MAX_UUID_LENGTH 71 #define GRUB_CRYPTODISK_GF_LOG_SIZE 7 #define GRUB_CRYPTODISK_GF_SIZE (1U << GRUB_CRYPTODISK_GF_LOG_SIZE) From 8358d7f22154b26c94d440e5c76e6287dfdf1372 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 21:40:13 +0200 Subject: [PATCH 0939/1414] Skip one-time volumes and add option for skipping non-boot volumes --- grub-core/disk/geli.c | 36 +++++++++++++++++++++++++++++------- grub-core/disk/luks.c | 2 +- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 104200546..8731d3065 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -70,7 +70,7 @@ struct grub_geli_phdr grub_uint8_t magic[16]; #define GELI_MAGIC "GEOM::ELI" grub_uint32_t version; - grub_uint32_t unused1; + grub_uint32_t flags; grub_uint16_t alg; grub_uint16_t keylen; grub_uint16_t unused3[5]; @@ -81,6 +81,12 @@ struct grub_geli_phdr struct grub_geli_key keys[2]; } __attribute__ ((packed)); +enum + { + GRUB_GELI_FLAGS_ONETIME = 1, + GRUB_GELI_FLAGS_BOOT = 2, + }; + /* FIXME: support big-endian pre-version-4 volumes. */ /* FIXME: support for keyfiles. */ /* FIXME: support for HMAC. */ @@ -103,10 +109,11 @@ static const struct grub_arg_option options[] = { {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, {"all", 'a', 0, N_("Mount all."), 0, 0}, + {"boot", 'b', 0, N_("Mount all volumes marked as boot."), 0, 0}, {0, 0, 0, 0, 0, 0} }; -static int check_uuid, have_it; +static int check_uuid, check_boot, have_it; static char *search_uuid; static gcry_err_code_t @@ -171,7 +178,19 @@ configure_ciphers (const struct grub_geli_phdr *header) grub_dprintf ("geli", "incorrect sector size %d\n", grub_le_to_cpu32 (header->sector_size)); return NULL; - } + } + + if (grub_le_to_cpu32 (header->flags) & GRUB_GELI_FLAGS_ONETIME) + { + grub_dprintf ("geli", "skipping one-time volume\n"); + return NULL; + } + + if (check_boot && !(grub_le_to_cpu32 (header->flags) & GRUB_GELI_FLAGS_BOOT)) + { + grub_dprintf ("geli", "not a boot volume\n"); + return NULL; + } gcry_err = grub_crypto_hmac_buffer (GRUB_MD_SHA256, header->salt, sizeof (header->salt), @@ -191,7 +210,7 @@ configure_ciphers (const struct grub_geli_phdr *header) if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) { - grub_dprintf ("luks", "%s != %s", uuid, search_uuid); + grub_dprintf ("geli", "%s != %s\n", uuid, search_uuid); return NULL; } @@ -549,7 +568,7 @@ grub_cmd_gelimount (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; - if (argc < 1 && !state[1].set) + if (argc < 1 && !state[1].set && !state[2].set) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); have_it = 0; @@ -565,6 +584,7 @@ grub_cmd_gelimount (grub_extcmd_context_t ctxt, int argc, char **args) } check_uuid = 1; + check_boot = state[2].set; search_uuid = args[0]; grub_device_iterate (&grub_geli_scan_device); search_uuid = NULL; @@ -573,10 +593,11 @@ grub_cmd_gelimount (grub_extcmd_context_t ctxt, int argc, char **args) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); return GRUB_ERR_NONE; } - else if (state[1].set) + else if (state[1].set || (argc == 0 && state[2].set)) { check_uuid = 0; search_uuid = NULL; + check_boot = state[2].set; grub_device_iterate (&grub_geli_scan_device); search_uuid = NULL; return GRUB_ERR_NONE; @@ -589,6 +610,7 @@ grub_cmd_gelimount (grub_extcmd_context_t ctxt, int argc, char **args) check_uuid = 0; search_uuid = NULL; + check_boot = state[2].set; disk = grub_disk_open (args[0]); if (!disk) return grub_errno; @@ -614,7 +636,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (geli) { cmd = grub_register_extcmd ("gelimount", grub_cmd_gelimount, 0, - N_("SOURCE|-u UUID|-a"), + N_("SOURCE|-u UUID|-a|-b"), N_("Mount a GELI device."), options); } diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index a94b3cc52..aa23e2e35 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -109,7 +109,7 @@ configure_ciphers (const struct grub_luks_phdr *header) if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) { - grub_dprintf ("luks", "%s != %s", uuid, search_uuid); + grub_dprintf ("luks", "%s != %s\n", uuid, search_uuid); return NULL; } From f718594e32da770ac412d1a02a2002c81d2302c2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 24 Apr 2011 21:41:49 +0200 Subject: [PATCH 0940/1414] update fixme --- grub-core/disk/geli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 8731d3065..1353be172 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -87,10 +87,10 @@ enum GRUB_GELI_FLAGS_BOOT = 2, }; +/* FIXME: support version 0. */ /* FIXME: support big-endian pre-version-4 volumes. */ /* FIXME: support for keyfiles. */ /* FIXME: support for HMAC. */ -/* FIXME: support for mounting all boot volumes. */ const char *algorithms[] = { [0x01] = "des", [0x02] = "3des", From d7bdab32b8e9e17c0111536b357189f72e6f330d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Apr 2011 14:46:47 +0200 Subject: [PATCH 0941/1414] fix linking trouble on FreeBSD --- Makefile.util.def | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 51771b9fa..3125b8b30 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -107,8 +107,8 @@ program = { name = grub-bin2h; common = util/bin2h.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER)'; mansection = 1; @@ -123,8 +123,8 @@ program = { extra_dist = util/grub-mkimagexx.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBLZMA)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; @@ -138,8 +138,8 @@ program = { common = util/grub-mkrelpath.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -151,8 +151,8 @@ program = { common = util/grub-script-check.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -164,8 +164,8 @@ program = { common = util/grub-editenv.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -177,8 +177,8 @@ program = { common = util/grub-mkpasswd-pbkdf2.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cflags = '$(CFLAGS_GCRY)'; @@ -198,8 +198,8 @@ program = { common = util/grub-pe2elf.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL)'; condition = COND_GRUB_PE2ELF; @@ -217,8 +217,8 @@ program = { cppflags = '$(CPPFLAGS_GCRY)'; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -232,8 +232,8 @@ program = { cflags = '$(freetype_cflags)'; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(freetype_libs)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; @@ -253,8 +253,8 @@ program = { sparc64_ieee1275 = util/ieee1275/devicemap.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -266,8 +266,8 @@ program = { common = util/grub-probe.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -299,8 +299,8 @@ program = { ieee1275 = util/ieee1275/ofpath.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBGEOM)'; @@ -314,8 +314,8 @@ program = { common = util/grub-mklayout.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -625,8 +625,8 @@ program = { common = grub-core/tests/lib/test.c; cflags = -Wno-format; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -639,8 +639,8 @@ program = { common = grub-core/lib/i386/pc/vesa_modes_table.c; ldadd = libgrubmods.a; - ldadd = libgrubkern.a; ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; From 20a409405b6caf9f51bb391caaac24124c0de3f9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Apr 2011 14:52:07 +0200 Subject: [PATCH 0942/1414] Integrate geli into autoconfiguration system --- grub-core/disk/cryptodisk.c | 210 ++++++++++++++- grub-core/disk/geli.c | 464 +++++++++++++--------------------- grub-core/disk/luks.c | 329 ++++++------------------ grub-core/kern/emu/getroot.c | 217 +++++++++++++++- grub-core/kern/emu/hostdisk.c | 204 +++++++-------- include/grub/cryptodisk.h | 35 ++- include/grub/emu/getroot.h | 5 + include/grub/emu/hostdisk.h | 8 +- util/grub-fstest.c | 6 +- util/grub-install.in | 6 +- util/grub-mkconfig.in | 2 +- util/grub-mkconfig_lib.in | 10 +- util/grub-probe.c | 21 +- 13 files changed, 835 insertions(+), 682 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index bf0b1cde2..1a5e8164b 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #ifdef GRUB_UTIL #include @@ -33,6 +35,16 @@ GRUB_MOD_LICENSE ("GPLv3+"); +grub_cryptodisk_dev_t grub_cryptodisk_list; + +static const struct grub_arg_option options[] = + { + {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, + {"all", 'a', 0, N_("Mount all."), 0, 0}, + {"boot", 'b', 0, N_("Mount all volumes marked as boot."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + /* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ #define GF_POLYNOM 0x87 static inline int GF_PER_SECTOR (const struct grub_cryptodisk *dev) @@ -480,7 +492,7 @@ grub_cryptodisk_close (grub_disk_t disk) static grub_err_t grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) + grub_size_t size, char *buf) { grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; grub_err_t err; @@ -635,7 +647,7 @@ grub_util_cryptodisk_print_abstraction (grub_disk_t disk) { grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - grub_printf ("luks "); + grub_printf ("cryptodisk %s ", dev->modname); if (dev->cipher) grub_printf ("%s ", dev->cipher->cipher->modname); @@ -650,8 +662,197 @@ grub_util_cryptodisk_print_abstraction (grub_disk_t disk) if (dev->iv_hash) grub_printf ("%s ", dev->iv_hash->modname); } + +void +grub_util_cryptodisk_print_uuid (grub_disk_t disk) +{ + grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; + grub_printf ("%s ", dev->uuid); +} + #endif +static int check_boot, have_it; +static char *search_uuid; + +static void +cryptodisk_close (grub_cryptodisk_t dev) +{ + grub_crypto_cipher_close (dev->cipher); + grub_crypto_cipher_close (dev->secondary_cipher); + grub_crypto_cipher_close (dev->essiv_cipher); + grub_free (dev); +} + +static grub_err_t +grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) +{ + grub_err_t err; + grub_cryptodisk_t dev; + grub_cryptodisk_dev_t cr; + + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) + return GRUB_ERR_NONE; + + FOR_CRYPTODISK_DEVS (cr) + { + dev = cr->scan (source, search_uuid, check_boot); + if (grub_errno) + return grub_errno; + if (!dev) + continue; + + err = cr->recover_key (source, dev); + if (err) + { + cryptodisk_close (dev); + return err; + } + + grub_cryptodisk_insert (dev, name, source); + + have_it = 1; + + return GRUB_ERR_NONE; + } + return GRUB_ERR_NONE; +} + +#ifdef GRUB_UTIL +#include +grub_err_t +grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) +{ + grub_err_t err; + grub_cryptodisk_t dev; + grub_cryptodisk_dev_t cr; + grub_disk_t source; + + /* Try to open disk. */ + source = grub_disk_open (sourcedev); + if (!source) + return grub_errno; + + dev = grub_cryptodisk_get_by_source_disk (source); + + if (dev) + { + grub_disk_close (source); + return GRUB_ERR_NONE; + } + + FOR_CRYPTODISK_DEVS (cr) + { + dev = cr->scan (source, search_uuid, check_boot); + if (grub_errno) + return grub_errno; + if (!dev) + continue; + + grub_util_info ("cheatmounted %s (%s) at %s", sourcedev, dev->modname, + cheat); + err = grub_cryptodisk_cheat_insert (dev, sourcedev, source, cheat); + grub_disk_close (source); + if (err) + grub_free (dev); + + return GRUB_ERR_NONE; + } + + grub_disk_close (source); + + return GRUB_ERR_NONE; +} +#endif + +static int +grub_cryptodisk_scan_device (const char *name) +{ + grub_err_t err; + grub_disk_t source; + + /* Try to open disk. */ + source = grub_disk_open (name); + if (!source) + return grub_errno; + + err = grub_cryptodisk_scan_device_real (name, source); + + grub_disk_close (source); + + if (err) + grub_print_error (); + return have_it && search_uuid ? 1 : 0; +} + +static grub_err_t +grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + + if (argc < 1 && !state[1].set && !state[2].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + have_it = 0; + if (state[0].set) + { + grub_cryptodisk_t dev; + + dev = grub_cryptodisk_get_by_uuid (args[0]); + if (dev) + { + grub_dprintf ("cryptodisk", + "already mounted as crypto%lu\n", dev->id); + return GRUB_ERR_NONE; + } + + check_boot = state[2].set; + search_uuid = args[0]; + grub_device_iterate (&grub_cryptodisk_scan_device); + search_uuid = NULL; + + if (!have_it) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); + return GRUB_ERR_NONE; + } + else if (state[1].set || (argc == 0 && state[2].set)) + { + search_uuid = NULL; + check_boot = state[2].set; + grub_device_iterate (&grub_cryptodisk_scan_device); + search_uuid = NULL; + return GRUB_ERR_NONE; + } + else + { + grub_err_t err; + grub_disk_t disk; + grub_cryptodisk_t dev; + + search_uuid = NULL; + check_boot = state[2].set; + disk = grub_disk_open (args[0]); + if (!disk) + return grub_errno; + + dev = grub_cryptodisk_get_by_source_disk (disk); + if (dev) + { + grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id); + grub_disk_close (disk); + return GRUB_ERR_NONE; + } + + err = grub_cryptodisk_scan_device_real (args[0], disk); + + grub_disk_close (disk); + + return err; + } +} + static struct grub_disk_dev grub_cryptodisk_dev = { .name = "cryptodisk", .id = GRUB_DISK_DEVICE_CRYPTODISK_ID, @@ -666,9 +867,14 @@ static struct grub_disk_dev grub_cryptodisk_dev = { .next = 0 }; +static grub_extcmd_t cmd; + GRUB_MOD_INIT (cryptodisk) { grub_disk_dev_register (&grub_cryptodisk_dev); + cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, + N_("SOURCE|-u UUID|-a|-b"), + N_("Mount a crypto device."), options); } GRUB_MOD_FINI (cryptodisk) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 1353be172..d2ae5da56 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -53,7 +53,7 @@ #include #include #include -#include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -105,17 +105,6 @@ const char *algorithms[] = { #define MAX_PASSPHRASE 256 -static const struct grub_arg_option options[] = - { - {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, - {"all", 'a', 0, N_("Mount all."), 0, 0}, - {"boot", 'b', 0, N_("Mount all volumes marked as boot."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -static int check_uuid, check_boot, have_it; -static char *search_uuid; - static gcry_err_code_t geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) { @@ -150,56 +139,21 @@ ascii2hex (char c) return 0; } -static grub_cryptodisk_t -configure_ciphers (const struct grub_geli_phdr *header) +static inline gcry_err_code_t +make_uuid (const struct grub_geli_phdr *header, + char *uuid) { - grub_cryptodisk_t newdev; - grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; - const struct gcry_cipher_spec *ciph; - const char *ciphername = NULL; - char uuid[GRUB_MD_SHA256->mdlen * 2 + 1]; grub_uint8_t uuidbin[GRUB_MD_SHA256->mdlen]; + gcry_err_code_t err; grub_uint8_t *iptr; char *optr; - gcry_err_code_t gcry_err; - /* Look for GELI magic sequence. */ - if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header->version) > 5 - || grub_le_to_cpu32 (header->version) < 1) - { - grub_dprintf ("geli", "wrong magic %02x\n", header->magic[0]); - return NULL; - } - if ((grub_le_to_cpu32 (header->sector_size) - & (grub_le_to_cpu32 (header->sector_size) - 1)) - || grub_le_to_cpu32 (header->sector_size) == 0) - { - grub_dprintf ("geli", "incorrect sector size %d\n", - grub_le_to_cpu32 (header->sector_size)); - return NULL; - } + err = grub_crypto_hmac_buffer (GRUB_MD_SHA256, + header->salt, sizeof (header->salt), + "uuid", sizeof ("uuid") - 1, uuidbin); + if (err) + return err; - if (grub_le_to_cpu32 (header->flags) & GRUB_GELI_FLAGS_ONETIME) - { - grub_dprintf ("geli", "skipping one-time volume\n"); - return NULL; - } - - if (check_boot && !(grub_le_to_cpu32 (header->flags) & GRUB_GELI_FLAGS_BOOT)) - { - grub_dprintf ("geli", "not a boot volume\n"); - return NULL; - } - - gcry_err = grub_crypto_hmac_buffer (GRUB_MD_SHA256, - header->salt, sizeof (header->salt), - "uuid", sizeof ("uuid") - 1, uuidbin); - if (gcry_err) - { - grub_crypto_gcry_error (gcry_err); - return NULL; - } optr = uuid; for (iptr = uuidbin; iptr < &uuidbin[ARRAY_SIZE (uuidbin)]; iptr++) { @@ -207,22 +161,133 @@ configure_ciphers (const struct grub_geli_phdr *header) optr += 2; } *optr = 0; + return GPG_ERR_NO_ERROR; +} - if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) +#ifdef GRUB_UTIL + +#include +#include +#include +#include +#include +#include +#include +#include + +char * +grub_util_get_geli_uuid (const char *dev) +{ + int fd = open (dev, O_RDONLY); + grub_uint64_t s; + unsigned log_secsize; + grub_uint8_t hdr[512]; + struct grub_geli_phdr *header; + char *uuid; + gcry_err_code_t err; + + if (fd < 0) + return NULL; + + s = grub_util_get_fd_sectors (fd, &log_secsize); + grub_util_fd_seek (fd, dev, (s << log_secsize) - 512); + + uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1); + if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0) + grub_util_error ("couldn't read ELI metadata"); + + COMPILE_TIME_ASSERT (sizeof (header) <= 512); + header = (void *) &hdr; + + /* Look for GELI magic sequence. */ + if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) + || grub_le_to_cpu32 (header->version) > 5 + || grub_le_to_cpu32 (header->version) < 1) + grub_util_error ("wrong ELI magic or version"); + + err = make_uuid ((void *) &hdr, uuid); + if (err) + return NULL; + + return uuid; +} +#endif + +static grub_cryptodisk_t +configure_ciphers (grub_disk_t disk, const char *check_uuid, + int boot_only) +{ + grub_cryptodisk_t newdev; + struct grub_geli_phdr header; + grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; + const struct gcry_cipher_spec *ciph; + const char *ciphername = NULL; + gcry_err_code_t gcry_err; + char uuid[GRUB_MD_SHA256->mdlen * 2 + 1]; + grub_disk_addr_t sector; + grub_err_t err; + + sector = grub_disk_get_size (disk); + if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0) + return NULL; + + /* Read the GELI header. */ + err = grub_disk_read (disk, sector - 1, 0, sizeof (header), &header); + if (err) + return NULL; + + /* Look for GELI magic sequence. */ + if (grub_memcmp (header.magic, GELI_MAGIC, sizeof (GELI_MAGIC)) + || grub_le_to_cpu32 (header.version) > 5 + || grub_le_to_cpu32 (header.version) < 1) { - grub_dprintf ("geli", "%s != %s\n", uuid, search_uuid); + grub_dprintf ("geli", "wrong magic %02x\n", header.magic[0]); return NULL; } - if (grub_le_to_cpu16 (header->alg) >= ARRAY_SIZE (algorithms) - || algorithms[grub_le_to_cpu16 (header->alg)] == NULL) + if ((grub_le_to_cpu32 (header.sector_size) + & (grub_le_to_cpu32 (header.sector_size) - 1)) + || grub_le_to_cpu32 (header.sector_size) == 0) + { + grub_dprintf ("geli", "incorrect sector size %d\n", + grub_le_to_cpu32 (header.sector_size)); + return NULL; + } + + if (grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_ONETIME) + { + grub_dprintf ("geli", "skipping one-time volume\n"); + return NULL; + } + + if (boot_only && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) + { + grub_dprintf ("geli", "not a boot volume\n"); + return NULL; + } + + gcry_err = make_uuid (&header, uuid); + if (gcry_err) + { + grub_crypto_gcry_error (gcry_err); + return NULL; + } + + if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) + { + grub_dprintf ("geli", "%s != %s\n", uuid, check_uuid); + return NULL; + } + + if (grub_le_to_cpu16 (header.alg) >= ARRAY_SIZE (algorithms) + || algorithms[grub_le_to_cpu16 (header.alg)] == NULL) { grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher 0x%x unknown", - grub_le_to_cpu16 (header->alg)); + grub_le_to_cpu16 (header.alg)); return NULL; } - ciphername = algorithms[grub_le_to_cpu16 (header->alg)]; + ciphername = algorithms[grub_le_to_cpu16 (header.alg)]; ciph = grub_crypto_lookup_cipher_by_name (ciphername); if (!ciph) { @@ -236,17 +301,17 @@ configure_ciphers (const struct grub_geli_phdr *header) if (!cipher) return NULL; - if (grub_le_to_cpu16 (header->alg) == 0x16) + if (grub_le_to_cpu16 (header.alg) == 0x16) { secondary_cipher = grub_crypto_cipher_open (ciph); if (!secondary_cipher) return NULL; } - if (grub_le_to_cpu16 (header->keylen) > 1024) + if (grub_le_to_cpu16 (header.keylen) > 1024) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", - grub_le_to_cpu16 (header->keylen)); + grub_le_to_cpu16 (header.keylen)); return NULL; } @@ -258,7 +323,7 @@ configure_ciphers (const struct grub_geli_phdr *header) newdev->offset = 0; newdev->source_disk = NULL; newdev->benbi_log = 0; - if (grub_le_to_cpu16 (header->alg) == 0x16) + if (grub_le_to_cpu16 (header.alg) == 0x16) { newdev->mode = GRUB_CRYPTODISK_MODE_XTS; newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64; @@ -274,25 +339,29 @@ configure_ciphers (const struct grub_geli_phdr *header) newdev->iv_hash = GRUB_MD_SHA256; for (newdev->log_sector_size = 0; - (1U << newdev->log_sector_size) < grub_le_to_cpu32 (header->sector_size); + (1U << newdev->log_sector_size) < grub_le_to_cpu32 (header.sector_size); newdev->log_sector_size++); - if (grub_le_to_cpu32 (header->version) >= 5) + if (grub_le_to_cpu32 (header.version) >= 5) { newdev->rekey = geli_rekey; newdev->rekey_shift = 20; } +#ifdef GRUB_UTIL + newdev->modname = "geli"; +#endif + + newdev->total_length = grub_disk_get_size (disk) - 1; grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= 32 * 2 + 1); return newdev; } static grub_err_t -recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, - const char *name, grub_disk_t source __attribute__ ((unused))) +recover_key (grub_disk_t source, grub_cryptodisk_t dev) { - grub_size_t keysize = grub_le_to_cpu16 (header->keylen) / 8; + grub_size_t keysize; grub_uint8_t digest[dev->hash->mdlen]; grub_uint8_t geomkey[dev->hash->mdlen]; grub_uint8_t verify_key[dev->hash->mdlen]; @@ -300,25 +369,45 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, char passphrase[MAX_PASSPHRASE] = ""; unsigned i; gcry_err_code_t gcry_err; + struct grub_geli_phdr header; + char *tmp; + grub_disk_addr_t sector; + grub_err_t err; + sector = grub_disk_get_size (source); + if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not a geli"); + + /* Read the GELI header. */ + err = grub_disk_read (source, sector - 1, 0, sizeof (header), &header); + if (err) + return err; + + keysize = grub_le_to_cpu16 (header.keylen) / 8; grub_memset (zero, 0, sizeof (zero)); grub_printf ("Attempting to decrypt master key...\n"); /* Get the passphrase from the user. */ - grub_printf ("Enter passphrase for %s (%s): ", name, dev->uuid); + tmp = NULL; + if (source->partition) + tmp = grub_partition_get_name (source->partition); + grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name, + source->partition ? "," : "", tmp ? : "", + dev->uuid); + grub_free (tmp); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); /* Calculate the PBKDF2 of the user supplied passphrase. */ - if (grub_le_to_cpu32 (header->niter) != 0) + if (grub_le_to_cpu32 (header.niter) != 0) { grub_uint8_t pbkdf_key[64]; gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, grub_strlen (passphrase), - header->salt, - sizeof (header->salt), - grub_le_to_cpu32 (header->niter), + header.salt, + sizeof (header.salt), + grub_le_to_cpu32 (header.niter), pbkdf_key, sizeof (pbkdf_key)); if (gcry_err) @@ -337,7 +426,7 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, if (!hnd) return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY); - grub_crypto_hmac_write (hnd, header->salt, sizeof (header->salt)); + grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt)); grub_crypto_hmac_write (hnd, passphrase, grub_strlen (passphrase)); gcry_err = grub_crypto_hmac_fini (hnd, geomkey); @@ -358,13 +447,13 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, grub_dprintf ("geli", "keylen = %" PRIuGRUB_SIZE "\n", keysize); /* Try to recover master key from each active keyslot. */ - for (i = 0; i < ARRAY_SIZE (header->keys); i++) + for (i = 0; i < ARRAY_SIZE (header.keys); i++) { struct grub_geli_key candidate_key; grub_uint8_t key_hmac[dev->hash->mdlen]; /* Check if keyslot is enabled. */ - if (! (header->keys_used & (1 << i))) + if (! (header.keys_used & (1 << i))) continue; grub_dprintf ("geli", "Trying keyslot %d\n", i); @@ -375,7 +464,7 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, return grub_crypto_gcry_error (gcry_err); gcry_err = grub_crypto_cbc_decrypt (dev->cipher, &candidate_key, - &header->keys[i], + &header.keys[i], sizeof (candidate_key), zero); if (gcry_err) @@ -398,7 +487,7 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, if (!dev->rekey) { grub_size_t real_keysize = keysize; - if (grub_le_to_cpu16 (header->alg) == 0x16) + if (grub_le_to_cpu16 (header.alg) == 0x16) real_keysize *= 2; gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, real_keysize); @@ -408,7 +497,7 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, else { grub_size_t real_keysize = keysize; - if (grub_le_to_cpu16 (header->alg) == 0x16) + if (grub_le_to_cpu16 (header.alg) == 0x16) real_keysize *= 2; /* For a reason I don't know, the IV key is used in rekeying. */ grub_memcpy (dev->rekey_key, candidate_key.iv_key, @@ -431,216 +520,17 @@ recover_key (grub_cryptodisk_t dev, const struct grub_geli_phdr *header, return GRUB_ACCESS_DENIED; } -static void -close (grub_cryptodisk_t luks) -{ - grub_crypto_cipher_close (luks->cipher); - grub_crypto_cipher_close (luks->secondary_cipher); - grub_crypto_cipher_close (luks->essiv_cipher); - grub_free (luks); -} - -static grub_err_t -grub_geli_scan_device_real (const char *name, grub_disk_t source) -{ - grub_err_t err; - struct grub_geli_phdr header; - grub_cryptodisk_t newdev, dev; - grub_disk_addr_t sector; - - grub_dprintf ("geli", "scanning %s\n", source->name); - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) - return GRUB_ERR_NONE; - - sector = grub_disk_get_size (source); - if (sector == GRUB_DISK_SIZE_UNKNOWN) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "not a geli"); - - /* Read the LUKS header. */ - err = grub_disk_read (source, sector - 1, 0, sizeof (header), &header); - if (err) - return err; - - newdev = configure_ciphers (&header); - if (!newdev) - return grub_errno; - - newdev->total_length = grub_disk_get_size (source) - 1; - - err = recover_key (newdev, &header, name, source); - if (err) - { - close (newdev); - return err; - } - - grub_cryptodisk_insert (newdev, name, source); - - have_it = 1; - - return GRUB_ERR_NONE; -} - -#ifdef GRUB_UTIL -grub_err_t -grub_geli_cheat_mount (const char *sourcedev, const char *cheat) -{ - grub_err_t err; - struct grub_geli_phdr header; - grub_cryptodisk_t newdev, dev; - grub_disk_t source; - grub_disk_addr_t sector; - - /* Try to open disk. */ - source = grub_disk_open (sourcedev); - if (!source) - return grub_errno; - - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) - { - grub_disk_close (source); - return GRUB_ERR_NONE; - } - - sector = grub_disk_get_size (source); - if (sector == GRUB_DISK_SIZE_UNKNOWN) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "not a geli"); - - /* Read the LUKS header. */ - err = grub_disk_read (source, sector - 1, 0, sizeof (header), &header); - if (err) - return err; - - newdev = configure_ciphers (&header); - if (!newdev) - { - grub_disk_close (source); - return grub_errno; - } - - newdev->total_length = grub_disk_get_size (source) - 1; - - err = grub_cryptodisk_cheat_insert (newdev, sourcedev, source, cheat); - grub_disk_close (source); - if (err) - grub_free (newdev); - - return err; -} -#endif - -static int -grub_geli_scan_device (const char *name) -{ - grub_err_t err; - grub_disk_t source; - - /* Try to open disk. */ - source = grub_disk_open (name); - if (!source) - return grub_errno; - - err = grub_geli_scan_device_real (name, source); - - grub_disk_close (source); - - if (err) - grub_print_error (); - return have_it && check_uuid ? 0 : 1; -} - -#ifdef GRUB_UTIL - -void -grub_util_geli_print_uuid (grub_disk_t disk) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - grub_printf ("%s ", dev->uuid); -} -#endif - -static grub_err_t -grub_cmd_gelimount (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - - if (argc < 1 && !state[1].set && !state[2].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - - have_it = 0; - if (state[0].set) - { - grub_cryptodisk_t dev; - - dev = grub_cryptodisk_get_by_uuid (args[0]); - if (dev) - { - grub_dprintf ("luks", "already mounted as crypto%lu\n", dev->id); - return GRUB_ERR_NONE; - } - - check_uuid = 1; - check_boot = state[2].set; - search_uuid = args[0]; - grub_device_iterate (&grub_geli_scan_device); - search_uuid = NULL; - - if (!have_it) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); - return GRUB_ERR_NONE; - } - else if (state[1].set || (argc == 0 && state[2].set)) - { - check_uuid = 0; - search_uuid = NULL; - check_boot = state[2].set; - grub_device_iterate (&grub_geli_scan_device); - search_uuid = NULL; - return GRUB_ERR_NONE; - } - else - { - grub_err_t err; - grub_disk_t disk; - grub_cryptodisk_t dev; - - check_uuid = 0; - search_uuid = NULL; - check_boot = state[2].set; - disk = grub_disk_open (args[0]); - if (!disk) - return grub_errno; - - dev = grub_cryptodisk_get_by_source_disk (disk); - if (dev) - { - grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); - grub_disk_close (disk); - return GRUB_ERR_NONE; - } - - err = grub_geli_scan_device_real (args[0], disk); - - grub_disk_close (disk); - - return err; - } -} - -static grub_extcmd_t cmd; +struct grub_cryptodisk_dev geli_crypto = { + .scan = configure_ciphers, + .recover_key = recover_key +}; GRUB_MOD_INIT (geli) { - cmd = grub_register_extcmd ("gelimount", grub_cmd_gelimount, 0, - N_("SOURCE|-u UUID|-a|-b"), - N_("Mount a GELI device."), options); + grub_cryptodisk_dev_register (&geli_crypto); } GRUB_MOD_FINI (geli) { - grub_unregister_extcmd (cmd); + grub_cryptodisk_dev_unregister (&geli_crypto); } diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index aa23e2e35..0ec95fccd 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -64,27 +64,19 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst, grub_size_t blocksize, grub_size_t blocknumbers); -static const struct grub_arg_option options[] = - { - {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, - {"all", 'a', 0, N_("Mount all."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -static int check_uuid, have_it; -static char *search_uuid; - static grub_cryptodisk_t -configure_ciphers (const struct grub_luks_phdr *header) +configure_ciphers (grub_disk_t disk, const char *check_uuid, + int check_boot) { grub_cryptodisk_t newdev; const char *iptr; + struct grub_luks_phdr header; char *optr; - char uuid[sizeof (header->uuid) + 1]; - char ciphername[sizeof (header->cipherName) + 1]; - char ciphermode[sizeof (header->cipherMode) + 1]; + char uuid[sizeof (header.uuid) + 1]; + char ciphername[sizeof (header.cipherName) + 1]; + char ciphermode[sizeof (header.cipherMode) + 1]; char *cipheriv = NULL; - char hashspec[sizeof (header->hashSpec) + 1]; + char hashspec[sizeof (header.hashSpec) + 1]; grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; grub_crypto_cipher_handle_t essiv_cipher = NULL; const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL; @@ -92,14 +84,27 @@ configure_ciphers (const struct grub_luks_phdr *header) grub_cryptodisk_mode_t mode; grub_cryptodisk_mode_iv_t mode_iv; int benbi_log = 0; + grub_err_t err; + + if (check_boot) + return NULL; + + /* Read the LUKS header. */ + err = grub_disk_read (disk, 0, 0, sizeof (header), &header); + if (err) + { + if (err == GRUB_ERR_OUT_OF_RANGE) + grub_errno = GRUB_ERR_NONE; + return NULL; + } /* Look for LUKS magic sequence. */ - if (grub_memcmp (header->magic, LUKS_MAGIC, sizeof (header->magic)) - || grub_be_to_cpu16 (header->version) != 1) + if (grub_memcmp (header.magic, LUKS_MAGIC, sizeof (header.magic)) + || grub_be_to_cpu16 (header.version) != 1) return NULL; optr = uuid; - for (iptr = header->uuid; iptr < &header->uuid[ARRAY_SIZE (header->uuid)]; + for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)]; iptr++) { if (*iptr != '-') @@ -107,19 +112,19 @@ configure_ciphers (const struct grub_luks_phdr *header) } *optr = 0; - if (check_uuid && grub_strcasecmp (search_uuid, uuid) != 0) + if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) { - grub_dprintf ("luks", "%s != %s\n", uuid, search_uuid); + grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid); return NULL; } /* Make sure that strings are null terminated. */ - grub_memcpy (ciphername, header->cipherName, sizeof (header->cipherName)); - ciphername[sizeof (header->cipherName)] = 0; - grub_memcpy (ciphermode, header->cipherMode, sizeof (header->cipherMode)); - ciphermode[sizeof (header->cipherMode)] = 0; - grub_memcpy (hashspec, header->hashSpec, sizeof (header->hashSpec)); - hashspec[sizeof (header->hashSpec)] = 0; + grub_memcpy (ciphername, header.cipherName, sizeof (header.cipherName)); + ciphername[sizeof (header.cipherName)] = 0; + grub_memcpy (ciphermode, header.cipherMode, sizeof (header.cipherMode)); + ciphermode[sizeof (header.cipherMode)] = 0; + grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec)); + hashspec[sizeof (header.hashSpec)] = 0; ciph = grub_crypto_lookup_cipher_by_name (ciphername); if (!ciph) @@ -134,10 +139,10 @@ configure_ciphers (const struct grub_luks_phdr *header) if (!cipher) return NULL; - if (grub_be_to_cpu32 (header->keyBytes) > 1024) + if (grub_be_to_cpu32 (header.keyBytes) > 1024) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", - grub_be_to_cpu32 (header->keyBytes)); + grub_be_to_cpu32 (header.keyBytes)); return NULL; } @@ -273,7 +278,7 @@ configure_ciphers (const struct grub_luks_phdr *header) if (!newdev) return NULL; newdev->cipher = cipher; - newdev->offset = grub_be_to_cpu32 (header->payloadOffset); + newdev->offset = grub_be_to_cpu32 (header.payloadOffset); newdev->source_disk = NULL; newdev->benbi_log = benbi_log; newdev->mode = mode; @@ -283,39 +288,54 @@ configure_ciphers (const struct grub_luks_phdr *header) newdev->essiv_hash = essiv_hash; newdev->hash = hash; newdev->log_sector_size = 9; + newdev->total_length = grub_disk_get_size (disk) - newdev->offset; grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); +#ifdef GRUB_UTIL + newdev->modname = "luks"; +#endif COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); return newdev; } static grub_err_t -luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, - const char *name, grub_disk_t source) +luks_recover_key (grub_disk_t source, + grub_cryptodisk_t dev) { - grub_size_t keysize = grub_be_to_cpu32 (header->keyBytes); - grub_uint8_t candidate_key[keysize]; - grub_uint8_t digest[keysize]; + struct grub_luks_phdr header; + grub_size_t keysize; grub_uint8_t *split_key = NULL; char passphrase[MAX_PASSPHRASE] = ""; - grub_uint8_t candidate_digest[sizeof (header->mkDigest)]; + grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; unsigned i; grub_size_t length; grub_err_t err; grub_size_t max_stripes = 1; + char *tmp; + + err = grub_disk_read (source, 0, 0, sizeof (header), &header); + if (err) + return err; grub_printf ("Attempting to decrypt master key...\n"); + keysize = grub_be_to_cpu32 (header.keyBytes); - for (i = 0; i < ARRAY_SIZE (header->keyblock); i++) - if (grub_be_to_cpu32 (header->keyblock[i].active) == LUKS_KEY_ENABLED - && grub_be_to_cpu32 (header->keyblock[i].stripes) > max_stripes) - max_stripes = grub_be_to_cpu32 (header->keyblock[i].stripes); + for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) + if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED + && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) + max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes); split_key = grub_malloc (keysize * max_stripes); if (!split_key) return grub_errno; /* Get the passphrase from the user. */ - grub_printf ("Enter passphrase for %s (%s): ", name, dev->uuid); + tmp = NULL; + if (source->partition) + tmp = grub_partition_get_name (source->partition); + grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name, + source->partition ? "," : "", tmp ? : "", + dev->uuid); + grub_free (tmp); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) { grub_free (split_key); @@ -323,12 +343,14 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, } /* Try to recover master key from each active keyslot. */ - for (i = 0; i < ARRAY_SIZE (header->keyblock); i++) + for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) { gcry_err_code_t gcry_err; + grub_uint8_t candidate_key[keysize]; + grub_uint8_t digest[keysize]; /* Check if keyslot is enabled. */ - if (grub_be_to_cpu32 (header->keyblock[i].active) != LUKS_KEY_ENABLED) + if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) continue; grub_dprintf ("luks", "Trying keyslot %d\n", i); @@ -336,9 +358,9 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, /* Calculate the PBKDF2 of the user supplied passphrase. */ gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, grub_strlen (passphrase), - header->keyblock[i].passwordSalt, - sizeof (header->keyblock[i].passwordSalt), - grub_be_to_cpu32 (header->keyblock[i]. + header.keyblock[i].passwordSalt, + sizeof (header.keyblock[i].passwordSalt), + grub_be_to_cpu32 (header.keyblock[i]. passwordIterations), digest, keysize); @@ -357,11 +379,11 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, return grub_crypto_gcry_error (gcry_err); } - length = (keysize * grub_be_to_cpu32 (header->keyblock[i].stripes)); + length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); /* Read and decrypt the key material from the disk. */ err = grub_disk_read (source, - grub_be_to_cpu32 (header->keyblock + grub_be_to_cpu32 (header.keyblock [i].keyMaterialOffset), 0, length, split_key); if (err) @@ -379,7 +401,7 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, /* Merge the decrypted key material to get the candidate master key. */ gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, - grub_be_to_cpu32 (header->keyblock[i].stripes)); + grub_be_to_cpu32 (header.keyblock[i].stripes)); if (gcry_err) { grub_free (split_key); @@ -390,11 +412,11 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, /* Calculate the PBKDF2 of the candidate master key. */ gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, - grub_be_to_cpu32 (header->keyBytes), - header->mkDigestSalt, - sizeof (header->mkDigestSalt), + grub_be_to_cpu32 (header.keyBytes), + header.mkDigestSalt, + sizeof (header.mkDigestSalt), grub_be_to_cpu32 - (header->mkDigestIterations), + (header.mkDigestIterations), candidate_digest, sizeof (candidate_digest)); if (gcry_err) @@ -405,8 +427,8 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, /* Compare the calculated PBKDF2 to the digest stored in the header to see if it's correct. */ - if (grub_memcmp (candidate_digest, header->mkDigest, - sizeof (header->mkDigest)) != 0) + if (grub_memcmp (candidate_digest, header.mkDigest, + sizeof (header.mkDigest)) != 0) { grub_dprintf ("luks", "bad digest\n"); continue; @@ -430,204 +452,19 @@ luks_recover_key (grub_cryptodisk_t dev, const struct grub_luks_phdr *header, return GRUB_ACCESS_DENIED; } -static void -luks_close (grub_cryptodisk_t luks) -{ - grub_crypto_cipher_close (luks->cipher); - grub_crypto_cipher_close (luks->secondary_cipher); - grub_crypto_cipher_close (luks->essiv_cipher); - grub_free (luks); -} - -static grub_err_t -grub_luks_scan_device_real (const char *name, grub_disk_t source) -{ - grub_err_t err; - struct grub_luks_phdr header; - grub_cryptodisk_t newdev, dev; - - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) - return GRUB_ERR_NONE; - - /* Read the LUKS header. */ - err = grub_disk_read (source, 0, 0, sizeof (header), &header); - if (err) - return err; - - newdev = configure_ciphers (&header); - if (!newdev) - return grub_errno; - - newdev->total_length = grub_disk_get_size (source) - newdev->offset; - - err = luks_recover_key (newdev, &header, name, source); - if (err) - { - luks_close (newdev); - return err; - } - - grub_cryptodisk_insert (newdev, name, source); - - have_it = 1; - - return GRUB_ERR_NONE; -} - -#ifdef GRUB_UTIL -grub_err_t -grub_luks_cheat_mount (const char *sourcedev, const char *cheat) -{ - grub_err_t err; - struct grub_luks_phdr header; - grub_cryptodisk_t newdev, dev; - grub_disk_t source; - - /* Try to open disk. */ - source = grub_disk_open (sourcedev); - if (!source) - return grub_errno; - - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) - { - grub_disk_close (source); - return GRUB_ERR_NONE; - } - - /* Read the LUKS header. */ - err = grub_disk_read (source, 0, 0, sizeof (header), &header); - if (err) - return err; - - newdev = configure_ciphers (&header); - if (!newdev) - { - grub_disk_close (source); - return grub_errno; - } - - newdev->total_length = grub_disk_get_size (source) - newdev->offset; - - err = grub_cryptodisk_cheat_insert (newdev, sourcedev, source, cheat); - grub_disk_close (source); - if (err) - grub_free (newdev); - - return err; -} -#endif - -static int -grub_luks_scan_device (const char *name) -{ - grub_err_t err; - grub_disk_t source; - - /* Try to open disk. */ - source = grub_disk_open (name); - if (!source) - return grub_errno; - - err = grub_luks_scan_device_real (name, source); - - grub_disk_close (source); - - if (err) - grub_print_error (); - return have_it && check_uuid ? 0 : 1; -} - -#ifdef GRUB_UTIL - -void -grub_util_luks_print_uuid (grub_disk_t disk) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - grub_printf ("%s ", dev->uuid); -} -#endif - -static grub_err_t -grub_cmd_luksmount (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - - if (argc < 1 && !state[1].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - - have_it = 0; - if (state[0].set) - { - grub_cryptodisk_t dev; - - dev = grub_cryptodisk_get_by_uuid (args[0]); - if (dev) - { - grub_dprintf ("luks", "already mounted as crypto%lu\n", dev->id); - return GRUB_ERR_NONE; - } - - check_uuid = 1; - search_uuid = args[0]; - grub_device_iterate (&grub_luks_scan_device); - search_uuid = NULL; - - if (!have_it) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such luks found"); - return GRUB_ERR_NONE; - } - else if (state[1].set) - { - check_uuid = 0; - search_uuid = NULL; - grub_device_iterate (&grub_luks_scan_device); - search_uuid = NULL; - return GRUB_ERR_NONE; - } - else - { - grub_err_t err; - grub_disk_t disk; - grub_cryptodisk_t dev; - - check_uuid = 0; - search_uuid = NULL; - disk = grub_disk_open (args[0]); - if (!disk) - return grub_errno; - - dev = grub_cryptodisk_get_by_source_disk (disk); - if (dev) - { - grub_dprintf ("luks", "already mounted as luks%lu\n", dev->id); - grub_disk_close (disk); - return GRUB_ERR_NONE; - } - - err = grub_luks_scan_device_real (args[0], disk); - - grub_disk_close (disk); - - return err; - } -} - -static grub_extcmd_t cmd; +struct grub_cryptodisk_dev luks_crypto = { + .scan = configure_ciphers, + .recover_key = luks_recover_key +}; GRUB_MOD_INIT (luks) { COMPILE_TIME_ASSERT (sizeof (((struct grub_luks_phdr *) 0)->uuid) < GRUB_CRYPTODISK_MAX_UUID_LENGTH); - cmd = grub_register_extcmd ("luksmount", grub_cmd_luksmount, 0, - N_("SOURCE|-u UUID|-a"), - N_("Mount a LUKS device."), options); + grub_cryptodisk_dev_register (&luks_crypto); } GRUB_MOD_FINI (luks) { - grub_unregister_extcmd (cmd); + grub_cryptodisk_dev_unregister (&luks_crypto); } diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 642d77cf0..b6e8a673f 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef HAVE_DEVICE_MAPPER # include @@ -756,6 +757,94 @@ grub_util_get_dm_abstraction (const char *os_dev) #endif } +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +#include + +/* FIXME: geom actually gives us the whole container hierarchy. + It can be used more efficiently than this. */ +void +grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out) +{ + struct gmesh mesh; + struct gclass *class; + int error; + struct ggeom *geom; + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + if (strcasecmp (class->lg_name, "part") == 0) + break; + if (!class) + grub_util_error ("couldn't open geom part"); + + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + char *name_tmp = xstrdup (geom->lg_name); + grub_disk_addr_t off = 0; + struct gconfig *config; + grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); + + grub_util_follow_gpart_up (name_tmp, &off, name_out); + free (name_tmp); + LIST_FOREACH (config, &provider->lg_config, lg_config) + if (strcasecmp (config->lg_name, "start") == 0) + off += strtoull (config->lg_val, 0, 10); + if (off_out) + *off_out = off; + return; + } + } + grub_util_info ("geom '%s' has no parent", name); + if (name_out) + *name_out = xstrdup (name); + if (off_out) + *off_out = 0; +} + +static const char * +grub_util_get_geom_abstraction (const char *dev) +{ + char *whole; + struct gmesh mesh; + struct gclass *class; + const char *name; + int error; + + if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return 0; + name = dev + sizeof ("/dev/") - 1; + grub_util_follow_gpart_up (name, NULL, &whole); + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + { + struct ggeom *geom; + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + return class->lg_name; + } + } + return NULL; +} +#endif + int grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { @@ -777,6 +866,14 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) return GRUB_DEV_ABSTRACTION_RAID; #endif +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) + const char *abs; + abs = grub_util_get_geom_abstraction (os_dev); + grub_util_info ("abstraction of %s is %s", os_dev, abs); + if (abs && grub_strcasecmp (abs, "eli") == 0) + return GRUB_DEV_ABSTRACTION_GELI; +#endif + /* No abstraction found. */ return GRUB_DEV_ABSTRACTION_NONE; } @@ -869,6 +966,71 @@ grub_util_pull_device (const char *os_dev) ab = grub_util_get_dev_abstraction (os_dev); switch (ab) { + case GRUB_DEV_ABSTRACTION_GELI: + { + char *whole; + struct gmesh mesh; + struct gclass *class; + const char *name; + int error; + char *lastsubdev = NULL; + + if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return; + name = os_dev + sizeof ("/dev/") - 1; + grub_util_follow_gpart_up (name, NULL, &whole); + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + { + struct ggeom *geom; + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + struct gconsumer *consumer; + char *fname; + char *uuid; + + LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) + break; + if (!consumer) + grub_util_error ("couldn't find geli consumer"); + fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); + grub_util_info ("consumer %s", consumer->lg_provider->lg_name); + lastsubdev = consumer->lg_provider->lg_name; + grub_util_pull_device (fname); + free (fname); + } + } + } + if (ab == GRUB_DEV_ABSTRACTION_GELI && lastsubdev) + { + char *fname = xasprintf ("/dev/%s", lastsubdev); + char *grdev = grub_util_get_grub_dev (fname); + free (fname); + + if (grdev) + { + grub_err_t err; + err = grub_cryptodisk_cheat_mount (grdev, os_dev); + if (err) + grub_util_error ("Can't mount crypto: %s", grub_errmsg); + } + + grub_free (grdev); + } + + } + break; + case GRUB_DEV_ABSTRACTION_LVM: case GRUB_DEV_ABSTRACTION_LUKS: #ifdef HAVE_DEVICE_MAPPER @@ -895,7 +1057,7 @@ grub_util_pull_device (const char *os_dev) grub_util_pull_device (subdev); } } - if (ab == GRUB_DEV_ABSTRACTION_LUKS && lastsubdev) + if (ab == GRUB_DEV_ABSTRACTION_CRYPTO && lastsubdev) { char *grdev = grub_util_get_grub_dev (lastsubdev); dm_tree_free (tree); @@ -904,7 +1066,7 @@ grub_util_pull_device (const char *os_dev) grub_err_t err; err = grub_luks_cheat_mount (grdev, os_dev); if (err) - grub_util_error ("Can't mount LUKS: %s", grub_errmsg); + grub_util_error ("Can't mount crypto: %s", grub_errmsg); } grub_free (grdev); } @@ -959,6 +1121,8 @@ grub_util_get_grub_dev (const char *os_dev) { char *uuid, *dash; uuid = get_dm_uuid (os_dev); + if (!uuid) + break; dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-'); if (dash) *dash = 0; @@ -968,6 +1132,55 @@ grub_util_get_grub_dev (const char *os_dev) } break; + case GRUB_DEV_ABSTRACTION_GELI: + { + char *whole; + struct gmesh mesh; + struct gclass *class; + const char *name; + int error; + + if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) + return 0; + name = os_dev + sizeof ("/dev/") - 1; + grub_util_follow_gpart_up (name, NULL, &whole); + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + { + struct ggeom *geom; + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + struct gconsumer *consumer; + char *fname; + char *uuid; + + LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) + break; + if (!consumer) + grub_util_error ("couldn't find geli consumer"); + fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); + uuid = grub_util_get_geli_uuid (fname); + if (!uuid) + grub_util_error ("couldn't retrieve geli UUID"); + grub_dev = xasprintf ("cryptouuid/%s", uuid); + free (fname); + free (uuid); + } + } + } + } + break; + case GRUB_DEV_ABSTRACTION_RAID: if (os_dev[7] == '_' && os_dev[8] == 'd') diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 97e090222..6cace3746 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -106,9 +106,7 @@ struct hd_geometry # include #endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#elif defined(__NetBSD__) +#if defined(__NetBSD__) # define HAVE_DIOCGDINFO # include # include /* struct disklabel */ @@ -226,6 +224,82 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), return 0; } +#if !defined(__MINGW32__) +grub_uint64_t +grub_util_get_fd_sectors (int fd, unsigned *log_secsize) +{ +#if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) +# if defined(__NetBSD__) + struct disklabel label; +# else + unsigned long long nr; +# endif + unsigned sector_size, log_sector_size; + struct stat st; + + if (fstat (fd, &st) < 0) + grub_util_error ("fstat failed"); + +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) + if (! S_ISCHR (st.st_mode)) +# else + if (! S_ISBLK (st.st_mode)) +# endif + goto fail; + +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + if (ioctl (fd, DIOCGMEDIASIZE, &nr)) +# elif defined(__APPLE__) + if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr)) +# elif defined(__NetBSD__) + configure_device_driver (fd); + if (ioctl (fd, DIOCGDINFO, &label) == -1) +# else + if (ioctl (fd, BLKGETSIZE64, &nr)) +# endif + goto fail; + +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + if (ioctl (fd, DIOCGSECTORSIZE, §or_size)) +# else + if (ioctl (fd, BLKSSZGET, §or_size)) +# endif + goto fail; + + if (sector_size & (sector_size - 1) || !sector_size) + goto fail; + for (log_sector_size = 0; + (1 << log_sector_size) < sector_size; + log_sector_size++); + + if (log_secsize) + *log_secsize = log_sector_size; + +# if defined (__APPLE__) + return nr; +# elif defined(__NetBSD__) + return label.d_secperunit; +# else + if (nr & ((1 << log_sector_size) - 1)) + grub_util_error ("unaligned device size"); + + return (nr >> log_sector_size); +# endif + + fail: + /* In GNU/Hurd, stat() will return the right size. */ +#elif !defined (__GNU__) +# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." +#endif + + if (log_secsize) + *log_secsize = 9; + + return st.st_size >> 9; +} +#endif + static grub_err_t grub_util_biosdisk_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull __attribute__ ((unused))) @@ -262,90 +336,30 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk, return GRUB_ERR_NONE; } -#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) +#else { -# if defined(__NetBSD__) - struct disklabel label; -# else - unsigned long long nr; -# endif - int sector_size; int fd; fd = open (map[drive].device, O_RDONLY); if (fd == -1) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device); + disk->total_sectors = grub_util_get_fd_sectors (fd, &disk->log_sector_size); + # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode)) # else if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode)) # endif - { - close (fd); - goto fail; - } - data->is_disk = 1; - -# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - if (ioctl (fd, DIOCGMEDIASIZE, &nr)) -# elif defined(__APPLE__) - if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr)) -# elif defined(__NetBSD__) - configure_device_driver (fd); - if (ioctl (fd, DIOCGDINFO, &label) == -1) -# else - if (ioctl (fd, BLKGETSIZE64, &nr)) -# endif - { - close (fd); - goto fail; - } - - if (ioctl (fd, BLKSSZGET, §or_size)) - { - close (fd); - goto fail; - } + data->is_disk = 1; close (fd); - if (sector_size & (sector_size - 1) || !sector_size) - goto fail; - for (disk->log_sector_size = 0; - (1 << disk->log_sector_size) < sector_size; - disk->log_sector_size++); - -# if defined (__APPLE__) - disk->total_sectors = nr; -# elif defined(__NetBSD__) - disk->total_sectors = label.d_secperunit; -# else - disk->total_sectors = nr >> disk->log_sector_size; - - if (nr & ((1 << disk->log_sector_size) - 1)) - grub_util_error ("unaligned device size"); -# endif - grub_util_info ("the size of %s is %llu", name, disk->total_sectors); return GRUB_ERR_NONE; } - - fail: - /* In GNU/Hurd, stat() will return the right size. */ -#elif !defined (__GNU__) -# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." #endif - if (stat (map[drive].device, &st) < 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot stat `%s'", map[drive].device); - - disk->total_sectors = st.st_size >> disk->log_sector_size; - - grub_util_info ("the size of %s is %lu", name, disk->total_sectors); - - return GRUB_ERR_NONE; } int @@ -367,55 +381,6 @@ grub_util_device_is_mapped (const char *dev) } #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) -/* FIXME: geom actually gives us the whole container hierarchy. - It can be used more efficiently than this. */ -static void -follow_geom_up (const char *name, grub_disk_addr_t *off_out, char **name_out) -{ - struct gmesh mesh; - struct gclass *class; - int error; - struct ggeom *geom; - - grub_util_info ("following geom '%s'", name); - - error = geom_gettree (&mesh); - if (error != 0) - grub_util_error ("couldn't open geom"); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - if (strcasecmp (class->lg_name, "part") == 0) - break; - if (!class) - grub_util_error ("couldn't open geom part"); - - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - { - char *name_tmp = xstrdup (geom->lg_name); - grub_disk_addr_t off = 0; - struct gconfig *config; - grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); - - follow_geom_up (name_tmp, &off, name_out); - free (name_tmp); - LIST_FOREACH (config, &provider->lg_config, lg_config) - if (strcasecmp (config->lg_name, "start") == 0) - off += strtoull (config->lg_val, 0, 10); - if (off_out) - *off_out = off; - return; - } - } - grub_util_info ("geom '%s' has no parent", name); - if (name_out) - *name_out = xstrdup (name); - if (off_out) - *off_out = 0; -} static grub_disk_addr_t find_partition_start (const char *dev) @@ -423,10 +388,11 @@ find_partition_start (const char *dev) grub_disk_addr_t out; if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0) return 0; - follow_geom_up (dev + sizeof ("/dev/") - 1, &out, NULL); + grub_util_follow_gpart_up (dev + sizeof ("/dev/") - 1, &out, NULL); return out; } + #elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) static grub_disk_addr_t find_partition_start (const char *dev) @@ -1508,7 +1474,7 @@ devmapper_out: char *out, *out2; if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) return xstrdup (os_dev); - follow_geom_up (os_dev + sizeof ("/dev/") - 1, NULL, &out); + grub_util_follow_gpart_up (os_dev + sizeof ("/dev/") - 1, NULL, &out); out2 = xasprintf ("/dev/%s", out); free (out); @@ -1667,6 +1633,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) struct stat st; int drive; + grub_util_info ("Looking for %s", os_dev); + if (stat (os_dev, &st) < 0) { grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev); diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 169fb119d..c6d1ce8de 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -21,6 +21,7 @@ #include #include +#include typedef enum { @@ -57,6 +58,8 @@ typedef gcry_err_code_t struct grub_cryptodisk { + struct grub_cryptodisk *next; + char *source; grub_disk_addr_t offset; grub_disk_addr_t total_length; @@ -78,6 +81,7 @@ struct grub_cryptodisk grub_size_t iv_prefix_len; #ifdef GRUB_UTIL char *cheat; + const char *modname; int cheat_fd; #endif int log_sector_size; @@ -86,10 +90,37 @@ struct grub_cryptodisk grub_uint8_t rekey_key[64]; grub_uint64_t last_rekey; int rekey_derived_size; - struct grub_cryptodisk *next; }; typedef struct grub_cryptodisk *grub_cryptodisk_t; +struct grub_cryptodisk_dev +{ + struct grub_cryptodisk_dev *next; + + grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, + int boot_only); + grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev); +}; +typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; + +extern grub_cryptodisk_dev_t EXPORT_VAR (grub_cryptodisk_list); + +#ifndef GRUB_LST_GENERATOR +static inline void +grub_cryptodisk_dev_register (grub_cryptodisk_dev_t cr) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_cryptodisk_list), GRUB_AS_LIST (cr)); +} +#endif + +static inline void +grub_cryptodisk_dev_unregister (grub_cryptodisk_dev_t cr) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_cryptodisk_list), GRUB_AS_LIST (cr)); +} + +#define FOR_CRYPTODISK_DEVS(var) FOR_LIST_ELEMENTS((var), (grub_cryptodisk_list)) + gcry_err_code_t grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize); @@ -106,6 +137,8 @@ grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, grub_disk_t source, const char *cheat); void grub_util_cryptodisk_print_abstraction (grub_disk_t disk); +char * +grub_util_get_geli_uuid (const char *dev); #endif grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h index 57cd911ef..6921e567c 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h @@ -26,6 +26,7 @@ enum grub_dev_abstraction_types { GRUB_DEV_ABSTRACTION_LVM, GRUB_DEV_ABSTRACTION_RAID, GRUB_DEV_ABSTRACTION_LUKS, + GRUB_DEV_ABSTRACTION_GELI, }; char *grub_find_device (const char *dir, dev_t dev); @@ -38,5 +39,9 @@ const char *grub_util_check_char_device (const char *blk_dev); #ifdef __linux__ char **grub_util_raid_getmembers (const char *name, int bootable); #endif +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +void grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, + char **name_out); +#endif #endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 18191c4eb..719faa29b 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -35,7 +35,11 @@ grub_err_t grub_util_fd_seek (int fd, const char *name, grub_uint64_t sector); ssize_t grub_util_fd_read (int fd, char *buf, size_t len); grub_err_t -grub_luks_cheat_mount (const char *sourcedev, const char *cheat); -void grub_util_luks_print_uuid (grub_disk_t disk); +grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat); +void grub_util_cryptodisk_print_uuid (grub_disk_t disk); +#if !defined(__MINGW32__) +grub_uint64_t +grub_util_get_fd_sectors (int fd, unsigned *log_secsize); +#endif #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 48a5be1ca..f5880626c 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -309,10 +309,8 @@ fstest (int n, char **args) char *argv[2] = { "-a", NULL}; if (mount_crypt) { - if (execute_command ("luksmount", 1, argv)) - grub_util_error (_("luksmount command fails: %s"), grub_errmsg); - if (execute_command ("gelimount", 1, argv)) - grub_util_error (_("gelimount command fails: %s"), grub_errmsg); + if (execute_command ("cryptomount", 1, argv)) + grub_util_error (_("cryptomount command fails: %s"), grub_errmsg); } } diff --git a/util/grub-install.in b/util/grub-install.in index 3b3383ab4..049444e93 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -538,9 +538,9 @@ if [ "x${devabstraction_module}" = "x" ] ; then exit 1 fi - if [ x$GRUB_LUKS_ENABLE = xy ]; then - for uuid in "`"${grub_probe}" --device "${device}" --target=luks_uuid`"; do - echo "luksmount -u $uuid" + if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then + for uuid in "`"${grub_probe}" --device "${device}" --target=cryptodisk_uuid`"; do + echo "cryptomount -u $uuid" done fi diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 41e68bc1b..ade7a558d 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -254,7 +254,7 @@ export GRUB_DEFAULT \ GRUB_DISABLE_OS_PROBER \ GRUB_INIT_TUNE \ GRUB_SAVEDEFAULT \ - GRUB_ENABLE_LUKS \ + GRUB_ENABLE_CRYPTODISK \ GRUB_BADRAM if test "x${grub_cfg}" != "x"; then diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 1664b6bbe..33ee7e432 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -69,12 +69,12 @@ is_path_readable_by_grub () return 1 fi - if [ x$GRUB_LUKS_ENABLE = xy ]; then + if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then return 0 fi for abstraction in $abstractions; do - if [ "x$abstraction" = xluks ]; then + if [ "x$abstraction" = xcryptodisk ]; then return 1 fi done @@ -138,9 +138,9 @@ prepare_grub_to_access_device () echo "insmod ${module}" done - if [ x$GRUB_LUKS_ENABLE = xy ]; then - for uuid in "`"${grub_probe}" --device "${device}" --target=luks_uuid`"; do - echo "luksmount -u $uuid" + if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then + for uuid in "`"${grub_probe}" --device "${device}" --target=cryptodisk_uuid`"; do + echo "cryptomount -u $uuid" done fi diff --git a/util/grub-probe.c b/util/grub-probe.c index f5d93ac4e..7c0a75123 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -56,7 +56,7 @@ enum { PRINT_DEVICE, PRINT_PARTMAP, PRINT_ABSTRACTION, - PRINT_LUKS_UUID + PRINT_CRYPTODISK_UUID }; int print = PRINT_FS; @@ -91,7 +91,7 @@ probe_partmap (grub_disk_t disk) } static void -probe_luks_uuid (grub_disk_t disk) +probe_cryptodisk_uuid (grub_disk_t disk) { grub_disk_memberlist_t list = NULL, tmp; @@ -102,14 +102,13 @@ probe_luks_uuid (grub_disk_t disk) } while (list) { - probe_luks_uuid (list->disk); + probe_cryptodisk_uuid (list->disk); tmp = list->next; free (list); list = tmp; } - /* FIXME: support non-LUKS. */ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) - grub_util_luks_print_uuid (disk); + grub_util_cryptodisk_print_uuid (disk); } static int @@ -215,9 +214,9 @@ probe (const char *path, char *device_name) goto end; } - if (print == PRINT_LUKS_UUID) + if (print == PRINT_CRYPTODISK_UUID) { - probe_luks_uuid (dev->disk); + probe_cryptodisk_uuid (dev->disk); printf ("\n"); goto end; } @@ -295,8 +294,8 @@ Probe device information for a given path (or device, if the -d option is given) \n\ -d, --device given argument is a system device, not a path\n\ -m, --device-map=FILE use FILE as the device map [default=%s]\n\ - -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|luks_uuid)\n\ - print filesystem module, GRUB drive, system device, partition map module, abstraction module or LUKS UUID [default=fs]\n\ + -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|cryptodisk_uuid)\n\ + print filesystem module, GRUB drive, system device, partition map module, abstraction module or CRYPTO UUID [default=fs]\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ @@ -354,8 +353,8 @@ main (int argc, char *argv[]) print = PRINT_PARTMAP; else if (!strcmp (optarg, "abstraction")) print = PRINT_ABSTRACTION; - else if (!strcmp (optarg, "luks_uuid")) - print = PRINT_LUKS_UUID; + else if (!strcmp (optarg, "cryptodisk_uuid")) + print = PRINT_CRYPTODISK_UUID; else usage (1); break; From 6be8715dfce00f852b8f31ae3d89f34c5b2f60b0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Apr 2011 15:23:37 +0200 Subject: [PATCH 0943/1414] * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Make mdraid UUID match the one used by mdadm. --- ChangeLog | 5 +++++ grub-core/disk/mdraid_linux.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd791308c..2de8578ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-25 Vladimir Serbinenko + + * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Make mdraid UUID + match the one used by mdadm. + 2011-04-21 Colin Watson * po/README: Add instructions for creating po/LINGUAS. diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index 691d100b8..0e2d85009 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -221,10 +221,10 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array, return grub_errno; uuid = (grub_uint32_t *) array->uuid; - uuid[0] = sb.set_uuid0; - uuid[1] = sb.set_uuid1; - uuid[2] = sb.set_uuid2; - uuid[3] = sb.set_uuid3; + uuid[0] = grub_swap_bytes32 (sb.set_uuid0); + uuid[1] = grub_swap_bytes32 (sb.set_uuid1); + uuid[2] = grub_swap_bytes32 (sb.set_uuid2); + uuid[3] = grub_swap_bytes32 (sb.set_uuid3); *start_sector = 0; From 68797f9230de4768b472f2807d1c947dba96dff0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Apr 2011 15:29:41 +0200 Subject: [PATCH 0944/1414] * grub-core/gnulib/regex.c: Remove GRUB_MOD_LICENSE since it's already supplied by another part of the module (fixes compilation on FreeBSD). --- ChangeLog | 6 ++++++ grub-core/gnulib/regex.c | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2de8578ff..b464d83a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-25 Vladimir Serbinenko + + * grub-core/gnulib/regex.c: Remove GRUB_MOD_LICENSE since it's + already supplied by another part of the module (fixes compilation on + FreeBSD). + 2011-04-25 Vladimir Serbinenko * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Make mdraid UUID diff --git a/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c index 4c2243f64..ba0eebee7 100644 --- a/grub-core/gnulib/regex.c +++ b/grub-core/gnulib/regex.c @@ -19,9 +19,6 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); /* Make sure noone compiles this code with a C++ compiler. */ #if defined __cplusplus && defined _LIBC From 723f63f2f88c91407ec0ee8c6b545f76a79e75dc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Apr 2011 15:36:08 +0200 Subject: [PATCH 0945/1414] * grub-core/partmap/amiga.c (amiga_partition_map_iterate): Fix a wrong action on non-detecting the magic. --- ChangeLog | 5 +++++ grub-core/partmap/amiga.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b464d83a8..3da7693db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-25 Vladimir Serbinenko + + * grub-core/partmap/amiga.c (amiga_partition_map_iterate): Fix a + wrong action on non-detecting the magic. + 2011-04-25 Vladimir Serbinenko * grub-core/gnulib/regex.c: Remove GRUB_MOD_LICENSE since it's diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c index f3ba950aa..36e318beb 100644 --- a/grub-core/partmap/amiga.c +++ b/grub-core/partmap/amiga.c @@ -114,8 +114,9 @@ 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) + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "invalid Amiga partition map"); /* Calculate the first block and the size of the partition. */ part.start = (grub_be_to_cpu32 (apart.lowcyl) * grub_be_to_cpu32 (apart.heads) From 3c62402d08da39973b299c1c153c119567bb08f3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Apr 2011 16:58:25 +0200 Subject: [PATCH 0946/1414] * grub-core/loader/i386/linux.c (grub_linux_boot): Supply target rather than source address for efi mmap buffer. --- ChangeLog | 5 +++++ grub-core/loader/i386/linux.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3da7693db..0a7e4d64c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-04-25 Vladimir Serbinenko + + * grub-core/loader/i386/linux.c (grub_linux_boot): Supply target rather + than source address for efi mmap buffer. + 2011-04-25 Vladimir Serbinenko * grub-core/partmap/amiga.c (amiga_partition_map_iterate): Fix a diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 241eaa5e7..f19f471ab 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -549,6 +549,7 @@ grub_linux_boot (void) #ifdef GRUB_MACHINE_EFI { grub_efi_uintn_t efi_desc_size; + grub_size_t efi_mmap_target; grub_efi_uint32_t efi_desc_version; err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, &efi_desc_size, &efi_desc_version); @@ -556,23 +557,24 @@ grub_linux_boot (void) return err; /* Note that no boot services are available from here. */ - + efi_mmap_target = real_mode_target + + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); /* Pass EFI parameters. */ if (grub_le_to_cpu16 (params->version) >= 0x0206) { params->v0206.efi_mem_desc_size = efi_desc_size; params->v0206.efi_mem_desc_version = efi_desc_version; - params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) efi_mmap_buf; + params->v0206.efi_mmap = efi_mmap_target; params->v0206.efi_mmap_size = efi_mmap_size; #ifdef __x86_64__ - params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) efi_mmap_buf >> 32); + params->v0206.efi_mmap_hi = (efi_mmap_target >> 32); #endif } else if (grub_le_to_cpu16 (params->version) >= 0x0204) { params->v0204.efi_mem_desc_size = efi_desc_size; params->v0204.efi_mem_desc_version = efi_desc_version; - params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) efi_mmap_buf; + params->v0204.efi_mmap = efi_mmap_target; params->v0204.efi_mmap_size = efi_mmap_size; } } From 8f9425534015c78ec04976aa04ce28811cf42405 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 1 May 2011 20:04:02 +0100 Subject: [PATCH 0947/1414] * docs/grub.texi (GRUB only offers a rescue shell): Suggest the use of `ls' to find out which devices are available. --- ChangeLog | 5 +++++ docs/grub.texi | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0a7e4d64c..58b3cc56c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-01 Colin Watson + + * docs/grub.texi (GRUB only offers a rescue shell): Suggest the use + of `ls' to find out which devices are available. + 2011-04-25 Vladimir Serbinenko * grub-core/loader/i386/linux.c (grub_linux_boot): Supply target rather diff --git a/docs/grub.texi b/docs/grub.texi index 8d2223fb4..95707e4cc 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4127,6 +4127,8 @@ device), then you can correct this and enter normal mode manually: @group # Inspect the current prefix (and other preset variables): set +# Find out which devices are available: +ls # Set to the correct value, which might be something like this: set prefix=(hd0,1)/grub set root=(hd0,1) From 4ebff75340fa311ed4c76644b6f3b798f0ae9723 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 3 May 2011 17:57:39 +0100 Subject: [PATCH 0948/1414] * tests/partmap_test.in: Don't hardcode path to parted. Reported by: Peter Hjalmarsson. Fixes Savannah bug #33150. --- ChangeLog | 5 +++++ tests/partmap_test.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 58b3cc56c..2aaeb862a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-03 Colin Watson + + * tests/partmap_test.in: Don't hardcode path to parted. + Reported by: Peter Hjalmarsson. Fixes Savannah bug #33150. + 2011-05-01 Colin Watson * docs/grub.texi (GRUB only offers a rescue shell): Suggest the use diff --git a/tests/partmap_test.in b/tests/partmap_test.in index 5a9c1a93d..7e9cef7c6 100644 --- a/tests/partmap_test.in +++ b/tests/partmap_test.in @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . -parted=/sbin/parted +parted=parted grubshell=@builddir@/grub-shell create_disk_image () { From bd405bbc55f88971a5e669d3c1f6c2570296093f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 3 May 2011 18:03:05 +0100 Subject: [PATCH 0949/1414] * grub-core/fs/i386/pc/pxe.c (grub_pxefs_dir): Return GRUB_ERR_BAD_FS rather than GRUB_ERR_IO if the disk is not a pxe disk; otherwise grub_fs_probe will not fall back to the next filesystem. (grub_pxefs_open): Likewise, for consistency. Reported and tested by: Ezekiel Grave. --- ChangeLog | 9 +++++++++ grub-core/fs/i386/pc/pxe.c | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2aaeb862a..29cdc3e01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-05-03 Colin Watson + + * grub-core/fs/i386/pc/pxe.c (grub_pxefs_dir): Return + GRUB_ERR_BAD_FS rather than GRUB_ERR_IO if the disk is not a pxe + disk; otherwise grub_fs_probe will not fall back to the next + filesystem. + (grub_pxefs_open): Likewise, for consistency. + Reported and tested by: Ezekiel Grave. + 2011-05-03 Colin Watson * tests/partmap_test.in: Don't hardcode path to parted. diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c index d6dc2c22d..4304881fa 100644 --- a/grub-core/fs/i386/pc/pxe.c +++ b/grub-core/fs/i386/pc/pxe.c @@ -227,7 +227,7 @@ grub_pxefs_dir (grub_device_t device, __attribute__ ((unused))) { if (device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID) - return grub_error (GRUB_ERR_IO, "not a pxe disk"); + return grub_error (GRUB_ERR_BAD_FS, "not a pxe disk"); return GRUB_ERR_NONE; } @@ -245,7 +245,7 @@ grub_pxefs_open (struct grub_file *file, const char *name) grub_file_t file_int, bufio; if (file->device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID) - return grub_error (GRUB_ERR_IO, "not a pxe disk"); + return grub_error (GRUB_ERR_BAD_FS, "not a pxe disk"); if (curr_file != 0) { From 664889a69ccae30908c13e2293d8400b570bee44 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 5 May 2011 01:26:16 +0200 Subject: [PATCH 0950/1414] * grub-core/efiemu/main.c (grub_efiemu_load_file): Return grub_errno and not 0 on failure. --- ChangeLog | 5 +++++ grub-core/efiemu/main.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 29cdc3e01..cdfc82688 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-05 Vladimir Serbinenko + + * grub-core/efiemu/main.c (grub_efiemu_load_file): Return grub_errno + and not 0 on failure. + 2011-05-03 Colin Watson * grub-core/fs/i386/pc/pxe.c (grub_pxefs_dir): Return diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index 772db2956..7ad3abb0d 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -193,7 +193,7 @@ grub_efiemu_load_file (const char *filename) file = grub_file_open (filename); if (! file) - return 0; + return grub_errno; err = grub_efiemu_mm_init (); if (err) From ee5614b7f8ff69ca55541a72bef0755488a4171d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 5 May 2011 01:27:54 +0200 Subject: [PATCH 0951/1414] * grub-core/lib/legacy_parse.c (grub_legacy_parse): Correctly handle hexadecimal. --- ChangeLog | 5 +++++ grub-core/lib/legacy_parse.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cdfc82688..7785ac9f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-05 Vladimir Serbinenko + + * grub-core/lib/legacy_parse.c (grub_legacy_parse): Correctly handle + hexadecimal. + 2011-05-05 Vladimir Serbinenko * grub-core/efiemu/main.c (grub_efiemu_load_file): Return grub_errno diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 024849055..659fa7061 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -680,7 +680,10 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) int base = 10; brk = curarg; if (brk[0] == '0' && brk[1] == 'x') - base = 16; + { + base = 16; + brk += 2; + } else if (brk[0] == '0') base = 8; for (; *brk && brk < curarg + curarglen; brk++) From ed660bd8ed99a29a5eb4b0bebf77a5c50a7fef44 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 5 May 2011 01:29:21 +0200 Subject: [PATCH 0952/1414] * util/grub-mkrescue.in (process_input_dir): Include efiemu??.o. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7785ac9f7..794fdf719 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-05-05 Vladimir Serbinenko + + * util/grub-mkrescue.in (process_input_dir): Include efiemu??.o. + 2011-05-05 Vladimir Serbinenko * grub-core/lib/legacy_parse.c (grub_legacy_parse): Correctly handle diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 455534009..f7f751708 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -160,7 +160,7 @@ process_input_dir () input_dir="$1" platform="$2" mkdir -p ${iso9660_dir}/boot/grub/${platform} - for file in ${input_dir}/*.mod; do + for file in "${input_dir}/"*.mod "${input_dir}/"efiemu32.o "${input_dir}/"efiemu64.o; do if test -f "$file"; then cp -f "$file" ${iso9660_dir}/boot/grub/${platform}/ fi From 7c515bee148b85f907bdd41db613064b6e2f445c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 5 May 2011 01:32:04 +0200 Subject: [PATCH 0953/1414] * util/grub-mkpasswd-pbkdf2.c (main): Use /dev/urandom and not /dev/random. /dev/urandom is good enough for our purposes (salting). --- ChangeLog | 5 +++++ util/grub-mkpasswd-pbkdf2.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 794fdf719..5dd39905e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-05 Vladimir Serbinenko + + * util/grub-mkpasswd-pbkdf2.c (main): Use /dev/urandom and not + /dev/random. /dev/urandom is good enough for our purposes (salting). + 2011-05-05 Vladimir Serbinenko * util/grub-mkrescue.in (process_input_dir): Include efiemu??.o. diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index fe1887f8f..dc2afdb6e 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -248,7 +248,7 @@ main (int argc, char *argv[]) { FILE *f; size_t rd; - f = fopen ("/dev/random", "rb"); + f = fopen ("/dev/urandom", "rb"); if (!f) { memset (pass1, 0, strlen (pass1)); From 7fae005102ffab0148219a26df8aa80d2110627e Mon Sep 17 00:00:00 2001 From: Zach Date: Thu, 5 May 2011 12:18:00 +0200 Subject: [PATCH 0954/1414] Support 2010 Macbooks. * grub-core/loader/efi/appleloader.c (devpath_6): New variable. (devs): Add devpath_6. --- ChangeLog | 7 +++++++ grub-core/loader/efi/appleloader.c | 33 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5dd39905e..81deaf96d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-05-05 Zach + + Support 2010 Macbooks. + + * grub-core/loader/efi/appleloader.c (devpath_6): New variable. + (devs): Add devpath_6. + 2011-05-05 Vladimir Serbinenko * util/grub-mkpasswd-pbkdf2.c (main): Use /dev/urandom and not diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c index 847750dc0..d8ca4a7f3 100644 --- a/grub-core/loader/efi/appleloader.c +++ b/grub-core/loader/efi/appleloader.c @@ -229,6 +229,38 @@ static struct piwg_full_device_path devpath_5 = } }; +/* mid-2010 MB/MBP (NVidia chipset) */ +static struct piwg_full_device_path devpath_6 = +{ + .comp1 = + { + .header = { + .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, + .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, + .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} + }, + .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, + .start_address = 0xffcc4000, + .end_address = 0xffffbfff + }, + .comp2 = + { + .header = { + .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, + .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, + .length = {sizeof (struct grub_efi_piwg_device_path), 0} + }, + .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, + 0x01, 0xAE, 0xF2, 0xB7}} + }, + .end = + { + .type = GRUB_EFI_END_DEVICE_PATH_TYPE, + .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, + .length = {sizeof (struct grub_efi_device_path), 0} + } +}; + struct devdata { char *model; @@ -242,6 +274,7 @@ struct devdata devs[] = {"MBP", (grub_efi_device_path_t *) &devpath_3}, {"MBA", (grub_efi_device_path_t *) &devpath_4}, {"MB NV", (grub_efi_device_path_t *) &devpath_5}, + {"MB NV2", (grub_efi_device_path_t *) &devpath_6}, {NULL, NULL}, }; From 072b5d315af49fc0ff4c6e31bc4f3a8f9e8a58ef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 5 May 2011 13:34:03 +0200 Subject: [PATCH 0955/1414] * grub-core/loader/efi/appleloader.c (MAKE_PIWG_PATH): New macro. (devpath_1): Use MAKE_PIWG_PATH. (devpath_2): Likewise. (devpath_3): Likewise. (devpath_4): Likewise. (devpath_5): Likewise. (devpath_6): Likewise. The appleldr.mod was checked that to be binary identical to previous version. --- ChangeLog | 13 ++ grub-core/loader/efi/appleloader.c | 223 ++++++----------------------- 2 files changed, 56 insertions(+), 180 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81deaf96d..540e171cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-05-05 Vladimir Serbinenko + + * grub-core/loader/efi/appleloader.c (MAKE_PIWG_PATH): New macro. + (devpath_1): Use MAKE_PIWG_PATH. + (devpath_2): Likewise. + (devpath_3): Likewise. + (devpath_4): Likewise. + (devpath_5): Likewise. + (devpath_6): Likewise. + + The appleldr.mod was checked that to be binary identical to previous + version. + 2011-05-05 Zach Support 2010 Macbooks. diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c index d8ca4a7f3..db57a573c 100644 --- a/grub-core/loader/efi/appleloader.c +++ b/grub-core/loader/efi/appleloader.c @@ -69,197 +69,60 @@ struct piwg_full_device_path struct grub_efi_device_path end; }; -/* early 2006 Core Duo / Core Solo models */ -static struct piwg_full_device_path devpath_1 = -{ - .comp1 = - { - .header = { - .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} - }, - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, - .start_address = 0xffe00000, - .end_address = 0xfff9ffff - }, - .comp2 = - { - .header = { - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_piwg_device_path), 0} - }, - .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, - 0x01, 0xAE, 0xF2, 0xB7}} - }, - .end = - { - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_device_path), 0} +#define MAKE_PIWG_PATH(st, en) \ + { \ + .comp1 = \ + { \ + .header = { \ + .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, \ + .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, \ + .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} \ + }, \ + .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, \ + .start_address = st, \ + .end_address = en \ + }, \ + .comp2 = \ + { \ + .header = { \ + .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, \ + .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, \ + .length = {sizeof (struct grub_efi_piwg_device_path), 0} \ + }, \ + .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, \ + 0x01, 0xAE, 0xF2, 0xB7}} \ + }, \ + .end = \ + { \ + .type = GRUB_EFI_END_DEVICE_PATH_TYPE, \ + .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, \ + .length = {sizeof (struct grub_efi_device_path), 0} \ + } \ } -}; + +/* early 2006 Core Duo / Core Solo models */ +static struct piwg_full_device_path devpath_1 = MAKE_PIWG_PATH (0xffe00000, + 0xfff9ffff); /* mid-2006 Mac Pro (and probably other Core 2 models) */ -static struct piwg_full_device_path devpath_2 = -{ - .comp1 = - { - .header = { - .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} - }, - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, - .start_address = 0xffe00000, - .end_address = 0xfff7ffff - }, - .comp2 = - { - .header = { - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_piwg_device_path), 0} - }, - .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, - 0x01, 0xAE, 0xF2, 0xB7}} - }, - .end = - { - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_device_path), 0} - } -}; +static struct piwg_full_device_path devpath_2 = MAKE_PIWG_PATH (0xffe00000, + 0xfff7ffff); /* mid-2007 MBP ("Santa Rosa" based models) */ -static struct piwg_full_device_path devpath_3 = -{ - .comp1 = - { - .header = { - .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} - }, - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, - .start_address = 0xffe00000, - .end_address = 0xfff8ffff - }, - .comp2 = - { - .header = { - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_piwg_device_path), 0} - }, - .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, - 0x01, 0xAE, 0xF2, 0xB7}} - }, - .end = - { - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_device_path), 0} - } -}; +static struct piwg_full_device_path devpath_3 = MAKE_PIWG_PATH (0xffe00000, + 0xfff8ffff); /* early-2008 MBA */ -static struct piwg_full_device_path devpath_4 = -{ - .comp1 = - { - .header = { - .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} - }, - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, - .start_address = 0xffc00000, - .end_address = 0xfff8ffff - }, - .comp2 = - { - .header = { - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_piwg_device_path), 0} - }, - .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, - 0x01, 0xAE, 0xF2, 0xB7}} - }, - .end = - { - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_device_path), 0} - } -}; +static struct piwg_full_device_path devpath_4 = MAKE_PIWG_PATH (0xffc00000, + 0xfff8ffff); /* late-2008 MB/MBP (NVidia chipset) */ -static struct piwg_full_device_path devpath_5 = -{ - .comp1 = - { - .header = { - .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} - }, - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, - .start_address = 0xffcb4000, - .end_address = 0xffffbfff - }, - .comp2 = - { - .header = { - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_piwg_device_path), 0} - }, - .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, - 0x01, 0xAE, 0xF2, 0xB7}} - }, - .end = - { - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_device_path), 0} - } -}; +static struct piwg_full_device_path devpath_5 = MAKE_PIWG_PATH (0xffcb4000, + 0xffffbfff); /* mid-2010 MB/MBP (NVidia chipset) */ -static struct piwg_full_device_path devpath_6 = -{ - .comp1 = - { - .header = { - .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} - }, - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, - .start_address = 0xffcc4000, - .end_address = 0xffffbfff - }, - .comp2 = - { - .header = { - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_piwg_device_path), 0} - }, - .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, - 0x01, 0xAE, 0xF2, 0xB7}} - }, - .end = - { - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - .length = {sizeof (struct grub_efi_device_path), 0} - } -}; +static struct piwg_full_device_path devpath_6 = MAKE_PIWG_PATH (0xffcc4000, + 0xffffbfff); struct devdata { From c5934345bea4070e56813c4064645240ff902f4a Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Fri, 6 May 2011 14:03:51 -0300 Subject: [PATCH 0956/1414] Free memory when removing packet. --- include/grub/net.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grub/net.h b/include/grub/net.h index 37b258f36..59974b94f 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -178,6 +178,7 @@ grub_net_remove_packet (grub_net_packet_t *pkt) pkt->next->prev = pkt->prev; else pkt->up->last = pkt->prev; + grub_free (pkt); } typedef struct grub_net_app_protocol *grub_net_app_level_t; From 5452733f3505fcd1135c3705a9565365be60bfd5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 8 May 2011 12:39:08 +0200 Subject: [PATCH 0957/1414] 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 0958/1414] 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 0959/1414] 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 0960/1414] 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 0961/1414] 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 0962/1414] 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 0963/1414] 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 0964/1414] 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 0965/1414] 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 0966/1414] 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 0967/1414] 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 0968/1414] * 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 0969/1414] * 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 0970/1414] * 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 0971/1414] 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 0972/1414] * 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 0973/1414] * 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 0974/1414] * 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 0975/1414] * 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 4f7386025b3bc0e5da39e79062aaef02a924a86a Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:28:45 -0300 Subject: [PATCH 0976/1414] Correct expected argument numbers in del addr command. --- grub-core/net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 636aaefaf..48fb350d2 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -200,7 +200,7 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), { struct grub_net_network_level_interface *inter; - if (argc != 4) + if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); FOR_NET_NETWORK_LEVEL_INTERFACES (inter) From 1893017d440b967cb977888ad1fbc4f4cf2df9a4 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:30:26 -0300 Subject: [PATCH 0977/1414] Mark file as not easily seekable on net open. --- grub-core/net/net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 48fb350d2..cdeaa5a32 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -609,6 +609,7 @@ grub_net_file_open_real (struct grub_file *file, const char *name) if ((err = file->device->net->protocol->open (file,name))) goto fail; + file->not_easily_seekable = 1; return GRUB_ERR_NONE; fail: From 4d6374ba7855abc9726d838258ec8093bc1238f1 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:32:38 -0300 Subject: [PATCH 0978/1414] Implement file close in network tranference. Stop receiving packets from card on error. --- grub-core/kern/file.c | 8 ++++++-- grub-core/net/net.c | 26 +++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index 6e7ed0e57..2b3e9d689 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -27,6 +27,7 @@ grub_ssize_t (*grub_file_net_read) (grub_file_t file, void *buf, grub_size_t len) = NULL; grub_err_t (*grub_file_net_open) (struct grub_file *file, const char *name) = NULL; +grub_err_t (*grub_file_net_close) (grub_file_t file) = NULL; grub_err_t (*grub_file_net_seek) (struct grub_file *file, grub_off_t offset) = NULL; grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX]; @@ -176,8 +177,11 @@ grub_err_t grub_file_close (grub_file_t file) { if (file->device->net) - return grub_errno; - + { + grub_file_net_close (file); + return grub_errno; + } + if (file->fs->close) (file->fs->close) (file); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index cdeaa5a32..6ccf20725 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -619,18 +619,35 @@ fail: } +static grub_err_t +grub_net_file_close_real (grub_file_t file) +{ + grub_net_socket_t sock = file->device->net->socket; + while (sock->packs->first) + { + grub_netbuff_free (sock->packs->first->nb); + grub_net_remove_packet (sock->packs->first); + } + grub_net_socket_unregister (sock); + grub_free (sock); + return GRUB_ERR_NONE; + +} + static grub_err_t receive_packets (struct grub_net_card *card) { /* Maybe should be better have a fixed number of packets for each card and just mark them as used and not used. */ struct grub_net_buff *nb; + grub_err_t err; nb = grub_netbuff_alloc (1500); if (!nb) return grub_errno; - card->driver->recv (card, nb); - return GRUB_ERR_NONE; + if ((err = card->driver->recv (card, nb)) != GRUB_ERR_NONE) + grub_netbuff_free (nb); + return err; } void @@ -642,7 +659,8 @@ grub_net_pool_cards (unsigned time) { start_time = grub_get_time_ms (); while( (grub_get_time_ms () - start_time) < time) - receive_packets (card); + if( receive_packets (card) != GRUB_ERR_NONE) + break; } } @@ -1018,6 +1036,7 @@ GRUB_MOD_INIT(net) grub_net_open = grub_net_open_real; grub_file_net_open = grub_net_file_open_real; + grub_file_net_close = grub_net_file_close_real; grub_file_net_read = grub_net_read_real; grub_file_net_seek = grub_net_seek_real; } @@ -1034,4 +1053,5 @@ GRUB_MOD_FINI(net) grub_net_open = NULL; grub_file_net_read = NULL; grub_file_net_open = NULL; + grub_file_net_close = NULL; } From a5184d629a4411f8c74eeb1b244523ddddf1512e Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:45:57 -0300 Subject: [PATCH 0979/1414] Prevente a bootp packet to be sent on open. --- grub-core/net/drivers/ieee1275/ofnet.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 10de81bc7..ce7ab32a8 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -1,17 +1,23 @@ #include #include #include +#include #include +#include static grub_err_t card_open (struct grub_net_card *dev) { int status; struct grub_ofnetcard_data *data = dev->data; - status = grub_ieee1275_open (data->path,&(data->handle)); + char path[grub_strlen(data->path) + grub_strlen(":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512") + 1]; + /* The full string will prevent a bootp packet to be sent. Just put some valid ip in there. */ + grub_snprintf(path,sizeof(path),"%s%s",data->path,":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512"); + status = grub_ieee1275_open (path,&(data->handle)); if (status) - return grub_error (GRUB_ERR_IO, "couldn't open network card"); + return grub_error (GRUB_ERR_IO, "Couldn't open network card."); + return GRUB_ERR_NONE; } From 0f231af8ae44b6e4efe6b25794db21fbfd270718 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:50:18 -0300 Subject: [PATCH 0980/1414] Implement timeout when receiving packets. --- grub-core/net/drivers/ieee1275/ofnet.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index ce7ab32a8..a7b66261c 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -42,24 +42,29 @@ send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) pack->tail - pack->data, &actual); if (status) - return grub_error (GRUB_ERR_IO, "couldn't send network packet"); + return grub_error (GRUB_ERR_IO, "Couldn't send network packet."); return GRUB_ERR_NONE; } static grub_err_t -get_card_packet (struct grub_net_card *dev, struct grub_net_buff *pack) +get_card_packet (struct grub_net_card *dev, struct grub_net_buff *nb) { int actual, rc; struct grub_ofnetcard_data *data = dev->data; - grub_netbuff_clear(pack); + grub_uint64_t start_time; + grub_netbuff_clear (nb); + start_time = grub_get_time_ms (); do - rc = grub_ieee1275_read (data->handle, pack->data, 1500, &actual); - while (actual <= 0 || rc < 0); - grub_netbuff_put (pack, actual); - - return GRUB_ERR_NONE; + rc = grub_ieee1275_read (data->handle, nb->data, data->mtu, &actual); + while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200)); + if (actual) + { + grub_netbuff_put (nb, actual); + return grub_net_recv_ethernet_packet (nb); + } + return GRUB_ERR_TIMEOUT; } static struct grub_net_card_driver ofdriver = From 70c52f3e248a67ad809c1309095b59cfff9d6628 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:54:32 -0300 Subject: [PATCH 0981/1414] Remove cards with no associated driver. --- grub-core/net/drivers/ieee1275/ofnet.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index a7b66261c..e33622fe2 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -148,10 +148,12 @@ void grub_ofnet_findcards (void) lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; card->default_address = lla; + card->driver = NULL; card->data = ofdata; card->flags = 0; card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name); - grub_net_card_register (card); + grub_net_card_register (card); + return 0; } return 0; } @@ -192,19 +194,24 @@ void grub_ofnet_probecards (void) net.ipv4.masksize = 24; grub_net_add_route ("bootp-router", net, inter); } - grub_free (bootp_pckt); break; - } + } } } + grub_free (bootp_pckt); + } GRUB_MOD_INIT (ofnet) { + struct grub_net_card *card; grub_getbootp = grub_getbootp_real; grub_net_card_driver_register (&ofdriver); grub_ofnet_findcards (); grub_ofnet_probecards (); + FOR_NET_CARDS (card) + if (card->driver == NULL) + grub_net_card_unregister (card); } GRUB_MOD_FINI (ofnet) From 36e2782dba154140c30ba77dabf67cea2df02719 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 09:55:20 -0300 Subject: [PATCH 0982/1414] Only setup network in the card we booted from. --- grub-core/net/drivers/ieee1275/ofnet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index e33622fe2..4067e36cf 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -171,6 +171,7 @@ void grub_ofnet_probecards (void) grub_bootp_t bootp_pckt; grub_net_network_level_address_t addr; grub_net_network_level_netaddress_t net; + bootp_pckt = grub_getbootp (); /* Assign correspondent driver for each device. */ FOR_NET_CARDS (card) @@ -180,8 +181,7 @@ void grub_ofnet_probecards (void) if (driver->init(card) == GRUB_ERR_NONE) { card->driver = driver; - bootp_pckt = grub_getbootp (); - if (bootp_pckt) + if (bootp_pckt && grub_memcmp(bootp_pckt->chaddr,card->default_address.mac,6) == 0) { addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bootp_pckt->yiaddr; From 0696f08f9238087edf5c1f1b91779f7515e7aeb5 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 14:07:20 -0300 Subject: [PATCH 0983/1414] Prevente error in broken cards by limiting data size. --- grub-core/net/tftp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index cafb30585..6cc281085 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -126,8 +126,12 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) { data->block++; - if (nb->tail - nb->data < 1024) + unsigned size = nb->tail - nb->data; + if (size < 1024) sock->status = 2; + /* Prevent garbage in broken cards. */ + if (size > 1024) + grub_netbuff_unput (nb, size - 1024); } else grub_netbuff_clear(nb); From 31b5172bbd3cfa83f0cd9d83fce18a21e2796048 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 14:07:54 -0300 Subject: [PATCH 0984/1414] Implement close in TFTP --- grub-core/net/tftp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 6cc281085..13bd87d15 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -157,7 +157,8 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) static grub_err_t tftp_close (struct grub_file *file __attribute__ ((unused))) { - return 0; + grub_free (file->device->net->socket->data); + return GRUB_ERR_NONE; } static struct grub_net_app_protocol grub_tftp_protocol = From 8db3b0eca9704c93fde8e1b0d41741f2299cb2b3 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 10 May 2011 14:08:18 -0300 Subject: [PATCH 0985/1414] Remove unused file --- include/grub/net/disknet.h | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 include/grub/net/disknet.h diff --git a/include/grub/net/disknet.h b/include/grub/net/disknet.h deleted file mode 100644 index 59aa2a320..000000000 --- a/include/grub/net/disknet.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef GRUB_DISKNET_HEADER -#define GRUB_DISKNET_HEADER 1 - void grub_disknet_init(void); - void grub_disknet_fini(void); -#endif /* ! GRUB_NET_HEADER */ From d8123bfb54e92aff473edaac87b535cb81e1f778 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 12 May 2011 13:20:43 -0300 Subject: [PATCH 0986/1414] Correct some compile erros. --- grub-core/Makefile.core.def | 2 +- grub-core/kern/ieee1275/openfw.c | 1 - grub-core/net/drivers/ieee1275/ofnet.c | 1 + include/grub/net.h | 4 +--- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index e242d8ece..e1e1623e6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1503,7 +1503,7 @@ module = { module = { name = emunet; emu = net/drivers/emu/emunet.c; - enable = ieee1275; + enable = emu; }; module = { diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index fed4f7e76..3473fe362 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -25,7 +25,6 @@ #include #include #include -#include #include grub_bootp_t (*grub_getbootp) (void); diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 4067e36cf..44738c67a 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/include/grub/net.h b/include/grub/net.h index 59974b94f..cb6db06d8 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -434,7 +434,5 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, void grub_net_pool_cards (unsigned time); -void -hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str); - +extern grub_err_t (*EXPORT_VAR (grub_file_net_close)) (grub_file_t file); #endif /* ! GRUB_NET_HEADER */ From 48ac061ab6f4d685a1c93af59a0c366d3721a84d Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 12 May 2011 15:40:54 -0300 Subject: [PATCH 0987/1414] Prevent "incompatible license" error. --- grub-core/net/drivers/ieee1275/ofnet.c | 2 ++ grub-core/net/net.c | 2 ++ grub-core/net/tftp.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 44738c67a..cb3882ceb 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -6,6 +6,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t card_open (struct grub_net_card *dev) { diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 6ccf20725..be5279c99 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_net_route { struct grub_net_route *next; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 13bd87d15..278f6ed14 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -9,6 +9,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_err_t tftp_open (struct grub_file *file, const char *filename) { From 9b44fecaa65643896bfd95fc76a5a782b802e416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 13 May 2011 15:17:02 +0200 Subject: [PATCH 0988/1414] * 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 0989/1414] * 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 0990/1414] * 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 0991/1414] 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 0992/1414] 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 0993/1414] 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 0994/1414] 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 0995/1414] 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 0996/1414] 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 0997/1414] 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 0998/1414] 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 0999/1414] 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 1000/1414] * 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 1001/1414] 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 1002/1414] * 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 1003/1414] 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 1004/1414] * 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 1005/1414] * 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 1006/1414] * 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 1007/1414] 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 1008/1414] * 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 1009/1414] 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 1010/1414] * 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 1011/1414] * 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 1012/1414] * 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 1013/1414] * 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 1014/1414] * 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 1015/1414] * 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 1016/1414] * 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 1017/1414] 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 1018/1414] * 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 1019/1414] 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 1020/1414] 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 1021/1414] 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 1022/1414] * 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 1023/1414] * 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 1024/1414] 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 1025/1414] 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 1026/1414] 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 1027/1414] 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 1028/1414] 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 1029/1414] 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 1030/1414] 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 1031/1414] * 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 1032/1414] * 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 1033/1414] * 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 1034/1414] * 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 1035/1414] * .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 1036/1414] 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 1037/1414] 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 1038/1414] 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 1039/1414] 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 1040/1414] * 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 1041/1414] 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 1042/1414] * 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 1043/1414] 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 1044/1414] 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 1045/1414] * 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 1046/1414] * 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 1047/1414] 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 1048/1414] * 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 1049/1414] * .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 1050/1414] * 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 1051/1414] * 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 eea841440d27babefa8dbc1e1e7810875a06eef7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 19 May 2011 15:39:34 +0200 Subject: [PATCH 1052/1414] fix several bugs --- Makefile.util.def | 2 - grub-core/Makefile.am | 1 + grub-core/commands/ls.c | 22 +++--- grub-core/net/arp.c | 7 +- grub-core/net/drivers/emu/emunet.c | 8 +-- grub-core/net/drivers/ieee1275/ofnet.c | 7 +- grub-core/net/net.c | 96 +++++++++++++------------- grub-core/net/tftp.c | 17 +++-- grub-core/net/udp.c | 5 +- include/grub/net.h | 14 ++-- 10 files changed, 89 insertions(+), 90 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index 79ab040dd..058572f06 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -36,8 +36,6 @@ library = { common = grub-core/commands/blocklist.c; common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; - common = grub-core/net/net.c; - common = grub-core/net/netbuff.c; common = grub-core/disk/dmraid_nvidia.c; common = grub-core/disk/loopback.c; common = grub-core/disk/lvm.c; diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 0fdb4b1db..d5cd25a70 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -167,6 +167,7 @@ endif if COND_emu KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/export.h if COND_GRUB_EMU_SDL KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h endif diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 20a75733c..9df830612 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -48,9 +48,6 @@ static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'}; static grub_err_t grub_ls_list_devices (int longlist) { - grub_net_app_level_t proto; - int first = 1; - auto int grub_ls_print_devices (const char *name); int grub_ls_print_devices (const char *name) { @@ -65,15 +62,20 @@ grub_ls_list_devices (int longlist) grub_device_iterate (grub_ls_print_devices); grub_xputs ("\n"); - FOR_NET_APP_LEVEL (proto) +#ifndef GRUB_UTIL { - if (first) - grub_puts_ (N_ ("Network protocols:")); - first = 0; - grub_printf ("%s ", proto->name); + grub_net_app_level_t proto; + int first = 1; + FOR_NET_APP_LEVEL (proto) + { + if (first) + grub_puts_ (N_ ("Network protocols:")); + first = 0; + grub_printf ("%s ", proto->name); + } + grub_xputs ("\n"); } - - grub_xputs ("\n"); +#endif grub_refresh (); diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 8778a6e51..1300def25 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -87,11 +87,10 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, grub_memcpy (hw_addr, &entry->ll_address, sizeof (*hw_addr)); return GRUB_ERR_NONE; } - grub_net_pool_cards (200); + grub_net_poll_cards (200); + } - } - - return grub_error (GRUB_ERR_TIMEOUT, "Timeout: could not resolve hardware address."); + return grub_error (GRUB_ERR_TIMEOUT, "timeout: could not resolve hardware address"); } grub_err_t diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c index 9e4e66dce..d707d8015 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -26,7 +26,7 @@ send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), return GRUB_ERR_NONE; } -static grub_size_t +static grub_ssize_t get_card_packet (struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { @@ -35,10 +35,7 @@ get_card_packet (struct grub_net_card *dev __attribute__ ((unused)), grub_netbuff_clear(pack); actual = read (fd, pack->data, 1500); if (actual < 0) - { - grub_error (GRUB_ERR_IO, "couldn't receive packets"); - return -1; - } + return -1; grub_netbuff_put (pack, actual); return actual; @@ -65,7 +62,6 @@ static struct grub_net_card emucard = GRUB_MOD_INIT(emunet) { struct ifreq ifr; - // char fullname[64]; fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK); if (fd < 0) return; diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index cb3882ceb..10d0b979e 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -49,7 +48,7 @@ send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) return GRUB_ERR_NONE; } -static grub_err_t +static grub_ssize_t get_card_packet (struct grub_net_card *dev, struct grub_net_buff *nb) { @@ -65,9 +64,9 @@ get_card_packet (struct grub_net_card *dev, struct grub_net_buff *nb) if (actual) { grub_netbuff_put (nb, actual); - return grub_net_recv_ethernet_packet (nb); + return actual; } - return GRUB_ERR_TIMEOUT; + return -1; } static struct grub_net_card_driver ofdriver = diff --git a/grub-core/net/net.c b/grub-core/net/net.c index be5279c99..a82e73ab0 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -587,9 +588,13 @@ grub_net_file_open_real (struct grub_file *file, const char *name) grub_net_network_level_address_t gateway; grub_net_socket_t socket; static int port = 25300; + const char *comma; - err = grub_net_resolve_address (file->device->net->name - + sizeof (file->device->net->protocol->name) + 1, &addr); + comma = grub_strchr (file->device->net->name, ','); + if (!comma) + return grub_error (GRUB_ERR_NET_BAD_ADDRESS, "no separator"); + + err = grub_net_resolve_address (comma + 1, &addr); if (err) return err; @@ -597,19 +602,22 @@ grub_net_file_open_real (struct grub_file *file, const char *name) if (err) return err; - if ((socket = (grub_net_socket_t) grub_malloc (sizeof (*socket))) == NULL) - return GRUB_ERR_OUT_OF_MEMORY; + socket = (grub_net_socket_t) grub_malloc (sizeof (*socket)); + if (socket == NULL) + return grub_errno; socket->inf = inf; socket->out_nla = addr; socket->in_port = port++; socket->status = 0; socket->app = file->device->net->protocol; - socket->packs = NULL; + socket->packs.first = NULL; + socket->packs.last = NULL; file->device->net->socket = socket; grub_net_socket_register (socket); - if ((err = file->device->net->protocol->open (file,name))) + err = file->device->net->protocol->open (file,name); + if (err) goto fail; file->not_easily_seekable = 1; @@ -625,10 +633,10 @@ static grub_err_t grub_net_file_close_real (grub_file_t file) { grub_net_socket_t sock = file->device->net->socket; - while (sock->packs->first) + while (sock->packs.first) { - grub_netbuff_free (sock->packs->first->nb); - grub_net_remove_packet (sock->packs->first); + grub_netbuff_free (sock->packs.first->nb); + grub_net_remove_packet (sock->packs.first); } grub_net_socket_unregister (sock); grub_free (sock); @@ -636,39 +644,44 @@ grub_net_file_close_real (grub_file_t file) } -static grub_err_t +static void receive_packets (struct grub_net_card *card) { /* Maybe should be better have a fixed number of packets for each card and just mark them as used and not used. */ struct grub_net_buff *nb; - grub_err_t err; + grub_ssize_t actual; nb = grub_netbuff_alloc (1500); if (!nb) - return grub_errno; + { + grub_print_error (); + return; + } - if ((err = card->driver->recv (card, nb)) != GRUB_ERR_NONE) + actual = card->driver->recv (card, nb); + if (actual < 0) grub_netbuff_free (nb); - return err; + else + grub_net_recv_ethernet_packet (nb); + grub_print_error (); } void -grub_net_pool_cards (unsigned time) +grub_net_poll_cards (unsigned time) { struct grub_net_card *card; grub_uint64_t start_time; FOR_NET_CARDS (card) { start_time = grub_get_time_ms (); - while( (grub_get_time_ms () - start_time) < time) - if( receive_packets (card) != GRUB_ERR_NONE) - break; + while ((grub_get_time_ms () - start_time) < time) + receive_packets (card); } } +/* Read from the packets list*/ static grub_ssize_t -process_packets (grub_file_t file, void *buf, grub_size_t len, - void *NESTED_FUNC_ATTR (hook) (void *dest, const void *src, grub_size_t n)) +grub_net_read_real (grub_file_t file, void *buf, grub_size_t len) { grub_net_socket_t sock = file->device->net->socket; struct grub_net_buff *nb; @@ -677,19 +690,24 @@ process_packets (grub_file_t file, void *buf, grub_size_t len, int try = 0; while (try <= 3) { - while (sock->packs->first) + while (sock->packs.first) { try = 0; - nb = sock->packs->first->nb; - amount = (grub_size_t)(len <= (grub_size_t) (nb->tail - nb->data))? len :(grub_size_t)(nb->tail - nb->data); + nb = sock->packs.first->nb; + amount = nb->tail - nb->data; + if (amount > len) + amount = len; len -= amount; total += amount; - hook (ptr, nb->data, amount); - ptr += amount; + if (buf) + { + grub_memcpy (ptr, nb->data, amount); + ptr += amount; + } if (amount == (grub_size_t) (nb->tail - nb->data)) { grub_netbuff_free (nb); - grub_net_remove_packet (sock->packs->first); + grub_net_remove_packet (sock->packs.first); } else nb->data += amount; @@ -700,7 +718,7 @@ process_packets (grub_file_t file, void *buf, grub_size_t len, if (sock->status == 1) { try++; - grub_net_pool_cards (200); + grub_net_poll_cards (200); } else return total; @@ -708,20 +726,6 @@ process_packets (grub_file_t file, void *buf, grub_size_t len, return total; } - -/* Read from the packets list*/ -static grub_ssize_t -grub_net_read_real (grub_file_t file, void *buf, grub_size_t len ) -{ - auto void *NESTED_FUNC_ATTR memcpy_hook (void *dest, const void *src, grub_size_t n); - void *NESTED_FUNC_ATTR memcpy_hook (void *dest __attribute__ ((unused)), const void *src __attribute__ ((unused)), - grub_size_t n __attribute__ ((unused))) - { - return grub_memcpy (dest, src, n); - } - return process_packets (file, buf, len, memcpy_hook); -} - /* Read from the packets list*/ static grub_err_t grub_net_seek_real (struct grub_file *file, grub_off_t offset) @@ -736,17 +740,11 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) /* We cant seek backwards past the current packet. */ if (file->offset > offset) { - nb = sock->packs->first->nb; + nb = sock->packs.first->nb; return grub_netbuff_push (nb, file->offset - offset); } - auto void *NESTED_FUNC_ATTR dummy (void *dest, const void *src, grub_size_t n); - void *NESTED_FUNC_ATTR dummy (void *dest __attribute__ ((unused)), const void *src __attribute__ ((unused)), - grub_size_t n __attribute__ ((unused))) - { - return NULL; - } - process_packets (file, NULL, len, dummy); + grub_net_read_real (file, NULL, len); return GRUB_ERR_NONE; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 278f6ed14..1daf11bc7 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -21,8 +21,12 @@ tftp_open (struct grub_file *file, const char *filename) int hdrlen; char open_data[1500]; struct grub_net_buff nb; - tftp_data_t data = grub_malloc (sizeof *data); + tftp_data_t data; grub_err_t err; + + data = grub_malloc (sizeof *data); + if (!data) + return grub_errno; file->device->net->socket->data = (void *) data; nb.head = open_data; @@ -74,7 +78,7 @@ tftp_open (struct grub_file *file, const char *filename) /* Receive OACK packet. */ for ( i = 0; i < 3; i++) { - grub_net_pool_cards (100); + grub_net_poll_cards (100); if (grub_errno) return grub_errno; if (file->device->net->socket->status != 0) @@ -110,10 +114,13 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) switch (grub_be_to_cpu16 (tftph->opcode)) { case TFTP_OACK: - for (ptr = nb->data; ptr < nb->tail; ) + for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail; ) { if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) - data->file_size = grub_strtoul (ptr + sizeof ("tsize\0") - 1, 0, 0); + { + data->file_size = grub_strtoul (ptr + sizeof ("tsize\0") - 1, + 0, 0); + } while (ptr < nb->tail && *ptr) ptr++; ptr++; @@ -150,7 +157,7 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); - tftph->u.ack.block = data->block; + tftph->u.ack.block = grub_cpu_to_be16 (data->block); err = grub_net_send_udp_packet (sock, &nb_ack); return err; diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 16b2011ff..4477b3c2b 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -36,15 +36,14 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) if (grub_be_to_cpu16 (udph->dst) == sock->in_port) { if (sock->status == 0) - sock->out_port = udph->src; + sock->out_port = grub_be_to_cpu16 (udph->src); - /* App protocol remove its own reader. */ sock->app->read (sock,nb); /* If there is data, puts packet in socket list */ if ((nb->tail - nb->data) > 0) - grub_net_put_packet (sock->packs, nb); + grub_net_put_packet (&sock->packs, nb); else grub_netbuff_free (nb); return GRUB_ERR_NONE; diff --git a/include/grub/net.h b/include/grub/net.h index cb6db06d8..1b113972b 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -63,7 +63,7 @@ struct grub_net_card_driver grub_err_t (*init) (struct grub_net_card *dev); grub_err_t (*fini) (struct grub_net_card *dev); grub_err_t (*send) (struct grub_net_card *dev, struct grub_net_buff *buf); - grub_size_t (*recv) (struct grub_net_card *dev, struct grub_net_buff *buf); + grub_ssize_t (*recv) (struct grub_net_card *dev, struct grub_net_buff *buf); }; extern struct grub_net_card_driver *grub_net_card_drivers; @@ -207,24 +207,24 @@ struct grub_net_socket grub_net_app_level_t app; grub_net_network_level_address_t out_nla; struct grub_net_network_level_interface *inf; - grub_net_packets_t *packs; + grub_net_packets_t packs; void *data; }; extern struct grub_net_socket *grub_net_sockets; static inline void -grub_net_socket_register (grub_net_socket_t socket) +grub_net_socket_register (grub_net_socket_t sock) { grub_list_push (GRUB_AS_LIST_P (&grub_net_sockets), - GRUB_AS_LIST (socket)); + GRUB_AS_LIST (sock)); } static inline void -grub_net_socket_unregister (grub_net_socket_t socket) +grub_net_socket_unregister (grub_net_socket_t sock) { grub_list_remove (GRUB_AS_LIST_P (&grub_net_sockets), - GRUB_AS_LIST (socket)); + GRUB_AS_LIST (sock)); } #define FOR_NET_SOCKETS(var) for (var = grub_net_sockets; var; var = var->next) @@ -432,7 +432,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, #define FOR_NET_NL_PACKETS(inf, var) FOR_PACKETS(inf->nl_pending, var) void -grub_net_pool_cards (unsigned time); +grub_net_poll_cards (unsigned time); extern grub_err_t (*EXPORT_VAR (grub_file_net_close)) (grub_file_t file); #endif /* ! GRUB_NET_HEADER */ From f35fa3a664474529be91252380eab589838add6d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 20 May 2011 11:21:36 +0100 Subject: [PATCH 1053/1414] * 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 1054/1414] 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 1055/1414] * 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; From f42313bdb07e5a9bb5f6ca92a37f342aae5a1bfa Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Wed, 25 May 2011 11:10:48 -0300 Subject: [PATCH 1056/1414] Remove unused structs and functions. --- include/grub/disk.h | 20 +------------------- include/grub/ieee1275/ofnet.h | 3 --- include/grub/net/ieee1275/interface.h | 10 ---------- include/grub/net/mem.h | 9 --------- 4 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 include/grub/net/ieee1275/interface.h delete mode 100644 include/grub/net/mem.h diff --git a/include/grub/disk.h b/include/grub/disk.h index 101303205..66db1149a 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -42,8 +42,7 @@ 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_OFNET_ID + GRUB_DISK_DEVICE_LUKS_ID }; struct grub_disk; @@ -117,23 +116,6 @@ struct grub_disk }; typedef struct grub_disk *grub_disk_t; -/* Net Disk */ -enum grub_netdisk_protocol -{ - GRUB_NETDISK_PROTOCOL_TFTP -}; -typedef enum grub_netdisk_protocol grub_netdisk_protocol_t; - -struct grub_netdisk_data -{ - grub_netdisk_protocol_t protocol; - grub_uint32_t server_ip; - grub_uint32_t port; - char *username; - char *password; -}; -typedef struct grub_netdisk_data *grub_netdisk_data_t; - #ifdef GRUB_UTIL struct grub_disk_memberlist { diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h index 9a0ae29e3..c7284df38 100644 --- a/include/grub/ieee1275/ofnet.h +++ b/include/grub/ieee1275/ofnet.h @@ -23,9 +23,6 @@ #include #include -void grub_ofnet_init(void); -void grub_ofnet_fini(void); - struct grub_ofnet { /* The net name. */ diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h deleted file mode 100644 index c369e35a6..000000000 --- a/include/grub/net/ieee1275/interface.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GRUB_IEEE1275_INTERFACE_HEADER -#define GRUB_IEEE1275_INTERFACE_HEADER 1 - -#include -#include -#include -#include - -grub_bootp_t bootp_pckt; -#endif diff --git a/include/grub/net/mem.h b/include/grub/net/mem.h deleted file mode 100644 index bbdac512b..000000000 --- a/include/grub/net/mem.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef GRUB_NETMM_H -#define GRUB_NETMM_H 1 - -#include -#include - -void *EXPORT_FUNC(grub_net_malloc) (grub_size_t size); - -#endif /* ! GRUB_MM_H */ From 7dd64f12368b8ee35eb32b52b0f6e69068053ab2 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Fri, 27 May 2011 00:22:35 -0300 Subject: [PATCH 1057/1414] Use a net fs struct to handle open, reand and close in file. --- grub-core/kern/file.c | 25 ++--------------------- grub-core/kern/fs.c | 4 ++-- grub-core/kern/ieee1275/openfw.c | 1 - grub-core/net/net.c | 34 +++++++++++++++++++++----------- include/grub/net.h | 4 +--- 5 files changed, 27 insertions(+), 41 deletions(-) diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index 2b3e9d689..749e72dfc 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -25,9 +25,6 @@ #include #include -grub_ssize_t (*grub_file_net_read) (grub_file_t file, void *buf, grub_size_t len) = NULL; -grub_err_t (*grub_file_net_open) (struct grub_file *file, const char *name) = NULL; -grub_err_t (*grub_file_net_close) (grub_file_t file) = NULL; grub_err_t (*grub_file_net_seek) (struct grub_file *file, grub_off_t offset) = NULL; grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX]; @@ -91,13 +88,6 @@ grub_file_open (const char *name) file->device = device; - if (device->net && grub_file_net_open) - { - if (grub_file_net_open (file, file_name)) - goto fail; - return file; - } - if (device->disk && file_name[0] != '/') /* This is a block list. */ file->fs = &grub_fs_blocklist; @@ -143,7 +133,7 @@ grub_file_open (const char *name) grub_ssize_t grub_file_read (grub_file_t file, void *buf, grub_size_t len) { - grub_ssize_t res = 0; + grub_ssize_t res; if (file->offset > file->size) { @@ -161,12 +151,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) if (len == 0) return 0; - if (file->device->disk) - res = (file->fs->read) (file, buf, len); - else - if (grub_file_net_read && file->device->net) - res = grub_file_net_read (file, buf, len); - + res = (file->fs->read) (file, buf, len); if (res > 0) file->offset += res; @@ -176,12 +161,6 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) grub_err_t grub_file_close (grub_file_t file) { - if (file->device->net) - { - grub_file_net_close (file); - return grub_errno; - } - if (file->fs->close) (file->fs->close) (file); diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c index 7166648be..14d389e07 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -94,8 +94,8 @@ grub_fs_probe (grub_device_t device) count--; } } - else if (device->net) - return NULL; + else if (device->net && device->net->fs) + return device->net->fs; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); return 0; diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 3473fe362..db4bec90a 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/grub-core/net/net.c b/grub-core/net/net.c index a82e73ab0..1232b3c74 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -49,6 +49,7 @@ struct grub_net_network_level_interface *grub_net_network_level_interfaces = NUL struct grub_net_card *grub_net_cards = NULL; struct grub_net_card_driver *grub_net_card_drivers = NULL; struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; +static struct grub_fs grub_net_fs; static inline void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) @@ -571,6 +572,7 @@ grub_net_open_real (const char *name) grub_free (ret); return NULL; } + ret->fs = &grub_net_fs; return ret; } } @@ -580,7 +582,7 @@ grub_net_open_real (const char *name) } static grub_err_t -grub_net_file_open_real (struct grub_file *file, const char *name) +grub_net_fs_open (struct grub_file *file, const char *name) { grub_err_t err; grub_net_network_level_address_t addr; @@ -620,7 +622,7 @@ grub_net_file_open_real (struct grub_file *file, const char *name) if (err) goto fail; file->not_easily_seekable = 1; - + return GRUB_ERR_NONE; fail: grub_net_socket_unregister (socket); @@ -630,7 +632,7 @@ fail: } static grub_err_t -grub_net_file_close_real (grub_file_t file) +grub_net_fs_close (grub_file_t file) { grub_net_socket_t sock = file->device->net->socket; while (sock->packs.first) @@ -681,11 +683,11 @@ grub_net_poll_cards (unsigned time) /* Read from the packets list*/ static grub_ssize_t -grub_net_read_real (grub_file_t file, void *buf, grub_size_t len) +grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) { grub_net_socket_t sock = file->device->net->socket; struct grub_net_buff *nb; - char *ptr = (char *) buf; + char *ptr = buf; grub_size_t amount, total = 0; int try = 0; while (try <= 3) @@ -744,7 +746,7 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) return grub_netbuff_push (nb, file->offset - offset); } - grub_net_read_real (file, NULL, len); + grub_net_fs_read (file, NULL, len); return GRUB_ERR_NONE; } @@ -1009,6 +1011,17 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), "unrecognised format specification %s", args[3]); } +static struct grub_fs grub_net_fs = + { + .name = "netfs", + .dir = NULL, + .open = grub_net_fs_open, + .read = grub_net_fs_read, + .close = grub_net_fs_close, + .label = NULL, + .uuid = NULL, + .mtime = NULL, + }; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp; @@ -1034,10 +1047,8 @@ GRUB_MOD_INIT(net) N_("VAR INTERFACE NUMBER DESCRIPTION"), N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); + grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; - grub_file_net_open = grub_net_file_open_real; - grub_file_net_close = grub_net_file_close_real; - grub_file_net_read = grub_net_read_real; grub_file_net_seek = grub_net_seek_real; } @@ -1050,8 +1061,7 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_lsroutes); grub_unregister_command (cmd_lscards); grub_unregister_command (cmd_getdhcp); + grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; - grub_file_net_read = NULL; - grub_file_net_open = NULL; - grub_file_net_close = NULL; + grub_file_net_seek = NULL; } diff --git a/include/grub/net.h b/include/grub/net.h index 1b113972b..f9745acec 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -234,11 +234,10 @@ typedef struct grub_net char *name; grub_net_app_level_t protocol; grub_net_socket_t socket; + grub_fs_t fs; } *grub_net_t; extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); -extern grub_ssize_t (*EXPORT_VAR (grub_file_net_read)) (grub_file_t file, void *buf, grub_size_t len); -extern grub_err_t (*EXPORT_VAR (grub_file_net_open)) (struct grub_file *file, const char *name); extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, grub_off_t offset); struct grub_net_network_level_interface @@ -434,5 +433,4 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, void grub_net_poll_cards (unsigned time); -extern grub_err_t (*EXPORT_VAR (grub_file_net_close)) (grub_file_t file); #endif /* ! GRUB_NET_HEADER */ From c64db050f7f8669fa0b7e27811c869febbeaa848 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 27 May 2011 13:52:21 +0100 Subject: [PATCH 1058/1414] * grub-core/kern/emu/hostdisk.c (linux_find_partition): Give up after ten consecutive open failures. Scanning all the way up to 10000 is excessive and can cause serious performance problems in some configurations. Fixes Ubuntu bug #787461. --- ChangeLog | 8 ++++++++ grub-core/kern/emu/hostdisk.c | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 198750f6a..351700803 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-05-27 Colin Watson + + * grub-core/kern/emu/hostdisk.c (linux_find_partition): Give up + after ten consecutive open failures. Scanning all the way up to + 10000 is excessive and can cause serious performance problems in + some configurations. + Fixes Ubuntu bug #787461. + 2011-05-21 Vladimir Serbinenko * grub-core/disk/arc/arcdisk.c (reopen): Close old handle before diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index d633059c3..e404c4fea 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -564,6 +564,7 @@ linux_find_partition (char *dev, grub_disk_addr_t sector) int i; char real_dev[PATH_MAX]; struct linux_partition_cache *cache; + int missing = 0; strcpy(real_dev, dev); @@ -602,7 +603,13 @@ linux_find_partition (char *dev, grub_disk_addr_t sector) fd = open (real_dev, O_RDONLY); if (fd == -1) - continue; + { + if (missing++ < 10) + continue; + else + return 0; + } + missing = 0; close (fd); start = find_partition_start (real_dev); From 6b4e643081999c9fe388ad5bd8ad96812777fc76 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 27 May 2011 13:57:22 +0100 Subject: [PATCH 1059/1414] * grub-core/kern/emu/hostdisk.c (linux_find_partition): Handle partitions under /dev/disk/by-id/. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 351700803..b9abcd07f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-27 Colin Watson + + * grub-core/kern/emu/hostdisk.c (linux_find_partition): Handle + partitions under /dev/disk/by-id/. + 2011-05-27 Colin Watson * grub-core/kern/emu/hostdisk.c (linux_find_partition): Give up diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e404c4fea..bb528d9bc 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -573,6 +573,12 @@ linux_find_partition (char *dev, grub_disk_addr_t sector) p = real_dev + len - 4; format = "part%d"; } + else if (strncmp (real_dev, "/dev/disk/by-id/", + sizeof ("/dev/disk/by-id/") - 1) == 0) + { + p = real_dev + len; + format = "-part%d"; + } else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9') { p = real_dev + len; From 351c7c8a155d1c3ace2cbefb9682c5b862082d98 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 29 May 2011 22:15:08 +0100 Subject: [PATCH 1060/1414] * docs/grub.texi (Obtaining and Building GRUB): Substitute `ftp.gnu.org' for `alpha.gnu.org'. --- ChangeLog | 5 +++++ docs/grub.texi | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9abcd07f..fca980c1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-05-29 Colin Watson + + * docs/grub.texi (Obtaining and Building GRUB): Substitute + `ftp.gnu.org' for `alpha.gnu.org'. + 2011-05-27 Colin Watson * grub-core/kern/emu/hostdisk.c (linux_find_partition): Handle diff --git a/docs/grub.texi b/docs/grub.texi index 818417d41..45c93d69c 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -4330,11 +4330,11 @@ how to get the latest version. @end quotation GRUB is available from the GNU alpha archive site -@uref{ftp://alpha.gnu.org/gnu/grub} or any of its mirrors. The file +@uref{ftp://ftp.gnu.org/gnu/grub} or any of its mirrors. The file will be named grub-version.tar.gz. The current version is @value{VERSION}, so the file you should grab is: -@uref{ftp://alpha.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz} +@uref{ftp://ftp.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz} To unbundle GRUB use the instruction: From 4f24b12e1fb7ad56b59dee6f545701a2864512a2 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Thu, 2 Jun 2011 15:13:33 -0300 Subject: [PATCH 1061/1414] Fix compilation in x86 --- grub-core/net/i386/pc/pxe.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/grub-core/net/i386/pc/pxe.c b/grub-core/net/i386/pc/pxe.c index 8e7f75ed8..27c4af17f 100644 --- a/grub-core/net/i386/pc/pxe.c +++ b/grub-core/net/i386/pc/pxe.c @@ -193,7 +193,7 @@ grub_pxefs_open (struct grub_file *file, const char *name) } file->data = data; - file->not_easly_seekable = 1; + file->not_easily_seekable = 1; grub_memcpy (file_int, file, sizeof (struct grub_file)); curr_file = file_int; @@ -215,7 +215,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; - grub_uint32_t pn, r; + grub_uint32_t pn; + grub_uint64_t r; data = file->data; @@ -292,7 +293,7 @@ grub_pxefs_label (grub_device_t device __attribute ((unused)), return GRUB_ERR_NONE; } -static struct grub_net_app_protocol grub_pxefs_fs = +static struct grub_fs grub_pxefs_fs = { .name = "pxe", .dir = grub_pxefs_dir, @@ -303,7 +304,7 @@ static struct grub_net_app_protocol grub_pxefs_fs = .next = 0 }; -static grub_size_t +static grub_ssize_t grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *buf __attribute__ ((unused))) { @@ -334,7 +335,7 @@ grub_pxe_unload (void) { if (grub_pxe_pxenv) { - grub_net_app_level_unregister (&grub_pxefs_fs); + grub_fs_unregister (&grub_pxefs_fs); grub_net_card_unregister (&grub_pxe_card); grub_pxe_pxenv = 0; } @@ -466,7 +467,7 @@ GRUB_MOD_INIT(pxe) ? bp->hw_len : sizeof (grub_pxe_card.default_address.mac)); grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_net_app_level_register (&grub_pxefs_fs); + grub_fs_register (&grub_pxefs_fs); grub_net_card_register (&grub_pxe_card); grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, GRUB_NET_INTERFACE_PERMANENT From 423a1849ef2d4791e03ef6cd6cd94d5bf75144af Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 7 Jun 2011 11:47:31 -0300 Subject: [PATCH 1062/1414] Write ChangeLog. --- ChangeLog | 26 ++++++++++++++++++++++++++ grub-core/net/tftp.c | 6 +++--- grub-core/net/udp.c | 3 +-- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 198750f6a..122ea029d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2011-06-07 Vladimir Serbinenko +2011-06-07 Manoel Rebelo Abranches + + Network infrastructure. + The ARP protocol was made by Paulo Pinatti + + * include/grub/net/arp.h: New file. + * include/grub/net/ethernet.h: New file. + * include/grub/net/ip.h: New file. + * include/grub/net/netbuff.h: New file. + * include/grub/net/tftp.h: New file. + * include/grub/net/udp.h: New file. + * include/grub/net.h: New file. + * grub-core/net/arp.c: New file. + * grub-core/net/ethernet.c: New file. + * grub-core/net/ip.c: New file. + * grub-core/net/netbuff.c: New file. + * grub-core/net/net.c: New file. + * grub-core/net/drivers/emu/emunet.c: New file. + * grub-core/net/drivers/ieee1275/ofnet.c: New file. + * grub-core/kern/device.c (grub_net_open) : New function. + (grub_device_open) : Handle Network device. + * grub-core/kern/file.c (grub_file_net_seek) : New function. + (grub_file_net_seek): Seek in network device. + + 2011-05-21 Vladimir Serbinenko * grub-core/disk/arc/arcdisk.c (reopen): Close old handle before diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 1daf11bc7..010a4a4bd 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -84,9 +84,9 @@ tftp_open (struct grub_file *file, const char *filename) if (file->device->net->socket->status != 0) break; /* Retry. */ - //err = grub_net_send_udp_packet (file->device->net->socket, &nb); - // if (err) - // return err; + /*err = grub_net_send_udp_packet (file->device->net->socket, &nb); + if (err) + return err;*/ } if (file->device->net->socket->status == 0) diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 4477b3c2b..0b19c3098 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -25,7 +25,6 @@ grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff grub_err_t grub_net_recv_udp_packet (struct grub_net_buff *nb) { - //grub_err_t err; struct udphdr *udph; grub_net_socket_t sock; udph = (struct udphdr *) nb->data; @@ -41,7 +40,7 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) /* App protocol remove its own reader. */ sock->app->read (sock,nb); - /* If there is data, puts packet in socket list */ + /* If there is data, puts packet in socket list. */ if ((nb->tail - nb->data) > 0) grub_net_put_packet (&sock->packs, nb); else From 4700d08bb4ed597a9aa122340b06fba137327bb7 Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Tue, 7 Jun 2011 21:59:53 -0300 Subject: [PATCH 1063/1414] Run indent on files. --- grub-core/net/arp.c | 91 ++++++++------- grub-core/net/drivers/emu/emunet.c | 39 +++---- grub-core/net/drivers/ieee1275/ofnet.c | 154 +++++++++++++------------ grub-core/net/ethernet.c | 28 ++--- grub-core/net/ip.c | 53 ++++----- grub-core/net/netbuff.c | 59 ++++++---- grub-core/net/tftp.c | 118 +++++++++---------- grub-core/net/udp.c | 53 ++++----- 8 files changed, 307 insertions(+), 288 deletions(-) diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 1300def25..0644d3d2e 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -9,10 +9,10 @@ static struct arp_entry arp_table[10]; static grub_int8_t new_table_entry = -1; -static -void arp_init_table(void) +static void +arp_init_table (void) { - grub_memset (arp_table, 0, sizeof (arp_table)); + grub_memset (arp_table, 0, sizeof (arp_table)); new_table_entry = 0; } @@ -20,19 +20,19 @@ static struct arp_entry * arp_find_entry (const grub_net_network_level_address_t *proto) { unsigned i; - for(i = 0; i < ARRAY_SIZE (arp_table); i++) + for (i = 0; i < ARRAY_SIZE (arp_table); i++) { - if(arp_table[i].avail == 1 && - arp_table[i].nl_address.ipv4 == proto->ipv4) - return &(arp_table[i]); + if (arp_table[i].avail == 1 && + arp_table[i].nl_address.ipv4 == proto->ipv4) + return &(arp_table[i]); } return NULL; } grub_err_t -grub_net_arp_resolve(struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr, - grub_net_link_level_address_t *hw_addr) +grub_net_arp_resolve (struct grub_net_network_level_interface *inf, + const grub_net_network_level_address_t *proto_addr, + grub_net_link_level_address_t *hw_addr) { struct arp_entry *entry; struct grub_net_buff nb; @@ -51,10 +51,10 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, /* Build a request packet. */ nb.head = arp_data; nb.end = arp_data + sizeof (arp_data); - grub_netbuff_clear (&nb); + grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb,128); - grub_netbuff_push (&nb, sizeof(*arp_header) + 2 * (6 + 4)); + grub_netbuff_reserve (&nb, 128); + grub_netbuff_push (&nb, sizeof (*arp_header) + 2 * (6 + 4)); arp_header = (struct arphdr *) nb.data; arp_header->hrd = grub_cpu_to_be16 (GRUB_NET_ARPHRD_ETHERNET); arp_header->pro = grub_cpu_to_be16 (GRUB_NET_ETHERTYPE_IP); @@ -71,11 +71,11 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, grub_memcpy (aux, &inf->address.ipv4, 4); aux += 4; /* Target hardware address */ - for(i = 0; i < 6; i++) + for (i = 0; i < 6; i++) aux[i] = 0x00; aux += 6; /* Target protocol address */ - grub_memcpy(aux, &proto_addr->ipv4, 4); + grub_memcpy (aux, &proto_addr->ipv4, 4); grub_memset (&target_hw_addr.mac, 0xff, 6); send_ethernet_packet (inf, &nb, target_hw_addr, GRUB_NET_ETHERTYPE_ARP); @@ -96,56 +96,59 @@ grub_net_arp_resolve(struct grub_net_network_level_interface *inf, grub_err_t grub_net_arp_receive (struct grub_net_buff *nb) { - struct arphdr *arp_header = (struct arphdr *)nb->data; + struct arphdr *arp_header = (struct arphdr *) nb->data; struct arp_entry *entry; grub_uint8_t *sender_hardware_address, *sender_protocol_address; grub_uint8_t *target_hardware_address, *target_protocol_address; grub_net_network_level_address_t hwaddress; struct grub_net_network_level_interface *inf; - sender_hardware_address = (grub_uint8_t *) arp_header + sizeof(*arp_header); + sender_hardware_address = + (grub_uint8_t *) arp_header + sizeof (*arp_header); sender_protocol_address = sender_hardware_address + arp_header->hln; target_hardware_address = sender_protocol_address + arp_header->pln; target_protocol_address = target_hardware_address + arp_header->hln; grub_memcpy (&hwaddress.ipv4, sender_protocol_address, 4); - /* Check if the sender is in the cache table */ - entry = arp_find_entry(&hwaddress); - /* Update sender hardware address */ + /* Check if the sender is in the cache table. */ + entry = arp_find_entry (&hwaddress); + /* Update sender hardware address. */ if (entry) - grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6); + grub_memcpy (entry->ll_address.mac, sender_hardware_address, 6); else { - /* Add sender to cache table */ + /* Add sender to cache table. */ if (new_table_entry == -1) - arp_init_table(); + arp_init_table (); entry = &(arp_table[new_table_entry]); entry->avail = 1; - grub_memcpy(&entry->nl_address.ipv4, sender_protocol_address, 4); - grub_memcpy(entry->ll_address.mac, sender_hardware_address, 6); + grub_memcpy (&entry->nl_address.ipv4, sender_protocol_address, 4); + grub_memcpy (entry->ll_address.mac, sender_hardware_address, 6); new_table_entry++; if (new_table_entry == ARRAY_SIZE (arp_table)) new_table_entry = 0; } - FOR_NET_NETWORK_LEVEL_INTERFACES(inf) - { - /* Am I the protocol address target? */ - if (grub_memcmp (target_protocol_address, &inf->address.ipv4, 6) == 0 - && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST) - { - grub_net_link_level_address_t aux; - /* Swap hardware fields */ - grub_memcpy (target_hardware_address, sender_hardware_address, arp_header->hln); - grub_memcpy (sender_hardware_address, inf->hwaddress.mac, 6); - grub_memcpy (aux.mac, sender_protocol_address, 6); - grub_memcpy (sender_protocol_address, target_protocol_address, arp_header->pln); - grub_memcpy (target_protocol_address, aux.mac, arp_header->pln); - /* Change operation to REPLY and send packet */ - arp_header->op = grub_be_to_cpu16 (ARP_REPLY); - grub_memcpy (aux.mac, target_hardware_address, 6); - send_ethernet_packet (inf, nb, aux, GRUB_NET_ETHERTYPE_ARP); - } - } + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { + /* Am I the protocol address target? */ + if (grub_memcmp (target_protocol_address, &inf->address.ipv4, 6) == 0 + && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST) + { + grub_net_link_level_address_t aux; + /* Swap hardware fields */ + grub_memcpy (target_hardware_address, sender_hardware_address, + arp_header->hln); + grub_memcpy (sender_hardware_address, inf->hwaddress.mac, 6); + grub_memcpy (aux.mac, sender_protocol_address, 6); + grub_memcpy (sender_protocol_address, target_protocol_address, + arp_header->pln); + grub_memcpy (target_protocol_address, aux.mac, arp_header->pln); + /* Change operation to REPLY and send packet */ + arp_header->op = grub_be_to_cpu16 (ARP_REPLY); + grub_memcpy (aux.mac, target_hardware_address, 6); + send_ethernet_packet (inf, nb, aux, GRUB_NET_ETHERTYPE_ARP); + } + } return GRUB_ERR_NONE; } diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c index d707d8015..ee4ba4773 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -13,7 +13,7 @@ static int fd; -static grub_err_t +static grub_err_t send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { @@ -22,7 +22,7 @@ send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), actual = write (fd, pack->data, pack->tail - pack->data); if (actual < 0) return grub_error (GRUB_ERR_IO, "couldn't send packets"); - + return GRUB_ERR_NONE; } @@ -32,32 +32,32 @@ get_card_packet (struct grub_net_card *dev __attribute__ ((unused)), { ssize_t actual; - grub_netbuff_clear(pack); + grub_netbuff_clear (pack); actual = read (fd, pack->data, 1500); if (actual < 0) return -1; grub_netbuff_put (pack, actual); - return actual; + return actual; } static struct grub_net_card_driver emudriver = -{ - .name = "emu", - .send = send_card_buffer, - .recv = get_card_packet -}; + { + .name = "emu", + .send = send_card_buffer, + .recv = get_card_packet + }; static struct grub_net_card emucard = -{ - .name = "emu0", - .driver = &emudriver, - .default_address = { - .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, - { .mac = { 0, 1, 2, 3, 4, 5} } - }, - .flags = 0 -}; + { + .name = "emu0", + .driver = &emudriver, + .default_address = { + .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, + {.mac = {0, 1, 2, 3, 4, 5}} + }, + .flags = 0 + }; GRUB_MOD_INIT(emunet) { @@ -84,6 +84,3 @@ GRUB_MOD_FINI(emunet) grub_net_card_unregister (&emucard); } } - - - diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 10d0b979e..751583e9d 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -7,15 +7,18 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_err_t +static grub_err_t card_open (struct grub_net_card *dev) { int status; struct grub_ofnetcard_data *data = dev->data; - char path[grub_strlen(data->path) + grub_strlen(":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512") + 1]; + char path[grub_strlen (data->path) + + grub_strlen (":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512") + 1]; + /* The full string will prevent a bootp packet to be sent. Just put some valid ip in there. */ - grub_snprintf(path,sizeof(path),"%s%s",data->path,":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512"); - status = grub_ieee1275_open (path,&(data->handle)); + grub_snprintf (path, sizeof (path), "%s%s", data->path, + ":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512"); + status = grub_ieee1275_open (path, &(data->handle)); if (status) return grub_error (GRUB_ERR_IO, "Couldn't open network card."); @@ -23,23 +26,23 @@ card_open (struct grub_net_card *dev) return GRUB_ERR_NONE; } -static grub_err_t +static grub_err_t card_close (struct grub_net_card *dev) { struct grub_ofnetcard_data *data = dev->data; - + if (data->handle) grub_ieee1275_close (data->handle); return GRUB_ERR_NONE; } -static grub_err_t +static grub_err_t send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) -{ +{ int actual; int status; struct grub_ofnetcard_data *data = dev->data; - + status = grub_ieee1275_write (data->handle, pack->data, pack->tail - pack->data, &actual); @@ -56,27 +59,27 @@ get_card_packet (struct grub_net_card *dev, struct grub_net_buff *nb) struct grub_ofnetcard_data *data = dev->data; grub_uint64_t start_time; - grub_netbuff_clear (nb); + grub_netbuff_clear (nb); start_time = grub_get_time_ms (); do rc = grub_ieee1275_read (data->handle, nb->data, data->mtu, &actual); while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200)); if (actual) { - grub_netbuff_put (nb, actual); + grub_netbuff_put (nb, actual); return actual; } return -1; } -static struct grub_net_card_driver ofdriver = -{ - .name = "ofnet", - .init = card_open, - .fini = card_close, - .send = send_card_buffer, - .recv = get_card_packet -}; +static struct grub_net_card_driver ofdriver = + { + .name = "ofnet", + .init = card_open, + .fini = card_close, + .send = send_card_buffer, + .recv = get_card_packet + }; static const struct { @@ -84,23 +87,23 @@ static const struct int offset; } -bootp_response_properties[] = -{ - { .name = "bootp-response", .offset = 0 }, - { .name = "dhcp-response", .offset = 0 }, - { .name = "bootpreply-packet", .offset = 0x2a }, -}; +bootp_response_properties[] = + { + { .name = "bootp-response", .offset = 0}, + { .name = "dhcp-response", .offset = 0}, + { .name = "bootpreply-packet", .offset = 0x2a}, + }; -static grub_bootp_t -grub_getbootp_real ( void ) +static grub_bootp_t +grub_getbootp_real (void) { grub_bootp_t packet = grub_malloc (sizeof *packet); - char *bootp_response; + char *bootp_response; grub_ssize_t size; unsigned int i; - for ( i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) - if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, + for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) + if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, bootp_response_properties[i].name, &size) >= 0) break; @@ -111,8 +114,7 @@ grub_getbootp_real ( void ) bootp_response = grub_malloc (size); if (grub_ieee1275_get_property (grub_ieee1275_chosen, bootp_response_properties[i].name, - bootp_response , - size, 0) < 0) + bootp_response, size, 0) < 0) return NULL; grub_memcpy (packet, bootp_response + bootp_response_properties[i].offset, sizeof (*packet)); @@ -120,52 +122,55 @@ grub_getbootp_real ( void ) return packet; } -static -void grub_ofnet_findcards (void) +static void +grub_ofnet_findcards (void) { struct grub_net_card *card; grub_ieee1275_phandle_t devhandle; - grub_net_link_level_address_t lla; + grub_net_link_level_address_t lla; int i = 0; auto int search_net_devices (struct grub_ieee1275_devalias *alias); int search_net_devices (struct grub_ieee1275_devalias *alias) - { - if ( !grub_strcmp (alias->type,"network") ) - { - - card = grub_malloc (sizeof (struct grub_net_card)); - struct grub_ofnetcard_data *ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); - ofdata->path = grub_strdup (alias->path); - - grub_ieee1275_finddevice (ofdata->path, &devhandle); - - if (grub_ieee1275_get_integer_property - (devhandle, "max-frame-size", &(ofdata->mtu), sizeof (ofdata->mtu), 0)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve mtu size."); + { + if (!grub_strcmp (alias->type, "network")) + { - if (grub_ieee1275_get_property (devhandle, "mac-address", &(lla.mac), 6, 0)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); - - lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - card->default_address = lla; + card = grub_malloc (sizeof (struct grub_net_card)); + struct grub_ofnetcard_data *ofdata = + grub_malloc (sizeof (struct grub_ofnetcard_data)); + ofdata->path = grub_strdup (alias->path); - card->driver = NULL; - card->data = ofdata; + grub_ieee1275_finddevice (ofdata->path, &devhandle); + + if (grub_ieee1275_get_integer_property + (devhandle, "max-frame-size", &(ofdata->mtu), + sizeof (ofdata->mtu), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve mtu size."); + + if (grub_ieee1275_get_property + (devhandle, "mac-address", &(lla.mac), 6, 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); + + lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + card->default_address = lla; + + card->driver = NULL; + card->data = ofdata; card->flags = 0; - card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name); - grub_net_card_register (card); + card->name = grub_xasprintf ("eth%d", i++); + grub_net_card_register (card); return 0; - } - return 0; + } + return 0; } /* Look at all nodes for devices of the type network. */ grub_ieee1275_devices_iterate (search_net_devices); } -static -void grub_ofnet_probecards (void) +static void +grub_ofnet_probecards (void) { struct grub_net_card *card; struct grub_net_card_driver *driver; @@ -175,19 +180,21 @@ void grub_ofnet_probecards (void) grub_net_network_level_netaddress_t net; bootp_pckt = grub_getbootp (); - /* Assign correspondent driver for each device. */ + /* Assign correspondent driver for each device. */ FOR_NET_CARDS (card) { FOR_NET_CARD_DRIVERS (driver) { - if (driver->init(card) == GRUB_ERR_NONE) + if (driver->init (card) == GRUB_ERR_NONE) { card->driver = driver; - if (bootp_pckt && grub_memcmp(bootp_pckt->chaddr,card->default_address.mac,6) == 0) + if (bootp_pckt + && grub_memcmp (bootp_pckt->chaddr, card->default_address.mac, 6) == 0) { addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bootp_pckt->yiaddr; - grub_net_add_addr ("bootp_cli_addr", card, addr, card->default_address, 0); + grub_net_add_addr ("bootp_cli_addr", card, addr, + card->default_address, 0); FOR_NET_NETWORK_LEVEL_INTERFACES (inter) if (grub_strcmp (inter->name, "bootp_cli_addr") == 0) break; @@ -197,30 +204,27 @@ void grub_ofnet_probecards (void) grub_net_add_route ("bootp-router", net, inter); } break; - } + } } } grub_free (bootp_pckt); - + } -GRUB_MOD_INIT (ofnet) +GRUB_MOD_INIT(ofnet) { struct grub_net_card *card; grub_getbootp = grub_getbootp_real; grub_net_card_driver_register (&ofdriver); - grub_ofnet_findcards (); - grub_ofnet_probecards (); - FOR_NET_CARDS (card) + grub_ofnet_findcards (); + grub_ofnet_probecards (); + FOR_NET_CARDS (card) if (card->driver == NULL) grub_net_card_unregister (card); } -GRUB_MOD_FINI (ofnet) +GRUB_MOD_FINI(ofnet) { grub_net_card_driver_unregister (&ofdriver); grub_getbootp = NULL; } - - - diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index c96a65602..d29193afe 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -8,25 +8,25 @@ #include #include -grub_err_t +grub_err_t send_ethernet_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, grub_net_link_level_address_t target_addr, grub_uint16_t ethertype) { - struct etherhdr *eth; + struct etherhdr *eth; - grub_netbuff_push (nb,sizeof(*eth)); - eth = (struct etherhdr *) nb->data; - grub_memcpy(eth->dst, target_addr.mac, 6); - grub_memcpy(eth->src, inf->hwaddress.mac, 6); + grub_netbuff_push (nb, sizeof (*eth)); + eth = (struct etherhdr *) nb->data; + grub_memcpy (eth->dst, target_addr.mac, 6); + grub_memcpy (eth->src, inf->hwaddress.mac, 6); eth->type = grub_cpu_to_be16 (ethertype); return inf->card->driver->send (inf->card, nb); } -grub_err_t +grub_err_t grub_net_recv_ethernet_packet (struct grub_net_buff *nb) { struct etherhdr *eth; @@ -34,32 +34,32 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) struct snaphdr *snaph; grub_uint16_t type; - eth = (struct etherhdr *) nb->data; + eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); grub_netbuff_pull (nb, sizeof (*eth)); - + if (type <= 1500) { llch = (struct llchdr *) nb->data; type = llch->dsap & LLCADDRMASK; if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3) - { - grub_netbuff_pull (nb,sizeof(*llch)); + { + grub_netbuff_pull (nb, sizeof (*llch)); snaph = (struct snaphdr *) nb->data; type = snaph->type; } } - /* ARP packet */ + /* ARP packet. */ if (type == GRUB_NET_ETHERTYPE_ARP) { grub_net_arp_receive (nb); grub_netbuff_free (nb); } - /* IP packet */ + /* IP packet. */ if (type == GRUB_NET_ETHERTYPE_IP) grub_net_recv_ip_packets (nb); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index d6684c29e..4adc2b028 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -8,54 +8,55 @@ #include grub_uint16_t -ipchksum(void *ipv, int len) +ipchksum (void *ipv, int len) { - grub_uint16_t *ip = (grub_uint16_t *)ipv; - grub_uint32_t sum = 0; + grub_uint16_t *ip = (grub_uint16_t *) ipv; + grub_uint32_t sum = 0; - len >>= 1; - while (len--) - { - sum += grub_be_to_cpu16 (*(ip++)); - if (sum > 0xFFFF) - sum -= 0xFFFF; - } + len >>= 1; + while (len--) + { + sum += grub_be_to_cpu16 (*(ip++)); + if (sum > 0xFFFF) + sum -= 0xFFFF; + } - return grub_cpu_to_be16 ((~sum) & 0x0000FFFF); + return grub_cpu_to_be16 ((~sum) & 0x0000FFFF); } grub_err_t grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, const grub_net_network_level_address_t *target, struct grub_net_buff *nb) -{ +{ struct iphdr *iph; - static int id = 0x2400; + static int id = 0x2400; grub_net_link_level_address_t ll_target_addr; grub_err_t err; - - grub_netbuff_push (nb, sizeof(*iph)); - iph = (struct iphdr *) nb->data; + + grub_netbuff_push (nb, sizeof (*iph)); + iph = (struct iphdr *) nb->data; iph->verhdrlen = ((4 << 4) | 5); iph->service = 0; - iph->len = grub_cpu_to_be16 (nb->tail - nb-> data); + iph->len = grub_cpu_to_be16 (nb->tail - nb->data); iph->ident = grub_cpu_to_be16 (++id); iph->frags = 0; iph->ttl = 0xff; iph->protocol = 0x11; iph->src = inf->address.ipv4; iph->dest = target->ipv4; - - iph->chksum = 0 ; - iph->chksum = ipchksum((void *)nb->data, sizeof(*iph)); - + + iph->chksum = 0; + iph->chksum = ipchksum ((void *) nb->data, sizeof (*iph)); + /* Determine link layer target address via ARP. */ err = grub_net_arp_resolve (inf, target, &ll_target_addr); if (err) return err; return send_ethernet_packet (inf, nb, ll_target_addr, GRUB_NET_ETHERTYPE_IP); } + /* static int ip_filter (struct grub_net_buff *nb) @@ -80,7 +81,7 @@ ip_filter (struct grub_net_buff *nb) return 1; } */ -grub_err_t +grub_err_t grub_net_recv_ip_packets (struct grub_net_buff *nb) { struct iphdr *iph = (struct iphdr *) nb->data; @@ -88,11 +89,11 @@ grub_net_recv_ip_packets (struct grub_net_buff *nb) switch (iph->protocol) { - case IP_UDP: - return grub_net_recv_udp_packet (nb); + case IP_UDP: + return grub_net_recv_udp_packet (nb); break; - default: - grub_netbuff_free (nb); + default: + grub_netbuff_free (nb); break; } diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index be9fc9de2..aae2f4d8f 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -22,73 +22,84 @@ #include -grub_err_t grub_netbuff_put (struct grub_net_buff *nb ,grub_size_t len) +grub_err_t +grub_netbuff_put (struct grub_net_buff *nb, grub_size_t len) { nb->tail += len; if (nb->tail > nb->end) return grub_error (GRUB_ERR_OUT_OF_RANGE, "put out of the packet range."); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_unput (struct grub_net_buff *nb ,grub_size_t len) +grub_err_t +grub_netbuff_unput (struct grub_net_buff *nb, grub_size_t len) { nb->tail -= len; if (nb->tail < nb->head) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "unput out of the packet range."); - return GRUB_ERR_NONE; + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "unput out of the packet range."); + return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_push (struct grub_net_buff *nb ,grub_size_t len) +grub_err_t +grub_netbuff_push (struct grub_net_buff *nb, grub_size_t len) { nb->data -= len; if (nb->data < nb->head) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range."); - return GRUB_ERR_NONE; + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "push out of the packet range."); + return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_pull (struct grub_net_buff *nb ,grub_size_t len) +grub_err_t +grub_netbuff_pull (struct grub_net_buff *nb, grub_size_t len) { nb->data += len; if (nb->data > nb->end) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "pull out of the packet range."); - return GRUB_ERR_NONE; + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "pull out of the packet range."); + return GRUB_ERR_NONE; } -grub_err_t grub_netbuff_reserve (struct grub_net_buff *nb ,grub_size_t len) +grub_err_t +grub_netbuff_reserve (struct grub_net_buff *nb, grub_size_t len) { nb->data += len; nb->tail += len; if ((nb->tail > nb->end) || (nb->data > nb->end)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "reserve out of the packet range."); - return GRUB_ERR_NONE; + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "reserve out of the packet range."); + return GRUB_ERR_NONE; } -struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len ) +struct grub_net_buff * +grub_netbuff_alloc (grub_size_t len) { struct grub_net_buff *nb; void *data; - if (len < NETBUFFMINLEN) + if (len < NETBUFFMINLEN) len = NETBUFFMINLEN; - - len = ALIGN_UP (len,NETBUFF_ALIGN); + + len = ALIGN_UP (len, NETBUFF_ALIGN); data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); if (!data) return NULL; - nb = (struct grub_net_buff *) ((grub_uint8_t *) data + len); + nb = (struct grub_net_buff *) ((grub_uint8_t *) data + len); nb->head = nb->data = nb->tail = data; - nb->end = (char *) nb; - return nb; + nb->end = (char *) nb; + return nb; } -grub_err_t grub_netbuff_free (struct grub_net_buff *nb) +grub_err_t +grub_netbuff_free (struct grub_net_buff *nb) { grub_free (nb->head); return 0; - } -grub_err_t grub_netbuff_clear (struct grub_net_buff *nb) +grub_err_t +grub_netbuff_clear (struct grub_net_buff *nb) { nb->data = nb->tail = nb->head; return 0; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 010a4a4bd..ac3b3e9db 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -11,15 +11,15 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_err_t +static grub_err_t tftp_open (struct grub_file *file, const char *filename) { - struct tftphdr *tftph; + struct tftphdr *tftph; char *rrq; int i; int rrqlen; int hdrlen; - char open_data[1500]; + char open_data[1500]; struct grub_net_buff nb; tftp_data_t data; grub_err_t err; @@ -27,47 +27,47 @@ tftp_open (struct grub_file *file, const char *filename) data = grub_malloc (sizeof *data); if (!data) return grub_errno; - + file->device->net->socket->data = (void *) data; nb.head = open_data; nb.end = open_data + sizeof (open_data); - grub_netbuff_clear (&nb); + grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb,1500); - grub_netbuff_push (&nb,sizeof (*tftph)); + grub_netbuff_reserve (&nb, 1500); + grub_netbuff_push (&nb, sizeof (*tftph)); + + tftph = (struct tftphdr *) nb.data; - tftph = (struct tftphdr *) nb.data; - rrq = (char *) tftph->u.rrq; rrqlen = 0; - + tftph->opcode = grub_cpu_to_be16 (TFTP_RRQ); grub_strcpy (rrq, filename); rrqlen += grub_strlen (filename) + 1; - rrq += grub_strlen (filename) + 1; - - grub_strcpy (rrq,"octet"); + rrq += grub_strlen (filename) + 1; + + grub_strcpy (rrq, "octet"); rrqlen += grub_strlen ("octet") + 1; - rrq += grub_strlen ("octet") + 1; + rrq += grub_strlen ("octet") + 1; - grub_strcpy (rrq,"blksize"); - rrqlen += grub_strlen("blksize") + 1; - rrq += grub_strlen ("blksize") + 1; + grub_strcpy (rrq, "blksize"); + rrqlen += grub_strlen ("blksize") + 1; + rrq += grub_strlen ("blksize") + 1; - grub_strcpy (rrq,"1024"); + grub_strcpy (rrq, "1024"); rrqlen += grub_strlen ("1024") + 1; - rrq += grub_strlen ("1024") + 1; - - grub_strcpy (rrq,"tsize"); - rrqlen += grub_strlen ("tsize") + 1; - rrq += grub_strlen ("tsize") + 1; + rrq += grub_strlen ("1024") + 1; - grub_strcpy (rrq,"0"); + grub_strcpy (rrq, "tsize"); + rrqlen += grub_strlen ("tsize") + 1; + rrq += grub_strlen ("tsize") + 1; + + grub_strcpy (rrq, "0"); rrqlen += grub_strlen ("0") + 1; rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; - - grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); + + grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); file->device->net->socket->out_port = TFTP_SERVER_PORT; @@ -76,7 +76,7 @@ tftp_open (struct grub_file *file, const char *filename) return err; /* Receive OACK packet. */ - for ( i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { grub_net_poll_cards (100); if (grub_errno) @@ -85,22 +85,22 @@ tftp_open (struct grub_file *file, const char *filename) break; /* Retry. */ /*err = grub_net_send_udp_packet (file->device->net->socket, &nb); - if (err) - return err;*/ + if (err) + return err; */ } if (file->device->net->socket->status == 0) - return grub_error (GRUB_ERR_TIMEOUT,"Time out opening tftp."); + return grub_error (GRUB_ERR_TIMEOUT, "Time out opening tftp."); file->size = data->file_size; return GRUB_ERR_NONE; } -static grub_err_t +static grub_err_t tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) { struct tftphdr *tftph; - char nbdata[128]; + char nbdata[128]; tftp_data_t data = sock->data; grub_err_t err; char *ptr; @@ -112,9 +112,9 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) tftph = (struct tftphdr *) nb->data; switch (grub_be_to_cpu16 (tftph->opcode)) - { + { case TFTP_OACK: - for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail; ) + for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) { if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) { @@ -125,13 +125,14 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) ptr++; ptr++; } - sock->status = 1; + sock->status = 1; data->block = 0; - grub_netbuff_clear(nb); - break; + grub_netbuff_clear (nb); + break; case TFTP_DATA: - grub_netbuff_pull (nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block)); - + grub_netbuff_pull (nb, sizeof (tftph->opcode) + + sizeof (tftph->u.data.block)); + if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) { data->block++; @@ -140,22 +141,23 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) sock->status = 2; /* Prevent garbage in broken cards. */ if (size > 1024) - grub_netbuff_unput (nb, size - 1024); + grub_netbuff_unput (nb, size - 1024); } else - grub_netbuff_clear(nb); - - break; + grub_netbuff_clear (nb); + + break; case TFTP_ERROR: grub_netbuff_clear (nb); - return grub_error (GRUB_ERR_IO, (char *)tftph->u.err.errmsg); - break; - } + return grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg); + break; + } grub_netbuff_clear (&nb_ack); - grub_netbuff_reserve (&nb_ack,128); - grub_netbuff_push (&nb_ack,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block)); + grub_netbuff_reserve (&nb_ack, 128); + grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) + + sizeof (tftph->u.ack.block)); - tftph = (struct tftphdr *) nb_ack.data; + tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); tftph->u.ack.block = grub_cpu_to_be16 (data->block); @@ -163,7 +165,7 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) return err; } -static grub_err_t +static grub_err_t tftp_close (struct grub_file *file __attribute__ ((unused))) { grub_free (file->device->net->socket->data); @@ -171,19 +173,19 @@ tftp_close (struct grub_file *file __attribute__ ((unused))) } static struct grub_net_app_protocol grub_tftp_protocol = -{ - .name = "tftp", - .open = tftp_open, - .read = tftp_receive, - .close = tftp_close -}; + { + .name = "tftp", + .open = tftp_open, + .read = tftp_receive, + .close = tftp_close + }; -GRUB_MOD_INIT (tftp) +GRUB_MOD_INIT(tftp) { grub_net_app_level_register (&grub_tftp_protocol); } -GRUB_MOD_FINI (tftp) +GRUB_MOD_FINI(tftp) { grub_net_app_level_unregister (&grub_tftp_protocol); } diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 0b19c3098..86220bf0f 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -5,24 +5,25 @@ #include grub_err_t -grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb) +grub_net_send_udp_packet (const grub_net_socket_t socket, + struct grub_net_buff *nb) { struct udphdr *udph; - grub_netbuff_push (nb,sizeof(*udph)); - - udph = (struct udphdr *) nb->data; + grub_netbuff_push (nb, sizeof (*udph)); + + udph = (struct udphdr *) nb->data; udph->src = grub_cpu_to_be16 (socket->in_port); udph->dst = grub_cpu_to_be16 (socket->out_port); /* No chechksum. */ - udph->chksum = 0; + udph->chksum = 0; udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - + return grub_net_send_ip_packet (socket->inf, &(socket->out_nla), nb); } -grub_err_t +grub_err_t grub_net_recv_udp_packet (struct grub_net_buff *nb) { struct udphdr *udph; @@ -30,24 +31,24 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) udph = (struct udphdr *) nb->data; grub_netbuff_pull (nb, sizeof (*udph)); - FOR_NET_SOCKETS(sock) - { - if (grub_be_to_cpu16 (udph->dst) == sock->in_port) - { - if (sock->status == 0) - sock->out_port = grub_be_to_cpu16 (udph->src); - - /* App protocol remove its own reader. */ - sock->app->read (sock,nb); - - /* If there is data, puts packet in socket list. */ - if ((nb->tail - nb->data) > 0) - grub_net_put_packet (&sock->packs, nb); - else - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - } - grub_netbuff_free (nb); + FOR_NET_SOCKETS (sock) + { + if (grub_be_to_cpu16 (udph->dst) == sock->in_port) + { + if (sock->status == 0) + sock->out_port = grub_be_to_cpu16 (udph->src); + + /* App protocol remove its own reader. */ + sock->app->read (sock, nb); + + /* If there is data, puts packet in socket list. */ + if ((nb->tail - nb->data) > 0) + grub_net_put_packet (&sock->packs, nb); + else + grub_netbuff_free (nb); + return GRUB_ERR_NONE; + } + } + grub_netbuff_free (nb); return GRUB_ERR_NONE; } From 338c7fab9be66bc5aa6cf093539a0aafa4010b83 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 11 Jun 2011 16:57:19 +0200 Subject: [PATCH 1064/1414] fix grub-mount buildability on GNU/kFreeBSD --- Makefile.util.def | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.util.def b/Makefile.util.def index cd37d0d65..313339adc 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -223,7 +223,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)' '-lfuse'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse'; condition = COND_GRUB_MOUNT; }; diff --git a/configure.ac b/configure.ac index d1eaa0c84..26af7e7c3 100644 --- a/configure.ac +++ b/configure.ac @@ -871,7 +871,7 @@ fi if test x"$grub_mount_excuse" = x ; then # Check for fuse headers. SAVED_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26" AC_CHECK_HEADERS([fuse/fuse.h], [], [grub_mount_excuse=["need FUSE headers"]]) CPPFLAGS="$SAVED_CPPFLAGS" From 1e9aef7d963e86016cbb0568c5f9d01eee31fd99 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 13 Jun 2011 17:35:50 +0100 Subject: [PATCH 1065/1414] * docs/man/grub-mklayout.h2m (DESCRIPTION): Add a reference to the input format. --- ChangeLog | 5 +++++ docs/man/grub-mklayout.h2m | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index fca980c1b..5ac0ffb5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-13 Colin Watson + + * docs/man/grub-mklayout.h2m (DESCRIPTION): Add a reference to the + input format. + 2011-05-29 Colin Watson * docs/grub.texi (Obtaining and Building GRUB): Substitute diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m index cda6f3676..1e43409c0 100644 --- a/docs/man/grub-mklayout.h2m +++ b/docs/man/grub-mklayout.h2m @@ -1,4 +1,10 @@ [NAME] grub-mklayout \- generate a GRUB keyboard layout file +[DESCRIPTION] +grub-mklayout processes a keyboard layout description in +.BR keymaps (5) +format into a format that can be used by GRUB's +.B keymap +command. [SEE ALSO] .BR grub-mkconfig (8) From e23bc603f8e799dd85839ffe928b9e41d9a09d83 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Wed, 15 Jun 2011 15:11:26 -0300 Subject: [PATCH 1066/1414] Prevent crash when detecting fs. --- grub-core/net/net.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 1232b3c74..380eec3b5 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -581,6 +581,16 @@ grub_net_open_real (const char *name) return NULL; } +static grub_err_t +grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)), + int (*hook) (const char *filename, + const struct grub_dirhook_info *info) __attribute__ ((unused))) +{ + if (!device->net) + return grub_error (GRUB_ERR_BAD_FS, "invalid extent"); + return GRUB_ERR_NONE; +} + static grub_err_t grub_net_fs_open (struct grub_file *file, const char *name) { @@ -1014,7 +1024,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), static struct grub_fs grub_net_fs = { .name = "netfs", - .dir = NULL, + .dir = grub_net_fs_dir, .open = grub_net_fs_open, .read = grub_net_fs_read, .close = grub_net_fs_close, From 881ac815d00ecf1aa9093b015edf8c2da334d191 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 16 Jun 2011 14:33:11 +0200 Subject: [PATCH 1067/1414] 2011-06-16 Robert Millan Detect `ataraid' devices on GNU/kFreeBSD. Fix for ATA devices using `ata' driver on kernel of FreeBSD 9. * util/deviceiter.c [__FreeBSD_kernel__] (get_ada_disk_name) (get_ataraid_disk_name): New functions. [__FreeBSD_kernel__] (grub_util_iterate_devices): Scan for ataraid (/dev/ar[0-9]+) and ada (/dev/ada[0-9]+) devices using get_ataraid_disk_name() and get_ada_disk_name(). --- ChangeLog | 11 +++++++++++ util/deviceiter.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5ac0ffb5c..043b858a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-06-16 Robert Millan + + Detect `ataraid' devices on GNU/kFreeBSD. Fix for ATA devices using + `ata' driver on kernel of FreeBSD 9. + + * util/deviceiter.c [__FreeBSD_kernel__] (get_ada_disk_name) + (get_ataraid_disk_name): New functions. + [__FreeBSD_kernel__] (grub_util_iterate_devices): Scan for ataraid + (/dev/ar[0-9]+) and ada (/dev/ada[0-9]+) devices using + get_ataraid_disk_name() and get_ada_disk_name(). + 2011-06-13 Colin Watson * docs/man/grub-mklayout.h2m (DESCRIPTION): Add a reference to the diff --git a/util/deviceiter.c b/util/deviceiter.c index 30c18beea..2a8acec0e 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -1,7 +1,7 @@ /* deviceiter.c - iterate over system devices */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,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 @@ -286,6 +286,20 @@ get_scsi_disk_name (char *name, int unit) #endif } +#ifdef __FreeBSD_kernel__ +static void +get_ada_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/ada%d", unit); +} + +static void +get_ataraid_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/ar%d", unit); +} +#endif + #ifdef __linux__ static void get_virtio_disk_name (char *name, int unit) @@ -620,6 +634,35 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), } } +#ifdef __FreeBSD_kernel__ + /* IDE disks using ATA Direct Access driver. */ + if (get_kfreebsd_version () >= 800000) + for (i = 0; i < 96; i++) + { + char name[16]; + + get_ada_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0)) + goto out; + } + } + + /* ATARAID disks. */ + for (i = 0; i < 8; i++) + { + char name[20]; + + get_ataraid_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0)) + goto out; + } + } +#endif + #ifdef __linux__ /* Virtio disks. */ for (i = 0; i < 26; i++) From d6d205568f4ea7e6a49cd2ca745a8584d3bbca5d Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Sat, 18 Jun 2011 20:18:25 -0300 Subject: [PATCH 1068/1414] Close cards before boot. --- grub-core/kern/ieee1275/init.c | 2 ++ grub-core/net/drivers/ieee1275/ofnet.c | 4 ++++ grub-core/net/net.c | 11 +++++++++++ include/grub/net.h | 1 + 4 files changed, 18 insertions(+) diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index ad34ea188..3c55096a4 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -264,6 +264,8 @@ grub_machine_init (void) void grub_machine_fini (void) { + if (grub_grubnet_fini) + grub_grubnet_fini (); grub_ofdisk_fini (); grub_console_fini (); } diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 751583e9d..9789f2261 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -225,6 +225,10 @@ GRUB_MOD_INIT(ofnet) GRUB_MOD_FINI(ofnet) { + struct grub_net_card *card; + FOR_NET_CARDS (card) + if (card->driver && !grub_strcmp (card->driver->name, "ofnet")) + card->driver->fini (card); grub_net_card_driver_unregister (&ofdriver); grub_getbootp = NULL; } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 380eec3b5..c7732ecbf 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1021,6 +1021,15 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), "unrecognised format specification %s", args[3]); } +static void +grub_grubnet_fini_real (void) +{ + struct grub_net_card *card; + FOR_NET_CARDS (card) + if (card->driver) + card->driver->fini (card); +} + static struct grub_fs grub_net_fs = { .name = "netfs", @@ -1060,6 +1069,7 @@ GRUB_MOD_INIT(net) grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; grub_file_net_seek = grub_net_seek_real; + grub_grubnet_fini = grub_grubnet_fini_real; } GRUB_MOD_FINI(net) @@ -1074,4 +1084,5 @@ GRUB_MOD_FINI(net) grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; grub_file_net_seek = NULL; + grub_grubnet_fini = NULL; } diff --git a/include/grub/net.h b/include/grub/net.h index f9745acec..006ec0686 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -239,6 +239,7 @@ typedef struct grub_net extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, grub_off_t offset); +void (*EXPORT_VAR (grub_grubnet_fini)) (void); struct grub_net_network_level_interface { From d855fbcf37fa97de08952aae80fc5bf704fdf149 Mon Sep 17 00:00:00 2001 From: "Manoel R. Abranches" Date: Sat, 18 Jun 2011 20:20:53 -0300 Subject: [PATCH 1069/1414] Add error verification in netbuff operations. --- grub-core/net/arp.c | 7 +++++-- grub-core/net/drivers/ieee1275/ofnet.c | 5 ++++- grub-core/net/ethernet.c | 11 ++++++++--- grub-core/net/ip.c | 5 ++++- grub-core/net/netbuff.c | 4 ++-- grub-core/net/tftp.c | 21 ++++++++++++--------- grub-core/net/udp.c | 4 +++- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 0644d3d2e..6fc7554cd 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -39,6 +39,7 @@ grub_net_arp_resolve (struct grub_net_network_level_interface *inf, struct arphdr *arp_header; grub_net_link_level_address_t target_hw_addr; char *aux, arp_data[128]; + grub_err_t err; int i; /* Check cache table. */ @@ -52,9 +53,11 @@ grub_net_arp_resolve (struct grub_net_network_level_interface *inf, nb.head = arp_data; nb.end = arp_data + sizeof (arp_data); grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb, 128); - grub_netbuff_push (&nb, sizeof (*arp_header) + 2 * (6 + 4)); + + if ((err = grub_netbuff_push (&nb, sizeof (*arp_header) + 2 * (6 + 4))) != GRUB_ERR_NONE) + return err; + arp_header = (struct arphdr *) nb.data; arp_header->hrd = grub_cpu_to_be16 (GRUB_NET_ARPHRD_ETHERNET); arp_header->pro = grub_cpu_to_be16 (GRUB_NET_ETHERTYPE_IP); diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 9789f2261..2c264edb1 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -228,7 +228,10 @@ GRUB_MOD_FINI(ofnet) struct grub_net_card *card; FOR_NET_CARDS (card) if (card->driver && !grub_strcmp (card->driver->name, "ofnet")) - card->driver->fini (card); + { + card->driver->fini (card); + card->driver = NULL; + } grub_net_card_driver_unregister (&ofdriver); grub_getbootp = NULL; } diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index d29193afe..d33a07010 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -15,8 +15,10 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, grub_uint16_t ethertype) { struct etherhdr *eth; + grub_err_t err; - grub_netbuff_push (nb, sizeof (*eth)); + if ((err = grub_netbuff_push (nb, sizeof (*eth))) != GRUB_ERR_NONE) + return err; eth = (struct etherhdr *) nb->data; grub_memcpy (eth->dst, target_addr.mac, 6); grub_memcpy (eth->src, inf->hwaddress.mac, 6); @@ -33,10 +35,12 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) struct llchdr *llch; struct snaphdr *snaph; grub_uint16_t type; + grub_err_t err; eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); - grub_netbuff_pull (nb, sizeof (*eth)); + if ((err = grub_netbuff_pull (nb, sizeof (*eth))) != GRUB_ERR_NONE) + return err; if (type <= 1500) { @@ -45,7 +49,8 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3) { - grub_netbuff_pull (nb, sizeof (*llch)); + if ((err = grub_netbuff_pull (nb, sizeof (*llch))) != GRUB_ERR_NONE) + return err; snaph = (struct snaphdr *) nb->data; type = snaph->type; } diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 4adc2b028..749b41d02 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -85,7 +85,10 @@ grub_err_t grub_net_recv_ip_packets (struct grub_net_buff *nb) { struct iphdr *iph = (struct iphdr *) nb->data; - grub_netbuff_pull (nb, sizeof (*iph)); + grub_err_t err; + + if ((err = grub_netbuff_pull (nb, sizeof (*iph))) != GRUB_ERR_NONE) + return err; switch (iph->protocol) { diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index aae2f4d8f..d20104ab0 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -95,12 +95,12 @@ grub_err_t grub_netbuff_free (struct grub_net_buff *nb) { grub_free (nb->head); - return 0; + return GRUB_ERR_NONE; } grub_err_t grub_netbuff_clear (struct grub_net_buff *nb) { nb->data = nb->tail = nb->head; - return 0; + return GRUB_ERR_NONE; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index ac3b3e9db..138020b08 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -34,7 +34,8 @@ tftp_open (struct grub_file *file, const char *filename) grub_netbuff_clear (&nb); grub_netbuff_reserve (&nb, 1500); - grub_netbuff_push (&nb, sizeof (*tftph)); + if ((err = grub_netbuff_push (&nb, sizeof (*tftph))) != GRUB_ERR_NONE) + return err; tftph = (struct tftphdr *) nb.data; @@ -67,8 +68,8 @@ tftp_open (struct grub_file *file, const char *filename) rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; - grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); - + if ((err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen))) != GRUB_ERR_NONE) + return err; file->device->net->socket->out_port = TFTP_SERVER_PORT; err = grub_net_send_udp_packet (file->device->net->socket, &nb); @@ -130,9 +131,9 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) grub_netbuff_clear (nb); break; case TFTP_DATA: - grub_netbuff_pull (nb, sizeof (tftph->opcode) + - sizeof (tftph->u.data.block)); - + if ((err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + + sizeof (tftph->u.data.block))) != GRUB_ERR_NONE) + return err; if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) { data->block++; @@ -141,7 +142,8 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) sock->status = 2; /* Prevent garbage in broken cards. */ if (size > 1024) - grub_netbuff_unput (nb, size - 1024); + if ((err = grub_netbuff_unput (nb, size - 1024)) != GRUB_ERR_NONE) + return err; } else grub_netbuff_clear (nb); @@ -154,8 +156,9 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) } grub_netbuff_clear (&nb_ack); grub_netbuff_reserve (&nb_ack, 128); - grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) - + sizeof (tftph->u.ack.block)); + if ((err = grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) + + sizeof (tftph->u.ack.block))) != GRUB_ERR_NONE) + return err; tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 86220bf0f..b070cbb64 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -9,8 +9,10 @@ grub_net_send_udp_packet (const grub_net_socket_t socket, struct grub_net_buff *nb) { struct udphdr *udph; + grub_err_t err; - grub_netbuff_push (nb, sizeof (*udph)); + if ((err = grub_netbuff_push (nb, sizeof (*udph))) != GRUB_ERR_NONE) + return err; udph = (struct udphdr *) nb->data; udph->src = grub_cpu_to_be16 (socket->in_port); From 77ba5392d0e482de3618c00129c7bc2a35691cce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 08:45:12 +0200 Subject: [PATCH 1070/1414] New testload grub-fstest command --- Makefile.util.def | 1 + util/grub-fstest.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile.util.def b/Makefile.util.def index 829b16fac..1fcd9465e 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -34,6 +34,7 @@ library = { common_nodist = grub_script.tab.h; common = grub-core/commands/blocklist.c; + common = grub-core/commands/testload.c; common = grub-core/commands/extcmd.c; common = grub-core/commands/ls.c; common = grub-core/disk/dmraid_nvidia.c; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index f253a96f6..c2c8b1148 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -61,7 +61,8 @@ enum { CMD_CMP, CMD_HEX, CMD_CRC, - CMD_BLOCKLIST + CMD_BLOCKLIST, + CMD_TESTLOAD }; #define BUF_SIZE 32256 @@ -359,6 +360,9 @@ fstest (int n, char **args) case CMD_BLOCKLIST: execute_command ("blocklist", n, args); grub_printf ("\n"); + case CMD_TESTLOAD: + execute_command ("testload", n, args); + grub_printf ("\n"); } for (i = 0; i < num_disks; i++) @@ -520,6 +524,11 @@ argp_parser (int key, char *arg, struct argp_state *state) cmd = CMD_BLOCKLIST; nparm = 1; } + else if (!grub_strcmp (arg, "testload")) + { + cmd = CMD_TESTLOAD; + nparm = 1; + } else { fprintf (stderr, _("Invalid command %s.\n"), arg); From 2df2e89fee627a098b0192a526a2b6999699211c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 09:39:12 +0200 Subject: [PATCH 1071/1414] Fixed a cache collision bug. Thanks guufy1 for bugreport and test --- grub-core/kern/disk.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 30bc604f0..f1456defd 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -544,6 +544,17 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, break; } + if (data) + { + grub_memcpy ((char *) buf + + (agglomerate << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS)), + data, GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); + grub_disk_cache_unlock (disk->dev->id, disk->id, + sector + (agglomerate + << GRUB_DISK_CACHE_BITS)); + } + if (agglomerate) { grub_disk_addr_t i; @@ -568,17 +579,12 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, buf = (char *) buf + (agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS)); } - + if (data) { - grub_memcpy (buf, data, - GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); sector += GRUB_DISK_CACHE_SIZE; buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); - grub_disk_cache_unlock (disk->dev->id, disk->id, - sector + (agglomerate - << GRUB_DISK_CACHE_BITS)); } } From 8a5d6919e169d5839c474a5c0e8d8ed6b492fef1 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 23 Jun 2011 18:08:53 +0200 Subject: [PATCH 1072/1414] Avoid NULL deref in grub_device_open. * grub-core/kern/device.c (grub_device_open): Don't dereference a NULL pointer upon failed grub_env_get. --- ChangeLog | 6 ++++++ grub-core/kern/device.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e3ed5d13a..a7f6ce738 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-23 Jim Meyering + + avoid NULL deref in grub_device_open + * grub-core/kern/device.c (grub_device_open): Don't dereference + a NULL pointer upon failed grub_env_get. + 2011-06-23 Vladimir Serbinenko Support non-512B sectors and agglomerate reads. diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 3db14f50e..50f49ae6b 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -35,7 +35,7 @@ grub_device_open (const char *name) if (! name) { name = grub_env_get ("root"); - if (*name == '\0') + if (name == NULL || *name == '\0') { grub_error (GRUB_ERR_BAD_DEVICE, "no device is set"); goto fail; From e2d1dba0ae8d87c9f9fc8ecbb4b10243507b2615 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 19:50:41 +0200 Subject: [PATCH 1073/1414] * grub-core/kern/emu/getroot.c (grub_guess_root_device): Don't accept /dev/root as a valid device. --- ChangeLog | 8 +++++++- grub-core/kern/emu/getroot.c | 6 ++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a7f6ce738..0ea09a0ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ +2011-06-23 Vladimir Serbinenko + + * grub-core/kern/emu/getroot.c (grub_guess_root_device): Don't accept + /dev/root as a valid device. + 2011-06-23 Jim Meyering - avoid NULL deref in grub_device_open + Avoid NULL deref in grub_device_open. + * grub-core/kern/device.c (grub_device_open): Don't dereference a NULL pointer upon failed grub_env_get. diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 6e49cc31b..db27abf74 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -616,13 +616,15 @@ grub_guess_root_device (const char *dir) if (os_dev) { - if (strncmp (os_dev, "/dev/dm-", sizeof ("/dev/dm-") - 1) != 0) + int dm = (strncmp (os_dev, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0); + int root = (strcmp (os_dev, "/dev/root") == 0); + if (!dm && !root) 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); + return grub_find_device (dm ? "/dev/mapper" : "/dev", dev); } if (stat (dir, &st) < 0) From a199a8cd1a5d01847e21bb40f21e044f4d728244 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 20:05:39 +0200 Subject: [PATCH 1074/1414] Fix spurious warning. * grub-core/partmap/acorn.c (grub_acorn_boot_block): Make a union. (acorn_partition_map_find): Use .bin member. --- ChangeLog | 7 +++++++ grub-core/partmap/acorn.c | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ea09a0ab..a455d9b6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-23 Vladimir Serbinenko + + Fix spurious warning. + + * grub-core/partmap/acorn.c (grub_acorn_boot_block): Make a union. + (acorn_partition_map_find): Use .bin member. + 2011-06-23 Vladimir Serbinenko * grub-core/kern/emu/getroot.c (grub_guess_root_device): Don't accept diff --git a/grub-core/partmap/acorn.c b/grub-core/partmap/acorn.c index 9a68ddd92..341b8ac5f 100644 --- a/grub-core/partmap/acorn.c +++ b/grub-core/partmap/acorn.c @@ -34,11 +34,18 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct grub_acorn_boot_block { - grub_uint8_t misc[0x1C0]; - struct grub_filecore_disc_record disc_record; - grub_uint8_t flags; - grub_uint16_t start_cylinder; - grub_uint8_t checksum; + union + { + struct + { + grub_uint8_t misc[0x1C0]; + struct grub_filecore_disc_record disc_record; + grub_uint8_t flags; + grub_uint16_t start_cylinder; + grub_uint8_t checksum; + } __attribute__ ((packed, aligned)); + grub_uint8_t bin[0x200]; + }; } __attribute__ ((packed, aligned)); struct linux_part @@ -71,7 +78,7 @@ acorn_partition_map_find (grub_disk_t disk, struct linux_part *m, goto fail; for (i = 0; i != 0x1ff; ++i) - checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i]; + checksum = ((checksum & 0xff) + (checksum >> 8) + boot.bin[i]); if ((grub_uint8_t) checksum != boot.checksum) goto fail; From e98c83e910e7fd3e39dd021213d111526e80775c Mon Sep 17 00:00:00 2001 From: David Volgyes Date: Thu, 23 Jun 2011 20:28:04 +0200 Subject: [PATCH 1075/1414] * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Avoid NULL-pointer dereference. --- ChangeLog | 5 +++++ grub-core/bus/usb/ohci.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index a455d9b6b..ad72c8da2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-23 David Volgyes + + * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Avoid NULL-pointer + dereference. + 2011-06-23 Vladimir Serbinenko Fix spurious warning. diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index df0d0f4af..7e8eaaac2 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -454,10 +454,12 @@ grub_ohci_pci_iter (grub_pci_device_t dev, fail: if (o) - grub_dma_free (o->td_chunk); - grub_dma_free (o->ed_bulk_chunk); - grub_dma_free (o->ed_ctrl_chunk); - grub_dma_free (o->hcca_chunk); + { + grub_dma_free (o->td_chunk); + grub_dma_free (o->ed_bulk_chunk); + grub_dma_free (o->ed_ctrl_chunk); + grub_dma_free (o->hcca_chunk); + } grub_free (o); return 0; From fbc626665f458d60cc3d19e1e8eedb68638cb4dc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 20:38:19 +0200 Subject: [PATCH 1076/1414] * grub-core/loader/i386/xnu.c (grub_cpu_xnu_fill_devprop): Don't attempt to continue if allocation is failed. Reported by: David Volgyes . --- ChangeLog | 7 +++++++ grub-core/loader/i386/xnu.c | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad72c8da2..66c55d101 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-23 Vladimir Serbinenko + + * grub-core/loader/i386/xnu.c (grub_cpu_xnu_fill_devprop): Don't attempt + to continue if allocation is failed. + + Reported by: David Volgyes . + 2011-06-23 David Volgyes * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Avoid NULL-pointer diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index b877b0ea5..6128ec384 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -452,11 +452,11 @@ grub_cpu_xnu_fill_devprop (void) } devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties"); - if (devprop) - { - devprop->data = grub_malloc (total_length); - devprop->datasize = total_length; - } + if (!devprop) + return grub_errno; + + devprop->data = grub_malloc (total_length); + devprop->datasize = total_length; ptr = devprop->data; head = ptr; From 1abe47dc9935106c0079d0e50388d2c6168864a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 20:55:36 +0200 Subject: [PATCH 1077/1414] * grub-core/lib/reed_solomon.c (rs_recover): Prevent memory leak. (main): Close file. --- ChangeLog | 5 +++++ grub-core/lib/reed_solomon.c | 25 +++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66c55d101..c267a8a0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-23 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (rs_recover): Prevent memory leak. + (main): Close file. + 2011-06-23 Vladimir Serbinenko * grub-core/loader/i386/xnu.c (grub_cpu_xnu_fill_devprop): Don't attempt diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index e500ba32d..8b5e8235a 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -265,6 +265,22 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) syndroms (m, s, rs, sy); + for (i = 0; i < (int) rs; i++) + if (sy[i] != 0) + break; + + /* No error detected. */ + if (i == (int) rs) + { +#ifndef STANDALONE + free (sigma); + free (errpot); + free (errpos); + free (sy); +#endif + return; + } + { gf_single_t *eq; @@ -275,14 +291,6 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) scratch += rs2 * (rs2 + 1) * sizeof (gf_single_t); #endif - for (i = 0; i < (int) rs; i++) - if (sy[i] != 0) - break; - - /* No error detected. */ - if (i == (int) rs) - return; - for (i = 0; i < (int) rs2; i++) for (j = 0; j < (int) rs2 + 1; j++) eq[i * (rs2 + 1) + j] = sy[i+j]; @@ -504,6 +512,7 @@ main (int argc, char **argv) rs = s / 3; buf = xmalloc (s + rs + SECTOR_SIZE); fread (buf, 1, s, in); + fclose (in); grub_reed_solomon_add_redundancy (buf, s, rs); From e061a1b537b1f8b719bfa69c49bdf39877fdf4d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 20:58:35 +0200 Subject: [PATCH 1078/1414] * grub-core/lib/reed_solomon.c (rs_recover) [STANDALONE]: Prevent memory leak. --- ChangeLog | 6 ++++++ grub-core/lib/reed_solomon.c | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index c267a8a0f..327b52afc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,13 @@ +2011-06-23 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (rs_recover) [STANDALONE]: + Prevent memory leak. + 2011-06-23 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (rs_recover): Prevent memory leak. (main): Close file. + Reported by: David Volgyes . 2011-06-23 Vladimir Serbinenko diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 8b5e8235a..365b76003 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -277,6 +277,11 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs) free (errpot); free (errpos); free (sy); +#else + scratch -= rs2 * sizeof (gf_single_t); + scratch -= rs2 * sizeof (gf_single_t); + scratch -= rs2 * sizeof (int); + scratch -= rs * sizeof (gf_single_t); #endif return; } From 13548d26e9492450da911aa5b7c5d9e6850cb327 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 21:06:50 +0200 Subject: [PATCH 1079/1414] * util/raid.c (grub_util_raid_getmembers): Close fd before returning. Reported by: David Volgyes . --- ChangeLog | 6 ++++++ util/raid.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 327b52afc..058116fbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-23 Vladimir Serbinenko + + * util/raid.c (grub_util_raid_getmembers): Close fd before returning. + + Reported by: David Volgyes . + 2011-06-23 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (rs_recover) [STANDALONE]: diff --git a/util/raid.c b/util/raid.c index a6aa5f95e..c1c32b959 100644 --- a/util/raid.c +++ b/util/raid.c @@ -80,6 +80,8 @@ grub_util_raid_getmembers (const char *name) devicelist[j] = NULL; + close (fd); + return devicelist; } From cad3237fb5ecf1a21f9e1bad957942a0cac8d6cc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 22:02:05 +0200 Subject: [PATCH 1080/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Close file after stat. Reported by: David Volgyes . --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 058116fbb..abe285ee9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-23 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Close + file after stat. + Reported by: David Volgyes . + 2011-06-23 Vladimir Serbinenko * util/raid.c (grub_util_raid_getmembers): Close fd before returning. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e53a39c39..f4af73858 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1866,7 +1866,12 @@ grub_util_biosdisk_is_floppy (grub_disk_t disk) /* Shouldn't happen either. */ if (fstat (fd, &st) < 0) - return 0; + { + close (fd); + return 0; + } + + close (fd); #if defined(__NetBSD__) if (major(st.st_rdev) == RAW_FLOPPY_MAJOR) From 03147f46671e2270ef4849a710b20572462844ac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 22:11:42 +0200 Subject: [PATCH 1081/1414] * util/grub-mkpasswd-pbkdf2.c (main): Don't double-close. Reported by: David Volgyes . --- ChangeLog | 5 +++++ util/grub-mkpasswd-pbkdf2.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index abe285ee9..59cb3ec57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-23 Vladimir Serbinenko + + * util/grub-mkpasswd-pbkdf2.c (main): Don't double-close. + Reported by: David Volgyes . + 2011-06-23 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Close diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index dc2afdb6e..709ba7da7 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -270,7 +270,6 @@ main (int argc, char *argv[]) free (bufhex); free (salthex); free (salt); - fclose (f); grub_util_error ("couldn't retrieve random data for salt"); } fclose (f); From fe12fd5b439956ab5354dde8699870cb0fd7c8bd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 23 Jun 2011 22:18:31 +0200 Subject: [PATCH 1082/1414] * util/ieee1275/ofpath.c (check_sas): Close fd. (main): Free of_path. Reported by: David Volgyes . --- ChangeLog | 6 ++++++ util/ieee1275/ofpath.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 59cb3ec57..062f66c00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-23 Vladimir Serbinenko + + * util/ieee1275/ofpath.c (check_sas): Close fd. + (main): Free of_path. + Reported by: David Volgyes . + 2011-06-23 Vladimir Serbinenko * util/grub-mkpasswd-pbkdf2.c (main): Don't double-close. diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 1a433345d..f72bea8a5 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -297,6 +297,7 @@ check_sas (char *sysfs_path, int *tgt) free (path); free (p); + close (fd); } static void @@ -419,6 +420,7 @@ int main(int argc, char **argv) of_path = grub_util_devname_to_ofpath (argv[1]); printf("%s\n", of_path); + free (of_path); return 0; } From c31dc5f5e4291e2aa7fb9fbf5ed88640fb05cc83 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Jun 2011 23:13:20 +0200 Subject: [PATCH 1083/1414] Add support for DRI and RSTn markers in JPEG files. * grub-core/video/readers/jpeg.c (JPEG_MARKER_DRI): New define. (JPEG_MARKER_RST0): Likewise. (JPEG_MARKER_RST1): Likewise. (JPEG_MARKER_RST2): Likewise. (JPEG_MARKER_RST3): Likewise. (JPEG_MARKER_RST4): Likewise. (JPEG_MARKER_RST5): Likewise. (JPEG_MARKER_RST6): Likewise. (JPEG_MARKER_RST7): Likewise. (grub_jpeg_data): New fields dri, r1, bitmap_ptr. (grub_jpeg_decode_dri): New function. (grub_jpeg_decode_sos): Move image data related part into grub_jpeg_decode_data function. (grub_jpeg_decode_data): New function. (grub_jpeg_reset): New function. (grub_jpeg_decode_jpeg): Handle new markers. --- ChangeLog | 21 +++++++++ grub-core/video/readers/jpeg.c | 78 ++++++++++++++++++++++++++++------ 2 files changed, 87 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 062f66c00..655cbe25e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2011-06-23 Szymon Janc + + Add support for DRI and RSTn markers in JPEG files. + + * grub-core/video/readers/jpeg.c (JPEG_MARKER_DRI): New define. + (JPEG_MARKER_RST0): Likewise. + (JPEG_MARKER_RST1): Likewise. + (JPEG_MARKER_RST2): Likewise. + (JPEG_MARKER_RST3): Likewise. + (JPEG_MARKER_RST4): Likewise. + (JPEG_MARKER_RST5): Likewise. + (JPEG_MARKER_RST6): Likewise. + (JPEG_MARKER_RST7): Likewise. + (grub_jpeg_data): New fields dri, r1, bitmap_ptr. + (grub_jpeg_decode_dri): New function. + (grub_jpeg_decode_sos): Move image data related part into + grub_jpeg_decode_data function. + (grub_jpeg_decode_data): New function. + (grub_jpeg_reset): New function. + (grub_jpeg_decode_jpeg): Handle new markers. + 2011-06-23 Vladimir Serbinenko * util/ieee1275/ofpath.c (check_sas): Close fd. diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c index 8cdb2f61d..d61c90ec9 100644 --- a/grub-core/video/readers/jpeg.c +++ b/grub-core/video/readers/jpeg.c @@ -39,6 +39,15 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define JPEG_MARKER_DQT 0xdb #define JPEG_MARKER_SOF0 0xc0 #define JPEG_MARKER_SOS 0xda +#define JPEG_MARKER_DRI 0xdd +#define JPEG_MARKER_RST0 0xd0 +#define JPEG_MARKER_RST1 0xd1 +#define JPEG_MARKER_RST2 0xd2 +#define JPEG_MARKER_RST3 0xd3 +#define JPEG_MARKER_RST4 0xd4 +#define JPEG_MARKER_RST5 0xd5 +#define JPEG_MARKER_RST6 0xd6 +#define JPEG_MARKER_RST7 0xd7 #define SHIFT_BITS 8 #define CONST(x) ((int) ((x) * (1L << SHIFT_BITS) + 0.5)) @@ -66,6 +75,7 @@ struct grub_jpeg_data { grub_file_t file; struct grub_video_bitmap **bitmap; + grub_uint8_t *bitmap_ptr; int image_width; int image_height; @@ -82,6 +92,8 @@ struct grub_jpeg_data jpeg_data_unit_t cbdu; int vs, hs; + int dri; + int r1; int dc_value[3]; @@ -315,6 +327,18 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) return grub_errno; } +static grub_err_t +grub_jpeg_decode_dri (struct grub_jpeg_data *data) +{ + if (grub_jpeg_get_word (data) != 4) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: DRI marker length must be 4"); + + data->dri = grub_jpeg_get_word (data); + + return grub_errno; +} + static void grub_jpeg_idct_transform (jpeg_data_unit_t du) { @@ -526,8 +550,7 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb) static grub_err_t grub_jpeg_decode_sos (struct grub_jpeg_data *data) { - int i, cc, r1, c1, nr1, nc1, vb, hb; - grub_uint8_t *ptr1; + int i, cc; grub_uint32_t data_offset; data_offset = data->file->offset; @@ -563,17 +586,25 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) GRUB_VIDEO_BLIT_FORMAT_RGB_888)) return grub_errno; - data->bit_mask = 0x0; + data->bitmap_ptr = (*data->bitmap)->data; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_jpeg_decode_data (struct grub_jpeg_data *data) +{ + int c1, vb, hb, nr1, nc1; + int rst = data->dri; vb = data->vs * 8; hb = data->hs * 8; nr1 = (data->image_height + vb - 1) / vb; nc1 = (data->image_width + hb - 1) / hb; - ptr1 = (*data->bitmap)->data; - for (r1 = 0; r1 < nr1; - r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3) - for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3) + for (; data->r1 < nr1 && (!data->dri || rst); + data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) + for (c1 = 0; c1 < nc1 && (!data->dri || rst); + c1++, rst--, data->bitmap_ptr += hb * 3) { int r2, c2, nr2, nc2; grub_uint8_t *ptr2; @@ -588,10 +619,10 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) if (grub_errno) return grub_errno; - nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb; + nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb; nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb; - ptr2 = ptr1; + ptr2 = data->bitmap_ptr; for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3) for (c2 = 0; c2 < nc2; c2++, ptr2 += 3) { @@ -600,8 +631,7 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) i0 = (r2 / data->vs) * 8 + (c2 / data->hs); cr = data->crdu[i0]; cb = data->cbdu[i0]; - yy = - data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)]; + yy = data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)]; grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2); } @@ -610,6 +640,16 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) return grub_errno; } +static void +grub_jpeg_reset (struct grub_jpeg_data *data) +{ + data->bit_mask = 0x0; + + data->dc_value[0] = 0; + data->dc_value[1] = 0; + data->dc_value[2] = 0; +} + static grub_uint8_t grub_jpeg_get_marker (struct grub_jpeg_data *data) { @@ -655,8 +695,22 @@ grub_jpeg_decode_jpeg (struct grub_jpeg_data *data) case JPEG_MARKER_SOF0: /* Start Of Frame 0. */ grub_jpeg_decode_sof (data); break; + case JPEG_MARKER_DRI: /* Define Restart Interval. */ + grub_jpeg_decode_dri (data); + break; case JPEG_MARKER_SOS: /* Start Of Scan. */ - grub_jpeg_decode_sos (data); + if (grub_jpeg_decode_sos (data)) + break; + case JPEG_MARKER_RST0: /* Restart. */ + case JPEG_MARKER_RST1: + case JPEG_MARKER_RST2: + case JPEG_MARKER_RST3: + case JPEG_MARKER_RST4: + case JPEG_MARKER_RST5: + case JPEG_MARKER_RST6: + case JPEG_MARKER_RST7: + grub_jpeg_decode_data (data); + grub_jpeg_reset (data); break; case JPEG_MARKER_EOI: /* End Of Image. */ return grub_errno; From 005dd67cb68ece8ea1af43c5c11096d0d32614ea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 00:29:21 +0200 Subject: [PATCH 1084/1414] * grub-core/disk/ahci.c: Add missing license statements. * grub-core/fs/romfs.c: Likewise. * grub-core/lib/ia64/setjmp.S: Likewise. * grub-core/loader/i386/pc/freedos.c: Likewise. * grub-core/loader/ia64/efi/linux.c: Likewise. * grub-core/video/colors.c: Likewise. * include/grub/dl.h (GRUB_MOD_DEP): New macro. --- grub-core/disk/ahci.c | 2 ++ grub-core/fs/romfs.c | 2 ++ grub-core/lib/ia64/setjmp.S | 6 ++++++ grub-core/loader/i386/pc/freedos.c | 2 ++ grub-core/loader/ia64/efi/linux.c | 2 ++ grub-core/video/colors.c | 3 +++ include/grub/dl.h | 3 +++ 7 files changed, 20 insertions(+) diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 699df767c..0f355aa53 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -27,6 +27,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_ahci_cmd_head { grub_uint32_t config; diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 07632e635..58dc98f34 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -24,6 +24,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + struct grub_romfs_superblock { char magic[8]; diff --git a/grub-core/lib/ia64/setjmp.S b/grub-core/lib/ia64/setjmp.S index 0851885c5..190623d35 100644 --- a/grub-core/lib/ia64/setjmp.S +++ b/grub-core/lib/ia64/setjmp.S @@ -64,6 +64,12 @@ 0x1b0 f30 0x1c0 f31 */ +#include +#include + + .file "setjmp.S" + +GRUB_MOD_LICENSE ("GPLv2+") /* The following two entry points are the traditional entry points: */ diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c index 0ae815490..f796e08f4 100644 --- a/grub-core/loader/i386/pc/freedos.c +++ b/grub-core/loader/i386/pc/freedos.c @@ -33,6 +33,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; static struct grub_relocator *rel; static grub_uint32_t ebx = 0xffffffff; diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c index b018e4549..247eebae5 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -31,6 +31,8 @@ #include #include +GRUB_MOD_LICENSE ("GPLv3+"); + #define ALIGN_MIN (256*1024*1024) #define GRUB_ELF_SEARCH 1024 diff --git a/grub-core/video/colors.c b/grub-core/video/colors.c index 0637c5508..3119c0249 100644 --- a/grub-core/video/colors.c +++ b/grub-core/video/colors.c @@ -21,6 +21,9 @@ #include #include #include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); struct named_color { diff --git a/include/grub/dl.h b/include/grub/dl.h index 5ce01199c..75cd71758 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -90,6 +90,9 @@ static const char grub_module_name_##name[] \ #ifndef ASM_FILE #define GRUB_MOD_LICENSE(license) \ static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), used)) = "LICENSE=" license; +#define GRUB_MOD_DEP(name) \ +static const char grub_module_depend_##name[] \ + __attribute__((section(GRUB_MOD_SECTION(moddeps)), __used__)) = #name #else #define GRUB_MOD_LICENSE(license) \ .section GRUB_MOD_SECTION(module_license), "a"; \ From 290766fb770aa9d3ebd3ada989ae3b24d21a093a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 00:31:29 +0200 Subject: [PATCH 1085/1414] ZFS zlib support * grub-core/fs/zfs/zfs.c (zlib_decompress): New function. (decomp_table): Add zlib entries. (zio_read): USe 8 bits for compression function rather than 3. * include/grub/zfs/zio.h (zio_compress): Add zlib values. --- ChangeLog | 19 +++++++++++++++++++ grub-core/fs/zfs/zfs.c | 22 ++++++++++++++++++++-- include/grub/zfs/zio.h | 10 +++++++++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6535b6e17..954166148 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-06-24 Vladimir Serbinenko + + ZFS zlib support + + * grub-core/fs/zfs/zfs.c (zlib_decompress): New function. + (decomp_table): Add zlib entries. + (zio_read): USe 8 bits for compression function rather than 3. + * include/grub/zfs/zio.h (zio_compress): Add zlib values. + +2011-06-24 Vladimir Serbinenko + + * grub-core/disk/ahci.c: Add missing license statements. + * grub-core/fs/romfs.c: Likewise. + * grub-core/lib/ia64/setjmp.S: Likewise. + * grub-core/loader/i386/pc/freedos.c: Likewise. + * grub-core/loader/ia64/efi/linux.c: Likewise. + * grub-core/video/colors.c: Likewise. + * include/grub/dl.h (GRUB_MOD_DEP): New macro. + 2011-06-23 Vladimir Serbinenko AHCI support. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 8d86cf9e5..1eea13b26 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -51,6 +51,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -163,13 +164,30 @@ struct grub_zfs_data grub_disk_addr_t vdev_phys_sector; }; +static grub_err_t +zlib_decompress (void *s, void *d, + grub_size_t slen, grub_size_t dlen) +{ + if (grub_zlib_decompress (s, slen, 0, d, dlen) < 0) + return grub_errno; + return GRUB_ERR_NONE; +} + static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ {"off", NULL}, /* ZIO_COMPRESS_OFF */ {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */ {"empty", NULL}, /* ZIO_COMPRESS_EMPTY */ - {"gzip", NULL}, /* ZIO_COMPRESS_GZIP */ + {"gzip-1", zlib_decompress}, /* ZIO_COMPRESS_GZIP1 */ + {"gzip-2", zlib_decompress}, /* ZIO_COMPRESS_GZIP2 */ + {"gzip-3", zlib_decompress}, /* ZIO_COMPRESS_GZIP3 */ + {"gzip-4", zlib_decompress}, /* ZIO_COMPRESS_GZIP4 */ + {"gzip-5", zlib_decompress}, /* ZIO_COMPRESS_GZIP5 */ + {"gzip-6", zlib_decompress}, /* ZIO_COMPRESS_GZIP6 */ + {"gzip-7", zlib_decompress}, /* ZIO_COMPRESS_GZIP7 */ + {"gzip-8", zlib_decompress}, /* ZIO_COMPRESS_GZIP8 */ + {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ }; static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, @@ -527,7 +545,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, *buf = NULL; checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; - comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7; + comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; lsize = (BP_IS_HOLE(bp) ? 0 : (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) << SPA_MINBLOCKSHIFT)); diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 797d4f9b3..3dafb4028 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -77,7 +77,15 @@ enum zio_compress { ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_EMPTY, - ZIO_COMPRESS_GZIP, + ZIO_COMPRESS_GZIP1, + ZIO_COMPRESS_GZIP2, + ZIO_COMPRESS_GZIP3, + ZIO_COMPRESS_GZIP4, + ZIO_COMPRESS_GZIP5, + ZIO_COMPRESS_GZIP6, + ZIO_COMPRESS_GZIP7, + ZIO_COMPRESS_GZIP8, + ZIO_COMPRESS_GZIP9, ZIO_COMPRESS_FUNCTIONS }; From bc09e1a23804bd4132a51bca01851135d7307bff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 04:32:54 +0200 Subject: [PATCH 1086/1414] * grub-core/kern/emu/getroot.c (grub_guess_root_device): Revert to old method if mountinfo would return /dev/root and /dev/root doesn't exist. --- ChangeLog | 6 ++++++ grub-core/kern/emu/getroot.c | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 954166148..1b63af871 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-24 Vladimir Serbinenko + + * grub-core/kern/emu/getroot.c (grub_guess_root_device): Revert to + old method if mountinfo would return /dev/root and /dev/root doesn't + exist. + 2011-06-24 Vladimir Serbinenko ZFS zlib support diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index db27abf74..6d6c8ef8b 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -620,11 +620,13 @@ grub_guess_root_device (const char *dir) int root = (strcmp (os_dev, "/dev/root") == 0); if (!dm && !root) return os_dev; - if (stat (os_dev, &st) < 0) - grub_util_error ("cannot stat `%s'", os_dev); + if (stat (os_dev, &st) >= 0) + { + free (os_dev); + dev = st.st_rdev; + return grub_find_device (dm ? "/dev/mapper" : "/dev", dev); + } free (os_dev); - dev = st.st_rdev; - return grub_find_device (dm ? "/dev/mapper" : "/dev", dev); } if (stat (dir, &st) < 0) From 535c191059459b9212991f59aea494db1c1da767 Mon Sep 17 00:00:00 2001 From: Alexander Kurtz Date: Fri, 24 Jun 2011 12:38:24 +0200 Subject: [PATCH 1087/1414] * util/grub-mkconfig_lib.in: Add missing quotes. --- ChangeLog | 4 ++++ util/grub-mkconfig_lib.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1b63af871..d5c97b6e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-24 Alexander Kurtz + + * util/grub-mkconfig_lib.in: Add missing quotes. + 2011-06-24 Vladimir Serbinenko * grub-core/kern/emu/getroot.c (grub_guess_root_device): Revert to diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 2c5fd8c6f..759bcba1b 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -63,7 +63,7 @@ is_path_readable_by_grub () # ... or if we can't figure out the abstraction module, for example if # memberlist fails on an LVM volume group. - if ${grub_probe} -t abstraction $path > /dev/null 2>&1 ; then : ; else + if "${grub_probe}" -t abstraction "$path" > /dev/null 2>&1 ; then : ; else return 1 fi From 2a5e94d84abd9efad39e7eafe68fb766cea87314 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 12:41:05 +0200 Subject: [PATCH 1088/1414] * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load partmap before abstraction. --- ChangeLog | 5 +++++ util/grub-mkconfig_lib.in | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5c97b6e0..1e7a468ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-24 Vladimir Serbinenko + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load + partmap before abstraction. + 2011-06-24 Alexander Kurtz * util/grub-mkconfig_lib.in: Add missing quotes. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 759bcba1b..090fcf314 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -105,12 +105,6 @@ prepare_grub_to_access_device () { device="$1" - # Abstraction modules aren't auto-loaded. - abstraction="`"${grub_probe}" --device "${device}" --target=abstraction`" - for module in ${abstraction} ; do - echo "insmod ${module}" - done - partmap="`"${grub_probe}" --device "${device}" --target=partmap`" for module in ${partmap} ; do case "${module}" in @@ -121,6 +115,12 @@ prepare_grub_to_access_device () esac done + # Abstraction modules aren't auto-loaded. + abstraction="`"${grub_probe}" --device "${device}" --target=abstraction`" + for module in ${abstraction} ; do + echo "insmod ${module}" + done + fs="`"${grub_probe}" --device "${device}" --target=fs`" for module in ${fs} ; do echo "insmod ${module}" From 98e2f50661b63494a7d94d3ad04d31669468f9b4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 13:02:49 +0200 Subject: [PATCH 1089/1414] * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Skip . and .. --- ChangeLog | 4 ++++ grub-core/fs/iso9660.c | 11 ++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e7a468ec..d21fa1026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-24 Vladimir Serbinenko + + * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Skip . and .. + 2011-06-24 Vladimir Serbinenko * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 508cc5b71..5b53ca597 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -598,7 +598,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, return 0; } - while (offset < dir->size) + for (; offset < dir->size; offset += dirent.len) { if (grub_disk_read (dir->data->disk, (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) @@ -676,10 +676,9 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, if (filename) *filename = '\0'; - if (dirent.namelen == 1 && name[0] == 0) - filename = "."; - else if (dirent.namelen == 1 && name[0] == 1) - filename = ".."; + /* . and .. */ + if (dirent.namelen == 1 && (name[0] == 0 || name[0] == 1)) + continue; else filename = name; } @@ -712,8 +711,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, if (filename_alloc) grub_free (filename); } - - offset += dirent.len; } return 0; From 4388ca7224904dd35cafb7aa4a48fe60af1cdd4d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 13:43:10 +0200 Subject: [PATCH 1090/1414] * grub-core/commands/wildcard.c (match_files): Add a useful dprintf. (wildcard_expand): Don't stop on nonregexp parts after regexp ones since it truncates the output. Reported by: Ximin Luo. --- ChangeLog | 7 +++++++ grub-core/commands/wildcard.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d21fa1026..eaee6266a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-24 Vladimir Serbinenko + + * grub-core/commands/wildcard.c (match_files): Add a useful dprintf. + (wildcard_expand): Don't stop on nonregexp parts after regexp ones since + it truncates the output. + Reported by: Ximin Luo. + 2011-06-24 Vladimir Serbinenko * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Skip . and .. diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 32561abe6..45d819a3e 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -288,6 +288,8 @@ match_files (const char *prefix, const char *suffix, const char *end, if (regexec (regexp, name, 0, 0, 0)) return 0; + grub_dprintf ("expand", "matched\n"); + buffer = grub_xasprintf ("%s%s", dir, name); if (! buffer) return 1; @@ -423,8 +425,6 @@ wildcard_expand (const char *s, char ***strs) while (*start) { split_path (start, &noregexop, ®exop); - if (noregexop >= regexop) /* no more wildcards */ - break; if (make_regex (noregexop, regexop, ®exp)) goto fail; From 031f22a01f81f3b65bdc8bc8fde473a5f847752e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 18:26:20 +0200 Subject: [PATCH 1091/1414] * grub-core/disk/raid.c (insert_array): Ensure uniqueness of readable names. --- ChangeLog | 5 +++++ grub-core/disk/raid.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/ChangeLog b/ChangeLog index eaee6266a..d70c7c6c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-24 Vladimir Serbinenko + + * grub-core/disk/raid.c (insert_array): Ensure uniqueness of readable + names. + 2011-06-24 Vladimir Serbinenko * grub-core/commands/wildcard.c (match_files): Add a useful dprintf. diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index c6be3efde..7c7dbc3dc 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -679,6 +679,49 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, scanner_name); #endif + { + int max_used_number = 0, len, need_new_name = 0; + int add_us = 0; + len = grub_strlen (array->name); + if (len && grub_isdigit (array->name[len-1])) + add_us = 1; + for (p = array_list; p != NULL; p = p->next) + { + int cur_num; + char *num, *end; + if (grub_strncmp (p->name, array->name, len) != 0) + continue; + if (p->name[len] == 0) + { + need_new_name = 1; + continue; + } + if (add_us && p->name[len] != '_') + continue; + if (add_us) + num = p->name + len + 1; + else + num = p->name + len; + if (!grub_isdigit (num[0])) + continue; + cur_num = grub_strtoull (num, &end, 10); + if (end[0]) + continue; + if (cur_num > max_used_number) + max_used_number = cur_num; + } + if (need_new_name) + { + char *tmp; + tmp = grub_xasprintf ("%s%s%d", array->name, add_us ? "_" : "", + max_used_number + 1); + if (!tmp) + return grub_errno; + grub_free (array->name); + array->name = tmp; + } + } + /* Add our new array to the list. */ array->next = array_list; array_list = array; From 8b51fd98b90531c9a3407ee0d00c935171f58e92 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 24 Jun 2011 20:35:25 +0200 Subject: [PATCH 1092/1414] bootp support --- grub-core/net/arp.c | 8 + grub-core/net/drivers/emu/emunet.c | 6 +- grub-core/net/ethernet.c | 11 +- grub-core/net/ip.c | 69 +++++--- grub-core/net/net.c | 268 ++++++++++++++++++++++++++--- grub-core/net/tftp.c | 12 +- grub-core/net/udp.c | 10 +- include/grub/emu/export.h | 6 + include/grub/net.h | 38 ++-- include/grub/net/ethernet.h | 16 +- include/grub/net/netbuff.h | 2 +- include/grub/net/udp.h | 5 +- 12 files changed, 360 insertions(+), 91 deletions(-) create mode 100644 include/grub/emu/export.h diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 0644d3d2e..1dbd8a58f 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -41,6 +41,14 @@ grub_net_arp_resolve (struct grub_net_network_level_interface *inf, char *aux, arp_data[128]; int i; + if (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 + && proto_addr->ipv4 == 0xffffffff) + { + hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + grub_memset (hw_addr->mac, -1, 6); + return GRUB_ERR_NONE; + } + /* Check cache table. */ entry = arp_find_entry (proto_addr); if (entry) diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c index ee4ba4773..d1e49a2f4 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -13,8 +13,8 @@ static int fd; -static grub_err_t -send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), +static grub_err_t +send_card_buffer (const struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { ssize_t actual; @@ -27,7 +27,7 @@ send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), } static grub_ssize_t -get_card_packet (struct grub_net_card *dev __attribute__ ((unused)), +get_card_packet (const struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { ssize_t actual; diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index d29193afe..f1bc8c1d0 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -27,12 +27,14 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, } grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_buff *nb) +grub_net_recv_ethernet_packet (struct grub_net_buff * nb, + const struct grub_net_card * card) { struct etherhdr *eth; struct llchdr *llch; struct snaphdr *snaph; grub_uint16_t type; + grub_net_link_level_address_t hwaddress; eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); @@ -51,7 +53,10 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) } } - /* ARP packet. */ + hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); + + /* ARP packet. */ if (type == GRUB_NET_ETHERTYPE_ARP) { grub_net_arp_receive (nb); @@ -59,7 +64,7 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb) } /* IP packet. */ if (type == GRUB_NET_ETHERTYPE_IP) - grub_net_recv_ip_packets (nb); + grub_net_recv_ip_packets (nb, card, &hwaddress); return GRUB_ERR_NONE; } diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 4adc2b028..808532a4a 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -25,9 +25,9 @@ ipchksum (void *ipv, int len) } grub_err_t -grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - struct grub_net_buff *nb) +grub_net_send_ip_packet (struct grub_net_network_level_interface * inf, + const grub_net_network_level_address_t * target, + struct grub_net_buff * nb) { struct iphdr *iph; static int id = 0x2400; @@ -54,43 +54,58 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, err = grub_net_arp_resolve (inf, target, &ll_target_addr); if (err) return err; - return send_ethernet_packet (inf, nb, ll_target_addr, GRUB_NET_ETHERTYPE_IP); + return send_ethernet_packet (inf, nb, ll_target_addr, + GRUB_NET_ETHERTYPE_IP); } -/* -static int -ip_filter (struct grub_net_buff *nb) +grub_err_t +grub_net_recv_ip_packets (struct grub_net_buff * nb, + const struct grub_net_card * card, + const grub_net_link_level_address_t * hwaddress) { struct iphdr *iph = (struct iphdr *) nb->data; grub_err_t err; + struct grub_net_network_level_interface *inf; - if (nb->end - nb->data < (signed) sizeof (*iph)) - return 0; - - if (iph->protocol != 0x11 || - iph->dest != inf->address.ipv4) - return 0; - - grub_netbuff_pull (nb, sizeof (iph)); - err = grub_net_put_packet (&inf->nl_pending, nb); + err = grub_netbuff_pull (nb, sizeof (*iph)); if (err) + return err; + + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { + if (inf->card == card + && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 + && inf->address.ipv4 == iph->dest + && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) + break; + } + if (!inf) { - grub_print_error (); - return 0; + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + if (inf->card == card + && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC + && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) + break; + } + if (!inf) + { + if (iph->protocol == IP_UDP + && grub_net_hwaddr_cmp (&card->default_address, hwaddress) == 0) + { + struct udphdr *udph; + udph = (struct udphdr *) nb->data; + grub_netbuff_pull (nb, sizeof (*udph)); + if (grub_be_to_cpu16 (udph->dst) == 68) + grub_net_process_dhcp (nb, card); + } + grub_netbuff_free (nb); + return GRUB_ERR_NONE; } - return 1; -} -*/ -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb) -{ - struct iphdr *iph = (struct iphdr *) nb->data; - grub_netbuff_pull (nb, sizeof (*iph)); switch (iph->protocol) { case IP_UDP: - return grub_net_recv_udp_packet (nb); + return grub_net_recv_udp_packet (nb, inf); break; default: grub_netbuff_free (nb); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 1232b3c74..2da60256c 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -16,6 +16,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -54,8 +56,11 @@ static struct grub_fs grub_net_fs; static inline void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) { - grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); + *inter->prev = inter->next; + if (inter->next) + inter->next->prev = inter->prev; + inter->next = 0; + inter->prev = 0; } static inline void @@ -112,6 +117,8 @@ match_net (const grub_net_network_level_netaddress_t *net, return 0; switch (net->type) { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + return 0; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_int32_t mask = ((1 << net->ipv4.masksize) - 1) << (32 - net->ipv4.masksize); @@ -229,6 +236,9 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) { switch (target->type) { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + grub_strcpy (buf, "promisc"); + return; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); @@ -270,6 +280,23 @@ hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) grub_printf ("Unsupported hw address type %d\n", addr->type); } +int +grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, + const grub_net_link_level_address_t *b) +{ + if (a->type < b->type) + return -1; + if (a->type > b->type) + return +1; + switch (a->type) + { + case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: + return grub_memcmp (a->mac, b->mac, sizeof (a->mac)); + } + grub_printf ("Unsupported hw address type %d\n", a->type); + return 1; +} + /* FIXME: implement this. */ static char * hwaddr_set_env (struct grub_env_var *var __attribute__ ((unused)), @@ -307,12 +334,16 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa grub_register_variable_hook (name, 0, addr_set_env); } - grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces), - GRUB_AS_LIST (inter)); + inter->prev = &grub_net_network_level_interfaces; + inter->next = grub_net_network_level_interfaces; + if (inter->next) + inter->next->prev = &inter->next; + grub_net_network_level_interfaces = inter; } struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, struct grub_net_card *card, +grub_net_add_addr (const char *name, + const struct grub_net_card *card, grub_net_network_level_address_t addr, grub_net_link_level_address_t hwaddress, grub_net_interface_flags_t flags) @@ -488,6 +519,9 @@ print_net_address (const grub_net_network_level_netaddress_t *target) { switch (target->type) { + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + grub_printf ("promisc\n"); + break; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { grub_uint32_t n = grub_be_to_cpu32 (target->ipv4.base); @@ -546,6 +580,23 @@ grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +static grub_err_t +grub_cmd_listaddrs (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_net_network_level_interface *inf; + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { + char bufh[MAX_STR_HWADDR_LEN]; + char bufn[GRUB_NET_MAX_STR_ADDR_LEN]; + hwaddr_to_str (&inf->hwaddress, bufh); + grub_net_addr_to_str (&inf->address, bufn); + grub_printf ("%s %s %s\n", inf->name, bufh, bufn); + } + return GRUB_ERR_NONE; +} + grub_net_app_level_t grub_net_app_level_list; struct grub_net_socket *grub_net_sockets; @@ -649,22 +700,27 @@ grub_net_fs_close (grub_file_t file) static void receive_packets (struct grub_net_card *card) { - /* Maybe should be better have a fixed number of packets for each card - and just mark them as used and not used. */ - struct grub_net_buff *nb; - grub_ssize_t actual; - nb = grub_netbuff_alloc (1500); - if (!nb) + while (1) { - grub_print_error (); - return; - } + /* Maybe should be better have a fixed number of packets for each card + and just mark them as used and not used. */ + struct grub_net_buff *nb; + grub_ssize_t actual; + nb = grub_netbuff_alloc (1500); + if (!nb) + { + grub_print_error (); + return; + } - actual = card->driver->recv (card, nb); - if (actual < 0) - grub_netbuff_free (nb); - else - grub_net_recv_ethernet_packet (nb); + actual = card->driver->recv (card, nb); + if (actual < 0) + { + grub_netbuff_free (nb); + break; + } + grub_net_recv_ethernet_packet (nb, card); + } grub_print_error (); } @@ -828,9 +884,10 @@ parse_dhcp_vendor (const char *name, void *vend, int limit) #define OFFSET_OF(x, y) ((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)) struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, +grub_net_configure_by_dhcp_ack (const char *name, + const struct grub_net_card *card, grub_net_interface_flags_t flags, - struct grub_net_bootp_ack *bp, + const struct grub_net_bootp_packet *bp, grub_size_t size) { grub_net_network_level_address_t addr; @@ -889,6 +946,38 @@ grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, return inter; } +void +grub_net_process_dhcp (struct grub_net_buff *nb, + const struct grub_net_card *card) +{ + char *name; + struct grub_net_network_level_interface *inf; + + name = grub_xasprintf ("%s:dhcp", card->name); + if (!name) + { + grub_print_error (); + return; + } + grub_net_configure_by_dhcp_ack (name, card, + 0, (const struct grub_net_bootp_packet *) nb->data, + (nb->tail - nb->data)); + grub_free (name); + if (grub_errno) + grub_print_error (); + else + { + FOR_NET_NETWORK_LEVEL_INTERFACES(inf) + if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0 + && grub_memcmp (inf->name + grub_strlen (card->name), + ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0) + { + grub_net_network_level_interface_unregister (inf); + break; + } + } +} + static char hexdigit (grub_uint8_t val) { @@ -1011,6 +1100,131 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), "unrecognised format specification %s", args[3]); } +static grub_err_t +grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_card *card; + struct grub_net_network_level_interface *ifaces; + grub_size_t ncards = 0; + unsigned j = 0; + int interval; + grub_err_t err; + + FOR_NET_CARDS (card) + { + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; + ncards++; + } + + ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); + if (!ifaces) + return grub_errno; + + j = 0; + FOR_NET_CARDS (card) + { + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; + ifaces[j].card = card; + ifaces[j].next = &ifaces[j+1]; + if (j) + ifaces[j].prev = &ifaces[j-1].next; + ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); + if (!ifaces[j].name) + { + unsigned i; + for (i = 0; i < j; i++) + grub_free (ifaces[i].name); + grub_free (ifaces); + return grub_errno; + } + ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC; + grub_memcpy (&ifaces[j].hwaddress, &card->default_address, + sizeof (ifaces[j].hwaddress)); + j++; + } + ifaces[ncards - 1].next = grub_net_network_level_interfaces; + if (grub_net_network_level_interfaces) + grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next; + grub_net_network_level_interfaces = &ifaces[0]; + ifaces[0].prev = &grub_net_network_level_interfaces; + for (interval = 200; interval < 10000; interval *= 2) + { + int done = 0; + for (j = 0; j < ncards; j++) + { + struct grub_net_bootp_packet *pack; + struct grub_datetime date; + grub_int32_t t; + struct grub_net_buff *nb; + struct udphdr *udph; + grub_net_network_level_address_t target; + + if (!ifaces[j].prev) + continue; + nb = grub_netbuff_alloc (sizeof (*pack)); + if (!nb) + return grub_errno; + err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128); + if (err) + return err; + err = grub_netbuff_push (nb, sizeof (*pack) + 64); + if (err) + return err; + pack = (void *) nb->data; + done = 1; + grub_memset (pack, 0, sizeof (*pack) + 64); + pack->opcode = 1; + pack->hw_type = 1; + pack->hw_len = 6; + err = grub_get_datetime (&date); + if (err || !grub_datetime2unixtime (&date, &t)) + { + grub_errno = GRUB_ERR_NONE; + t = 0; + } + pack->ident = grub_cpu_to_be32 (t); + pack->seconds = 0;//grub_cpu_to_be16 (t); + + grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6); + + grub_netbuff_push (nb, sizeof (*udph)); + + udph = (struct udphdr *) nb->data; + udph->src = grub_cpu_to_be16 (68); + udph->dst = grub_cpu_to_be16 (67); + udph->chksum = 0; + udph->len = grub_cpu_to_be16 (nb->tail - nb->data); + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4 = 0xffffffff; + + err = grub_net_send_ip_packet (&ifaces[j], &target, nb); + if (err) + return err; + } + if (!done) + break; + grub_net_poll_cards (interval); + } + + err = GRUB_ERR_NONE; + for (j = 0; j < ncards; j++) + { + if (!ifaces[j].prev) + continue; + grub_error_push (); + grub_net_network_level_interface_unregister (&ifaces[j]); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't configure %s", + ifaces[j].card->name); + } + + return err; +} + + static struct grub_fs grub_net_fs = { .name = "netfs", @@ -1023,7 +1237,8 @@ static struct grub_fs grub_net_fs = .mtime = NULL, }; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp; +static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp, cmd_bootp; +static grub_command_t cmd_dhcp, cmd_lsaddr; GRUB_MOD_INIT(net) { @@ -1043,6 +1258,14 @@ GRUB_MOD_INIT(net) "", N_("list network routes")); cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards, "", N_("list network cards")); + cmd_lsaddr = grub_register_command ("net_ls_addr", grub_cmd_listaddrs, + "", N_("list network addresses")); + cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, + "[CARD]", + N_("perform a bootp autoconfiguration")); + cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, + "[CARD]", + N_("perform a bootp autoconfiguration")); cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, N_("VAR INTERFACE NUMBER DESCRIPTION"), N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); @@ -1060,6 +1283,7 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_delroute); grub_unregister_command (cmd_lsroutes); grub_unregister_command (cmd_lscards); + grub_unregister_command (cmd_lsaddr); grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index ac3b3e9db..545862092 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -24,7 +24,7 @@ tftp_open (struct grub_file *file, const char *filename) tftp_data_t data; grub_err_t err; - data = grub_malloc (sizeof *data); + data = grub_malloc (sizeof (*data)); if (!data) return grub_errno; @@ -86,7 +86,7 @@ tftp_open (struct grub_file *file, const char *filename) /* Retry. */ /*err = grub_net_send_udp_packet (file->device->net->socket, &nb); if (err) - return err; */ + return err; */ } if (file->device->net->socket->status == 0) @@ -154,8 +154,8 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) } grub_netbuff_clear (&nb_ack); grub_netbuff_reserve (&nb_ack, 128); - grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) - + sizeof (tftph->u.ack.block)); + grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) + + sizeof (tftph->u.ack.block)); tftph = (struct tftphdr *) nb_ack.data; tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); @@ -180,12 +180,12 @@ static struct grub_net_app_protocol grub_tftp_protocol = .close = tftp_close }; -GRUB_MOD_INIT(tftp) +GRUB_MOD_INIT (tftp) { grub_net_app_level_register (&grub_tftp_protocol); } -GRUB_MOD_FINI(tftp) +GRUB_MOD_FINI (tftp) { grub_net_app_level_unregister (&grub_tftp_protocol); } diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 86220bf0f..cc7534ea1 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -24,7 +24,8 @@ grub_net_send_udp_packet (const grub_net_socket_t socket, } grub_err_t -grub_net_recv_udp_packet (struct grub_net_buff *nb) +grub_net_recv_udp_packet (struct grub_net_buff * nb, + struct grub_net_network_level_interface * inf) { struct udphdr *udph; grub_net_socket_t sock; @@ -33,7 +34,8 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) FOR_NET_SOCKETS (sock) { - if (grub_be_to_cpu16 (udph->dst) == sock->in_port) + if (grub_be_to_cpu16 (udph->dst) == sock->in_port + && inf == sock->inf && sock->app) { if (sock->status == 0) sock->out_port = grub_be_to_cpu16 (udph->src); @@ -41,7 +43,7 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) /* App protocol remove its own reader. */ sock->app->read (sock, nb); - /* If there is data, puts packet in socket list. */ + /* If there is data, puts packet in socket list. */ if ((nb->tail - nb->data) > 0) grub_net_put_packet (&sock->packs, nb); else @@ -49,6 +51,8 @@ grub_net_recv_udp_packet (struct grub_net_buff *nb) return GRUB_ERR_NONE; } } + if (grub_be_to_cpu16 (udph->dst) == 68) + grub_net_process_dhcp (nb, inf->card); grub_netbuff_free (nb); return GRUB_ERR_NONE; } diff --git a/include/grub/emu/export.h b/include/grub/emu/export.h new file mode 100644 index 000000000..1e2f0432b --- /dev/null +++ b/include/grub/emu/export.h @@ -0,0 +1,6 @@ +void EXPORT_FUNC (open64) (void); +void EXPORT_FUNC (close) (void); +void EXPORT_FUNC (read) (void); +void EXPORT_FUNC (write) (void); +void EXPORT_FUNC (ioctl) (void); + diff --git a/include/grub/net.h b/include/grub/net.h index f9745acec..5d99cace3 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -62,8 +62,10 @@ struct grub_net_card_driver char *name; grub_err_t (*init) (struct grub_net_card *dev); grub_err_t (*fini) (struct grub_net_card *dev); - grub_err_t (*send) (struct grub_net_card *dev, struct grub_net_buff *buf); - grub_ssize_t (*recv) (struct grub_net_card *dev, struct grub_net_buff *buf); + grub_err_t (*send) (const struct grub_net_card *dev, + struct grub_net_buff *buf); + grub_ssize_t (*recv) (const struct grub_net_card *dev, + struct grub_net_buff *buf); }; extern struct grub_net_card_driver *grub_net_card_drivers; @@ -116,6 +118,7 @@ struct grub_net_network_level_interface; typedef enum grub_network_level_protocol_id { + GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC, GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 } grub_network_level_protocol_id_t; @@ -243,12 +246,13 @@ extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, gr struct grub_net_network_level_interface { struct grub_net_network_level_interface *next; + struct grub_net_network_level_interface **prev; char *name; - struct grub_net_card *card; + const struct grub_net_card *card; grub_net_network_level_address_t address; grub_net_link_level_address_t hwaddress; grub_net_interface_flags_t flags; - struct grub_net_bootp_ack *dhcp_ack; + struct grub_net_bootp_packet *dhcp_ack; grub_size_t dhcp_acklen; void *data; }; @@ -291,7 +295,8 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, } struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, struct grub_net_card *card, +grub_net_add_addr (const char *name, + const struct grub_net_card *card, grub_net_network_level_address_t addr, grub_net_link_level_address_t hwaddress, grub_net_interface_flags_t flags); @@ -369,7 +374,7 @@ grub_net_add_route_gw (const char *name, typedef grub_uint8_t grub_net_bootp_mac_addr_t[GRUB_NET_BOOTP_MAC_ADDR_LEN]; -struct grub_net_bootp_ack +struct grub_net_bootp_packet { grub_uint8_t opcode; grub_uint8_t hw_type; /* hardware type. */ @@ -391,11 +396,21 @@ struct grub_net_bootp_ack #define GRUB_NET_BOOTP_RFC1048_MAGIC 0x63825363L struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, +grub_net_configure_by_dhcp_ack (const char *name, + const struct grub_net_card *card, grub_net_interface_flags_t flags, - struct grub_net_bootp_ack *bp, + const struct grub_net_bootp_packet *bp, grub_size_t size); +void +grub_net_process_dhcp (struct grub_net_buff *nb, + const struct grub_net_card *card); + +int +grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, + const grub_net_link_level_address_t *b); + + /* Currently suppoerted adresses: IPv4: XXX.XXX.XXX.XXX @@ -420,8 +435,11 @@ typedef int grub_err_t grub_net_recv_link_layer (struct grub_net_network_level_interface *inf, grub_net_packet_handler_t handler); -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb); + +grub_err_t +grub_net_recv_ip_packets (struct grub_net_buff *nb, + const struct grub_net_card *card, + const grub_net_link_level_address_t *hwaddress); grub_err_t grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 7ff7a4562..a841dc12c 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -12,19 +12,6 @@ struct etherhdr grub_uint16_t type; } __attribute__ ((packed)); -#define PCP(x) x & 0xe000 -#define CFI(x) x & 0x1000 -#define VID(x) x & 0x0fff -#define PRINT_ETH_ADDR(name,addr) grub_printf("%s %x:%x:%x:%x:%x:%x\n",\ - name,\ - addr[0],\ - addr[1],\ - addr[2],\ - addr[3],\ - addr[4],\ - addr[5]\ - ) - struct llchdr { grub_uint8_t dsap; @@ -52,6 +39,7 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, grub_net_link_level_address_t target_addr, grub_uint16_t ethertype); grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_buff *nb); +grub_net_recv_ethernet_packet (struct grub_net_buff *nb, + const struct grub_net_card *card); #endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h index 8ce508ead..245e813c3 100644 --- a/include/grub/net/netbuff.h +++ b/include/grub/net/netbuff.h @@ -26,5 +26,5 @@ grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len ); grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff); -grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); + #endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index 86311ccf1..eacf3325c 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -14,8 +14,9 @@ struct udphdr grub_err_t grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb); -grub_err_t -grub_net_recv_udp_packet (struct grub_net_buff *nb); +grub_err_t +grub_net_recv_udp_packet (struct grub_net_buff *nb, + struct grub_net_network_level_interface *inf); #define FOR_NET_UDP_PACKETS(inf, var) FOR_PACKETS(inf->udp_pending, var) From 40ea05dee4d26693cb03e3d3157626b64f671da4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 24 Jun 2011 22:37:17 +0200 Subject: [PATCH 1093/1414] * grub-core/io/xzio.c: Fix code style issues --- ChangeLog | 4 ++++ grub-core/io/xzio.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f42719bc..286648a46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-24 Szymon Janc + + * grub-core/io/xzio.c: Fix code style issues + 2011-06-24 Vladimir Serbinenko 2011-06-24 Manoel Rebelo Abranches diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index 1f42cd242..1575ca236 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -48,7 +48,7 @@ static struct grub_fs grub_xzio_fs; static grub_size_t decode_vli (const grub_uint8_t buf[], grub_size_t size_max, - grub_uint64_t * num) + grub_uint64_t *num) { if (size_max == 0) return 0; @@ -71,7 +71,7 @@ decode_vli (const grub_uint8_t buf[], grub_size_t size_max, } static grub_ssize_t -read_vli (grub_file_t file, grub_uint64_t * num) +read_vli (grub_file_t file, grub_uint64_t *num) { grub_uint8_t buf[VLI_MAX_DIGITS]; grub_ssize_t read; @@ -92,6 +92,8 @@ static int test_header (grub_file_t file) { grub_xzio_t xzio = file->data; + enum xz_ret ret; + xzio->buf.in_size = grub_file_read (xzio->file, xzio->inbuf, STREAM_HEADER_SIZE); @@ -101,7 +103,7 @@ test_header (grub_file_t file) return 0; } - enum xz_ret ret = xz_dec_run (xzio->dec, &xzio->buf); + ret = xz_dec_run (xzio->dec, &xzio->buf); if (ret == XZ_FORMAT_ERROR) { @@ -132,8 +134,8 @@ test_footer (grub_file_t file) grub_uint64_t records; grub_file_seek (xzio->file, xzio->file->size - FOOTER_MAGIC_SIZE); - if (grub_file_read (xzio->file, footer, FOOTER_MAGIC_SIZE) != - FOOTER_MAGIC_SIZE + if (grub_file_read (xzio->file, footer, FOOTER_MAGIC_SIZE) + != FOOTER_MAGIC_SIZE || grub_memcmp (footer, FOOTER_MAGIC, FOOTER_MAGIC_SIZE) != 0) goto ERROR; @@ -150,8 +152,8 @@ test_footer (grub_file_t file) xzio->file->size - XZ_STREAM_FOOTER_SIZE - backsize); /* Test index marker. */ - if (grub_file_read (xzio->file, &imarker, sizeof (imarker)) != - sizeof (imarker) && imarker != 0x00) + if (grub_file_read (xzio->file, &imarker, sizeof (imarker)) + != sizeof (imarker) && imarker != 0x00) goto ERROR; if (read_vli (xzio->file, &records) <= 0) From 77c0840ba67302031363479dfbf8bf44ef1ab6d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 25 Jun 2011 00:18:36 +0200 Subject: [PATCH 1094/1414] * grub-core/net/i386/pc/pxe.c (grub_pxe_recv): Fix declaration. (grub_pxe_send): Likewise. (GRUB_MOD_INIT): Fix types. --- ChangeLog | 6 ++++++ grub-core/net/i386/pc/pxe.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 286648a46..4cac3cd65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-25 Vladimir Serbinenko + + * grub-core/net/i386/pc/pxe.c (grub_pxe_recv): Fix declaration. + (grub_pxe_send): Likewise. + (GRUB_MOD_INIT): Fix types. + 2011-06-24 Szymon Janc * grub-core/io/xzio.c: Fix code style issues diff --git a/grub-core/net/i386/pc/pxe.c b/grub-core/net/i386/pc/pxe.c index 27c4af17f..a23104bad 100644 --- a/grub-core/net/i386/pc/pxe.c +++ b/grub-core/net/i386/pc/pxe.c @@ -305,14 +305,14 @@ static struct grub_fs grub_pxefs_fs = }; static grub_ssize_t -grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)), +grub_pxe_recv (const struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *buf __attribute__ ((unused))) { return 0; } static grub_err_t -grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), +grub_pxe_send (const struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *buf __attribute__ ((unused))) { return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "not implemented"); @@ -424,7 +424,7 @@ GRUB_MOD_INIT(pxe) { struct grub_pxe_bangpxe *pxenv; struct grub_pxenv_get_cached_info ci; - struct grub_net_bootp_ack *bp; + struct grub_net_bootp_packet *bp; char *buf; pxenv = grub_pxe_scan (); From 6295b32f79acb93df2208321eec491aa6b214fa0 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 25 Jun 2011 01:09:32 +0200 Subject: [PATCH 1095/1414] * grub-core/kern/main.c (grub_load_normal_mode): Correct the comment. --- ChangeLog | 4 ++++ grub-core/kern/main.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4cac3cd65..c639cb9de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-25 Patrick + + * grub-core/kern/main.c (grub_load_normal_mode): Correct the comment. + 2011-06-25 Vladimir Serbinenko * grub-core/net/i386/pc/pxe.c (grub_pxe_recv): Fix declaration. diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index cc9758988..447f0ae33 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -159,7 +159,7 @@ grub_load_normal_mode (void) /* Load the module. */ grub_dl_load ("normal"); - /* Something went wrong. Print errors here to let user know why we're entering rescue mode. */ + /* Print errors if any. */ grub_print_error (); grub_errno = 0; From cc4bfec8fac9a6fdea9ce38f5c7a92bc5579f22e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 04:18:45 +0200 Subject: [PATCH 1096/1414] Fix a memory leak --- grub-core/net/ethernet.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 863e659a8..175d0b65f 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -69,10 +69,14 @@ grub_net_recv_ethernet_packet (struct grub_net_buff * nb, { grub_net_arp_receive (nb); grub_netbuff_free (nb); + return GRUB_ERR_NONE; } /* IP packet. */ if (type == GRUB_NET_ETHERTYPE_IP) - grub_net_recv_ip_packets (nb, card, &hwaddress); - + { + grub_net_recv_ip_packets (nb, card, &hwaddress); + return GRUB_ERR_NONE; + } + grub_netbuff_free (nb); return GRUB_ERR_NONE; } From 8e60fc8f85b27fb513ef0b83efa07c531ec8e9a7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 04:19:12 +0200 Subject: [PATCH 1097/1414] Send network packets on PXE --- grub-core/Makefile.core.def | 2 +- grub-core/net/drivers/i386/pc/pxe.c | 304 ++++++++++++++++++ grub-core/net/i386/pc/pxe.c | 482 ---------------------------- 3 files changed, 305 insertions(+), 483 deletions(-) create mode 100644 grub-core/net/drivers/i386/pc/pxe.c delete mode 100644 grub-core/net/i386/pc/pxe.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 927718359..5c3ce99be 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1100,7 +1100,7 @@ module = { module = { name = pxe; - i386_pc = net/i386/pc/pxe.c; + i386_pc = net/drivers/i386/pc/pxe.c; enable = i386_pc; }; diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c new file mode 100644 index 000000000..7d6e3adca --- /dev/null +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -0,0 +1,304 @@ +/* pxe.c - Driver to provide access to the pxe filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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 + * 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 + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define SEGMENT(x) ((x) >> 4) +#define OFFSET(x) ((x) & 0xF) +#define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) +#define LINEAR(x) (void *) ((((x) >> 16) << 4) + ((x) & 0xFFFF)) + +struct grub_pxe_undi_open +{ + grub_uint16_t status; + grub_uint16_t open_flag; + grub_uint16_t pkt_filter; + grub_uint16_t mcast_count; + grub_uint8_t mcast[8][6]; +} __attribute__ ((packed)); + +struct grub_pxe_undi_isr +{ + grub_uint16_t status; + grub_uint16_t func_flag; + grub_uint16_t buffer_len; + grub_uint16_t frame_len; + grub_uint16_t frame_hdr_len; + grub_uint32_t buffer; + grub_uint8_t prot_type; + grub_uint8_t pkt_type; +} __attribute__ ((packed)); + +enum + { + GRUB_PXE_ISR_IN_START = 1, + GRUB_PXE_ISR_IN_PROCESS, + GRUB_PXE_ISR_IN_GET_NEXT + }; + +enum + { + GRUB_PXE_ISR_OUT_OURS = 0, + GRUB_PXE_ISR_OUT_NOT_OURS = 1 + }; + +enum + { + GRUB_PXE_ISR_OUT_DONE = 0, + GRUB_PXE_ISR_OUT_TRANSMIT = 2, + GRUB_PXE_ISR_OUT_RECEIVE = 3, + GRUB_PXE_ISR_OUT_BUSY = 4, + }; + +struct grub_pxe_undi_transmit +{ + grub_uint16_t status; + grub_uint8_t protocol; + grub_uint8_t xmitflag; + grub_uint32_t dest; + grub_uint32_t tbd; + grub_uint32_t reserved[2]; +} __attribute__ ((packed)); + +struct grub_pxe_undi_tbd +{ + grub_uint16_t len; + grub_uint32_t buf; + grub_uint16_t blk_count; + struct + { + grub_uint8_t ptr_type; + grub_uint8_t reserved; + grub_uint16_t len; + grub_uint32_t ptr; + } blocks[8]; +} __attribute__ ((packed)); + +struct grub_pxe_bangpxe *grub_pxe_pxenv; +static grub_uint32_t pxe_rm_entry = 0; + +static struct grub_pxe_bangpxe * +grub_pxe_scan (void) +{ + struct grub_bios_int_registers regs; + struct grub_pxenv *pxenv; + struct grub_pxe_bangpxe *bangpxe; + + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + + regs.ebx = 0; + regs.ecx = 0; + regs.eax = 0x5650; + regs.es = 0; + + grub_bios_interrupt (0x1a, ®s); + + if ((regs.eax & 0xffff) != 0x564e) + return NULL; + + pxenv = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff)); + if (grub_memcmp (pxenv->signature, GRUB_PXE_SIGNATURE, + sizeof (pxenv->signature)) + != 0) + return NULL; + + if (pxenv->version < 0x201) + return NULL; + + bangpxe = (void *) ((((pxenv->pxe_ptr & 0xffff0000) >> 16) << 4) + + (pxenv->pxe_ptr & 0xffff)); + + if (!bangpxe) + return NULL; + + if (grub_memcmp (bangpxe->signature, GRUB_PXE_BANGPXE_SIGNATURE, + sizeof (bangpxe->signature)) != 0) + return NULL; + + pxe_rm_entry = bangpxe->rm_entry; + + return bangpxe; +} + +static grub_ssize_t +grub_pxe_recv (const struct grub_net_card *dev __attribute__ ((unused)), + struct grub_net_buff *buf) +{ + struct grub_pxe_undi_isr *isr; + static int in_progress = 0; + char *ptr, *end; + int len; + + isr = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + if (!in_progress) + { + grub_memset (isr, 0, sizeof (*isr)); + isr->func_flag = GRUB_PXE_ISR_IN_START; + grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); + if (isr->status || isr->func_flag != GRUB_PXE_ISR_OUT_OURS) + return -1; + grub_memset (isr, 0, sizeof (*isr)); + isr->func_flag = GRUB_PXE_ISR_IN_PROCESS; + grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); + } + else + { + grub_memset (isr, 0, sizeof (*isr)); + isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; + grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); + } + + while (isr->func_flag != GRUB_PXE_ISR_OUT_RECEIVE) + { + if (isr->status || isr->func_flag == GRUB_PXE_ISR_OUT_DONE) + return -1; + grub_memset (isr, 0, sizeof (*isr)); + isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; + grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); + } + + grub_netbuff_put (buf, isr->frame_len); + ptr = buf->data; + end = ptr + isr->frame_len; + len = isr->frame_len; + grub_memcpy (ptr, LINEAR (isr->buffer), isr->buffer_len); + ptr += isr->buffer_len; + while (ptr < end) + { + grub_memset (isr, 0, sizeof (*isr)); + isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; + grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); + if (isr->status || isr->func_flag != GRUB_PXE_ISR_OUT_RECEIVE) + return -1; + + grub_memcpy (ptr, LINEAR (isr->buffer), isr->buffer_len); + ptr += isr->buffer_len; + } + + grub_printf ("<%d>\n", len); + return len; +} + +static grub_err_t +grub_pxe_send (const struct grub_net_card *dev __attribute__ ((unused)), + struct grub_net_buff *pack) +{ + struct grub_pxe_undi_transmit *trans; + struct grub_pxe_undi_tbd *tbd; + char *buf; + + trans = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (trans, 0, sizeof (*trans)); + tbd = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128); + grub_memset (tbd, 0, sizeof (*tbd)); + buf = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256); + grub_memcpy (buf, pack->data, pack->tail - pack->data); + + trans->tbd = SEGOFS ((grub_addr_t) tbd); + trans->protocol = 0; + tbd->len = pack->tail - pack->data; + tbd->buf = SEGOFS ((grub_addr_t) buf); + + grub_pxe_call (GRUB_PXENV_UNDI_TRANSMIT, trans, pxe_rm_entry); + if (trans->status) + return grub_error (GRUB_ERR_IO, "PXE send failed (status 0x%x)", + trans->status); + return 0; +} + +struct grub_net_card_driver grub_pxe_card_driver = +{ + .send = grub_pxe_send, + .recv = grub_pxe_recv +}; + +struct grub_net_card grub_pxe_card = +{ + .driver = &grub_pxe_card_driver, + .name = "pxe" +}; + +void +grub_pxe_unload (void) +{ + if (grub_pxe_pxenv) + { + grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, + (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, + pxe_rm_entry); + grub_net_card_unregister (&grub_pxe_card); + grub_pxe_pxenv = 0; + } +} + +GRUB_MOD_INIT(pxe) +{ + struct grub_pxe_bangpxe *pxenv; + struct grub_pxenv_get_cached_info ci; + struct grub_net_bootp_packet *bp; + struct grub_pxe_undi_open *ou; + + pxenv = grub_pxe_scan (); + if (! pxenv) + return; + + ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK; + ci.buffer = 0; + ci.buffer_size = 0; + grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry); + if (ci.status) + return; + + bp = LINEAR (ci.buffer); + + grub_memcpy (grub_pxe_card.default_address.mac, bp->mac_addr, + bp->hw_len < sizeof (grub_pxe_card.default_address.mac) + ? bp->hw_len : sizeof (grub_pxe_card.default_address.mac)); + grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + + ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (ou, 0, sizeof (ou)); + ou->pkt_filter = 4; + grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); + + if (ou->status) + return; + + grub_net_card_register (&grub_pxe_card); + grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, + bp, GRUB_PXE_BOOTP_SIZE); +} + +GRUB_MOD_FINI(pxe) +{ + grub_pxe_unload (); +} diff --git a/grub-core/net/i386/pc/pxe.c b/grub-core/net/i386/pc/pxe.c deleted file mode 100644 index 27c4af17f..000000000 --- a/grub-core/net/i386/pc/pxe.c +++ /dev/null @@ -1,482 +0,0 @@ -/* pxe.c - Driver to provide access to the pxe filesystem */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 -#include -#include -#include - -#include -#include -#include - -#define SEGMENT(x) ((x) >> 4) -#define OFFSET(x) ((x) & 0xF) -#define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) -#define LINEAR(x) (void *) (((x >> 16) << 4) + (x & 0xFFFF)) - -struct grub_pxe_bangpxe *grub_pxe_pxenv; -static grub_uint32_t grub_pxe_default_server_ip; -#if 0 -static grub_uint32_t grub_pxe_default_gateway_ip; -#endif -static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE; -static grub_uint32_t pxe_rm_entry = 0; -static grub_file_t curr_file = 0; - -struct grub_pxe_data -{ - grub_uint32_t packet_number; - grub_uint32_t block_size; - grub_uint32_t server_ip; - grub_uint32_t gateway_ip; - char filename[0]; -}; - - -static struct grub_pxe_bangpxe * -grub_pxe_scan (void) -{ - struct grub_bios_int_registers regs; - struct grub_pxenv *pxenv; - struct grub_pxe_bangpxe *bangpxe; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - regs.ebx = 0; - regs.ecx = 0; - regs.eax = 0x5650; - regs.es = 0; - - grub_bios_interrupt (0x1a, ®s); - - if ((regs.eax & 0xffff) != 0x564e) - return NULL; - - pxenv = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff)); - if (grub_memcmp (pxenv->signature, GRUB_PXE_SIGNATURE, - sizeof (pxenv->signature)) - != 0) - return NULL; - - if (pxenv->version < 0x201) - return NULL; - - bangpxe = (void *) ((((pxenv->pxe_ptr & 0xffff0000) >> 16) << 4) - + (pxenv->pxe_ptr & 0xffff)); - - if (!bangpxe) - return NULL; - - if (grub_memcmp (bangpxe->signature, GRUB_PXE_BANGPXE_SIGNATURE, - sizeof (bangpxe->signature)) != 0) - return NULL; - - pxe_rm_entry = bangpxe->rm_entry; - - return bangpxe; -} - -static grub_err_t -grub_pxefs_dir (grub_device_t device __attribute__ ((unused)), - const char *path __attribute__ ((unused)), - int (*hook) (const char *filename, - const struct grub_dirhook_info *info) - __attribute__ ((unused))) -{ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_pxefs_open (struct grub_file *file, const char *name) -{ - union - { - struct grub_pxenv_tftp_get_fsize c1; - struct grub_pxenv_tftp_open c2; - } c; - struct grub_pxe_data *data; - grub_file_t file_int, bufio; - - data = grub_zalloc (sizeof (*data) + grub_strlen (name) + 1); - if (!data) - return grub_errno; - - { - grub_net_network_level_address_t addr; - grub_net_network_level_address_t gateway; - struct grub_net_network_level_interface *interf; - grub_err_t err; - - if (grub_strncmp (file->device->net->name, - "pxe,", sizeof ("pxe,") - 1) == 0 - || grub_strncmp (file->device->net->name, - "pxe:", sizeof ("pxe:") - 1) == 0) - { - err = grub_net_resolve_address (file->device->net->name - + sizeof ("pxe,") - 1, &addr); - if (err) - { - grub_free (data); - return err; - } - } - else - { - addr.ipv4 = grub_pxe_default_server_ip; - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - } - err = grub_net_route_address (addr, &gateway, &interf); - if (err) - { - grub_free (data); - return err; - } - data->server_ip = addr.ipv4; - data->gateway_ip = gateway.ipv4; - } - - if (curr_file != 0) - { - grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2, pxe_rm_entry); - curr_file = 0; - } - - c.c1.server_ip = data->server_ip; - c.c1.gateway_ip = data->gateway_ip; - grub_strcpy ((char *)&c.c1.filename[0], name); - grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry); - if (c.c1.status) - { - grub_free (data); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); - } - - file->size = c.c1.file_size; - - c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); - c.c2.packet_size = grub_pxe_blksize; - grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2, pxe_rm_entry); - if (c.c2.status) - { - grub_free (data); - return grub_error (GRUB_ERR_BAD_FS, "open fails"); - } - - data->block_size = c.c2.packet_size; - grub_strcpy (data->filename, name); - - file_int = grub_malloc (sizeof (*file_int)); - if (! file_int) - { - grub_free (data); - return grub_errno; - } - - file->data = data; - file->not_easily_seekable = 1; - grub_memcpy (file_int, file, sizeof (struct grub_file)); - curr_file = file_int; - - bufio = grub_bufio_open (file_int, data->block_size); - if (! bufio) - { - grub_free (file_int); - grub_free (data); - return grub_errno; - } - - grub_memcpy (file, bufio, sizeof (struct grub_file)); - - return GRUB_ERR_NONE; -} - -static grub_ssize_t -grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_pxenv_tftp_read c; - struct grub_pxe_data *data; - grub_uint32_t pn; - grub_uint64_t r; - - data = file->data; - - pn = grub_divmod64 (file->offset, data->block_size, &r); - if (r) - { - grub_error (GRUB_ERR_BAD_FS, - "read access must be aligned to packet size"); - return -1; - } - - if ((curr_file != file) || (data->packet_number > pn)) - { - struct grub_pxenv_tftp_open o; - - if (curr_file != 0) - grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o, pxe_rm_entry); - - o.server_ip = data->server_ip; - o.gateway_ip = data->gateway_ip; - grub_strcpy ((char *)&o.filename[0], data->filename); - o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); - o.packet_size = data->block_size; - grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o, pxe_rm_entry); - if (o.status) - { - grub_error (GRUB_ERR_BAD_FS, "open fails"); - return -1; - } - data->block_size = o.packet_size; - data->packet_number = 0; - curr_file = file; - } - - c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - while (pn >= data->packet_number) - { - c.buffer_size = data->block_size; - grub_pxe_call (GRUB_PXENV_TFTP_READ, &c, pxe_rm_entry); - if (c.status) - { - grub_error (GRUB_ERR_BAD_FS, "read fails"); - return -1; - } - data->packet_number++; - } - - grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len); - - return len; -} - -static grub_err_t -grub_pxefs_close (grub_file_t file) -{ - struct grub_pxenv_tftp_close c; - - if (curr_file == file) - { - grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c, pxe_rm_entry); - curr_file = 0; - } - - grub_free (file->data); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_pxefs_label (grub_device_t device __attribute ((unused)), - char **label __attribute ((unused))) -{ - *label = 0; - return GRUB_ERR_NONE; -} - -static struct grub_fs grub_pxefs_fs = - { - .name = "pxe", - .dir = grub_pxefs_dir, - .open = grub_pxefs_open, - .read = grub_pxefs_read, - .close = grub_pxefs_close, - .label = grub_pxefs_label, - .next = 0 - }; - -static grub_ssize_t -grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)), - struct grub_net_buff *buf __attribute__ ((unused))) -{ - return 0; -} - -static grub_err_t -grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), - struct grub_net_buff *buf __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "not implemented"); -} - -struct grub_net_card_driver grub_pxe_card_driver = -{ - .send = grub_pxe_send, - .recv = grub_pxe_recv -}; - -struct grub_net_card grub_pxe_card = -{ - .driver = &grub_pxe_card_driver, - .name = "pxe" -}; - -void -grub_pxe_unload (void) -{ - if (grub_pxe_pxenv) - { - grub_fs_unregister (&grub_pxefs_fs); - grub_net_card_unregister (&grub_pxe_card); - grub_pxe_pxenv = 0; - } -} - -static void -set_ip_env (char *varname, grub_uint32_t ip) -{ - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - grub_net_network_level_address_t addr; - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = ip; - - grub_net_addr_to_str (&addr, buf); - grub_env_set (varname, buf); -} - -static char * -write_ip_env (grub_uint32_t *ip, const char *val) -{ - char *buf; - grub_err_t err; - grub_net_network_level_address_t addr; - - err = grub_net_resolve_address (val, &addr); - if (err) - return 0; - if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) - return NULL; - - /* Normalize the IP. */ - buf = grub_malloc (GRUB_NET_MAX_STR_ADDR_LEN); - if (!buf) - return 0; - grub_net_addr_to_str (&addr, buf); - - *ip = addr.ipv4; - - return buf; -} - -static char * -grub_env_write_pxe_default_server (struct grub_env_var *var - __attribute__ ((unused)), - const char *val) -{ - return write_ip_env (&grub_pxe_default_server_ip, val); -} - -#if 0 -static char * -grub_env_write_pxe_default_gateway (struct grub_env_var *var - __attribute__ ((unused)), - const char *val) -{ - return write_ip_env (&grub_pxe_default_gateway_ip, val); -} -#endif - -static char * -grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), - const char *val) -{ - unsigned size; - char *buf; - - size = grub_strtoul (val, 0, 0); - if (grub_errno) - return 0; - - if (size < GRUB_PXE_MIN_BLKSIZE) - size = GRUB_PXE_MIN_BLKSIZE; - else if (size > GRUB_PXE_MAX_BLKSIZE) - size = GRUB_PXE_MAX_BLKSIZE; - - buf = grub_xasprintf ("%d", size); - if (!buf) - return 0; - - grub_pxe_blksize = size; - - return buf; -} - -GRUB_MOD_INIT(pxe) -{ - struct grub_pxe_bangpxe *pxenv; - struct grub_pxenv_get_cached_info ci; - struct grub_net_bootp_ack *bp; - char *buf; - - pxenv = grub_pxe_scan (); - if (! pxenv) - return; - - ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK; - ci.buffer = 0; - ci.buffer_size = 0; - grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry); - if (ci.status) - return; - - bp = LINEAR (ci.buffer); - - grub_pxe_default_server_ip = bp->server_ip; - grub_pxe_pxenv = pxenv; - - set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); - grub_register_variable_hook ("pxe_default_server", 0, - grub_env_write_pxe_default_server); - -#if 0 - grub_pxe_default_gateway_ip = bp->gateway_ip; - - grub_register_variable_hook ("pxe_default_gateway", 0, - grub_env_write_pxe_default_gateway); -#endif - - buf = grub_xasprintf ("%d", grub_pxe_blksize); - if (buf) - grub_env_set ("pxe_blksize", buf); - grub_free (buf); - - grub_register_variable_hook ("pxe_blksize", 0, - grub_env_write_pxe_blocksize); - - grub_memcpy (grub_pxe_card.default_address.mac, bp->mac_addr, - bp->hw_len < sizeof (grub_pxe_card.default_address.mac) - ? bp->hw_len : sizeof (grub_pxe_card.default_address.mac)); - grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - grub_fs_register (&grub_pxefs_fs); - grub_net_card_register (&grub_pxe_card); - grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, - GRUB_NET_INTERFACE_PERMANENT - | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE - | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE, - bp, GRUB_PXE_BOOTP_SIZE); -} - -GRUB_MOD_FINI(pxe) -{ - grub_pxe_unload (); -} From bf651f790717fd5b73c80e6bedd9df66069c847e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 14:47:38 +0200 Subject: [PATCH 1098/1414] Fix incorrect memset --- grub-core/net/drivers/i386/pc/pxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 7d6e3adca..e667d42ef 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -286,7 +286,7 @@ GRUB_MOD_INIT(pxe) grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - grub_memset (ou, 0, sizeof (ou)); + grub_memset (ou, 0, sizeof (*ou)); ou->pkt_filter = 4; grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); From 80ca250565745aa1f587216ed8af6dc70e036e92 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 17:06:18 +0200 Subject: [PATCH 1099/1414] Add backward compatibiulity with old (pxe) syntax. Several cleanups --- grub-core/commands/probe.c | 2 +- grub-core/kern/device.c | 2 +- grub-core/net/drivers/i386/pc/pxe.c | 1 - grub-core/net/net.c | 114 ++++++++++++++++++++-------- include/grub/net.h | 6 +- 5 files changed, 87 insertions(+), 38 deletions(-) diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index 7ed2a4e51..ce1e9aac0 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -74,7 +74,7 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) { const char *val = "none"; if (dev->net) - val = dev->net->name; + val = dev->net->protocol->name; if (dev->disk) val = dev->disk->dev->name; if (state[0].set) diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 45bcd8210..c998d4d4b 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -79,7 +79,7 @@ grub_device_close (grub_device_t device) if (device->net) { - grub_free (device->net->name); + grub_free (device->net->server); grub_free (device->net); } diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index e667d42ef..084cdb876 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -204,7 +204,6 @@ grub_pxe_recv (const struct grub_net_card *dev __attribute__ ((unused)), ptr += isr->buffer_len; } - grub_printf ("<%d>\n", len); return len; } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 5c7d00991..2932986b2 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2010,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 @@ -32,6 +32,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); +static char *default_server; + struct grub_net_route { struct grub_net_route *next; @@ -603,26 +605,63 @@ struct grub_net_socket *grub_net_sockets; static grub_net_t grub_net_open_real (const char *name) { - const char *comma = grub_strchr (name, ','); grub_net_app_level_t proto; + const char *protname, *server; + grub_size_t protnamelen; + + if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) + { + protname = "tftp"; + protnamelen = sizeof ("tftp") - 1; + server = name + sizeof ("pxe:") - 1; + } + else if (grub_strcmp (name, "pxe") == 0) + { + protname = "tftp"; + protnamelen = sizeof ("tftp") - 1; + server = default_server; + } + else + { + const char *comma; + comma = grub_strchr (name, ','); + if (comma) + { + protnamelen = comma - name; + server = comma + 1; + } + else + { + protnamelen = grub_strlen (name); + server = default_server; + } + } + if (!server) + { + grub_error (GRUB_ERR_NET_BAD_ADDRESS, "no server"); + return NULL; + } - if (!comma) - comma = name + grub_strlen (name); FOR_NET_APP_LEVEL (proto) { - if (comma - name == (grub_ssize_t) grub_strlen (proto->name) - && grub_memcmp (proto->name, name, comma - name) == 0) + if (grub_memcmp (proto->name, protname, protnamelen) == 0 + && proto->name[protnamelen] == 0) { grub_net_t ret = grub_malloc (sizeof (*ret)); if (!ret) return NULL; ret->protocol = proto; - ret->name = grub_strdup (name); - if (!ret->name) + if (server) { - grub_free (ret); - return NULL; + ret->server = grub_strdup (server); + if (!ret->server) + { + grub_free (ret); + return NULL; + } } + else + ret->server = NULL; ret->fs = &grub_net_fs; return ret; } @@ -651,13 +690,8 @@ grub_net_fs_open (struct grub_file *file, const char *name) grub_net_network_level_address_t gateway; grub_net_socket_t socket; static int port = 25300; - const char *comma; - comma = grub_strchr (file->device->net->name, ','); - if (!comma) - return grub_error (GRUB_ERR_NET_BAD_ADDRESS, "no separator"); - - err = grub_net_resolve_address (comma + 1, &addr); + err = grub_net_resolve_address (file->device->net->server, &addr); if (err) return err; @@ -913,20 +947,19 @@ grub_net_configure_by_dhcp_ack (const char *name, hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; inter = grub_net_add_addr (name, card, addr, hwaddr, flags); - if (bp->gateway_ip != bp->server_ip) - { - grub_net_network_level_netaddress_t target; - grub_net_network_level_address_t gw; - char rname[grub_strlen (name) + sizeof ("_gw")]; + { + grub_net_network_level_netaddress_t target; + grub_net_network_level_address_t gw; + char rname[grub_strlen (name) + sizeof ("_gw")]; - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = bp->server_ip; - target.ipv4.masksize = 32; - gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - gw.ipv4 = bp->gateway_ip; - grub_snprintf (rname, sizeof (rname), "%s_gw", name); - grub_net_add_route_gw (rname, target, gw); - } + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = bp->server_ip; + target.ipv4.masksize = 32; + gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + gw.ipv4 = bp->gateway_ip; + grub_snprintf (rname, sizeof (rname), "%s_gw", name); + grub_net_add_route_gw (rname, target, gw); + } { grub_net_network_level_netaddress_t target; target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; @@ -938,9 +971,26 @@ grub_net_configure_by_dhcp_ack (const char *name, if (size > OFFSET_OF (boot_file, bp)) set_env_limn_ro (name, "boot_file", (char *) bp->boot_file, sizeof (bp->boot_file)); - if (size > OFFSET_OF (server_name, bp)) - set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, - sizeof (bp->server_name)); + if (size > OFFSET_OF (server_name, bp) + && bp->server_name[0]) + { + set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, + sizeof (bp->server_name)); + if (!default_server) + { + default_server = grub_strdup (bp->server_name); + grub_errno = GRUB_ERR_NONE; + } + } + if (!default_server) + { + default_server = grub_xasprintf ("%d.%d.%d.%d", + ((grub_uint8_t *) &bp->server_ip)[0], + ((grub_uint8_t *) &bp->server_ip)[1], + ((grub_uint8_t *) &bp->server_ip)[2], + ((grub_uint8_t *) &bp->server_ip)[3]); + grub_errno = GRUB_ERR_NONE; + } if (size > OFFSET_OF (vendor, bp)) parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp)); diff --git a/include/grub/net.h b/include/grub/net.h index 068ccec41..6595a8276 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -234,7 +234,7 @@ grub_net_socket_unregister (grub_net_socket_t sock) typedef struct grub_net { - char *name; + char *server; grub_net_app_level_t protocol; grub_net_socket_t socket; grub_fs_t fs; @@ -389,8 +389,8 @@ struct grub_net_bootp_packet grub_uint32_t server_ip; grub_uint32_t gateway_ip; grub_net_bootp_mac_addr_t mac_addr; - grub_uint8_t server_name[64]; - grub_uint8_t boot_file[128]; + char server_name[64]; + char boot_file[128]; grub_uint8_t vendor[0]; } __attribute__ ((packed)); From cbf597afb158a54ff1d35d4e21f0f6df3c1a01b9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 26 Jun 2011 17:17:41 +0200 Subject: [PATCH 1100/1414] * grub-core/commands/cmp.c (grub_cmd_cmp): Remove unnecessary NULL pointer checks before calling grub_free(). * grub-core/commands/wildcard.c (match_devices): Likewise. * grub-core/commands/wildcard.c (match_files): Likewise. * grub-core/fs/cpio.c (grub_cpio_dir): Likewise. * grub-core/fs/cpio.c (grub_cpio_open): Likewise. * grub-core/fs/udf.c (grub_udf_read_block): Likewise. * grub-core/fs/xfs.c (grub_xfs_read_block): Likewise. * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Likewise. * grub-core/normal/cmdline.c (grub_cmdline_get): Likewise. * grub-core/script/yylex.l (grub_lexer_unput): Likewise. * grub-core/video/readers/jpeg.c (grub_video_reader_jpeg): Likewise. * grub-core/video/readers/png.c (grub_png_output_byte): Likewise. --- ChangeLog | 16 ++++++++++++++++ grub-core/commands/cmp.c | 6 ++---- grub-core/commands/wildcard.c | 12 ++++-------- grub-core/fs/cpio.c | 13 ++++--------- grub-core/fs/udf.c | 3 +-- grub-core/fs/xfs.c | 3 +-- grub-core/loader/efi/chainloader.c | 3 +-- grub-core/normal/cmdline.c | 6 ++---- grub-core/script/yylex.l | 3 +-- grub-core/video/readers/jpeg.c | 3 +-- grub-core/video/readers/png.c | 3 +-- 11 files changed, 34 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index c639cb9de..17be445af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-06-26 Szymon Janc + + * grub-core/commands/cmp.c (grub_cmd_cmp): Remove unnecessary NULL + pointer checks before calling grub_free(). + * grub-core/commands/wildcard.c (match_devices): Likewise. + * grub-core/commands/wildcard.c (match_files): Likewise. + * grub-core/fs/cpio.c (grub_cpio_dir): Likewise. + * grub-core/fs/cpio.c (grub_cpio_open): Likewise. + * grub-core/fs/udf.c (grub_udf_read_block): Likewise. + * grub-core/fs/xfs.c (grub_xfs_read_block): Likewise. + * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Likewise. + * grub-core/normal/cmdline.c (grub_cmdline_get): Likewise. + * grub-core/script/yylex.l (grub_lexer_unput): Likewise. + * grub-core/video/readers/jpeg.c (grub_video_reader_jpeg): Likewise. + * grub-core/video/readers/png.c (grub_png_output_byte): Likewise. + 2011-06-25 Patrick * grub-core/kern/main.c (grub_load_normal_mode): Correct the comment. diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c index 0222927b6..526459311 100644 --- a/grub-core/commands/cmp.c +++ b/grub-core/commands/cmp.c @@ -94,10 +94,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), cleanup: - if (buf1) - grub_free (buf1); - if (buf2) - grub_free (buf2); + grub_free (buf1); + grub_free (buf2); if (file1) grub_file_close (file1); if (file2) diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 45d819a3e..d2f4347d5 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -255,8 +255,7 @@ match_devices (const regex_t *regexp, int noparts) for (i = 0; devs && devs[i]; i++) grub_free (devs[i]); - if (devs) - grub_free (devs); + grub_free (devs); return 0; } @@ -342,20 +341,17 @@ match_files (const char *prefix, const char *suffix, const char *end, fail: - if (dir) - grub_free (dir); + grub_free (dir); for (i = 0; files && files[i]; i++) grub_free (files[i]); - if (files) - grub_free (files); + grub_free (files); if (dev) grub_device_close (dev); - if (device_name) - grub_free (device_name); + grub_free (device_name); grub_error_pop (); return 0; diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 3a07873ec..0d84382ac 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -239,8 +239,7 @@ grub_cpio_dir (grub_device_t device, const char *path, info.mtimeset = 1; hook (name + len, &info); - if (prev) - grub_free (prev); + grub_free (prev); prev = name; } else @@ -251,11 +250,8 @@ grub_cpio_dir (grub_device_t device, const char *path, fail: - if (prev) - grub_free (prev); - - if (data) - grub_free (data); + grub_free (prev); + grub_free (data); grub_dl_unref (my_mod); @@ -326,8 +322,7 @@ grub_cpio_open (grub_file_t file, const char *name) fail: - if (data) - grub_free (data); + grub_free (data); grub_dl_unref (my_mod); diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index 48906f84f..e1f115015 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -546,8 +546,7 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) } fail: - if (buf) - grub_free (buf); + grub_free (buf); return 0; } diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 1e466465b..eb0783407 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -324,8 +324,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) } } - if (leaf) - grub_free (leaf); + grub_free (leaf); return GRUB_XFS_FSB_TO_BLOCK(node->data, ret); } diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index 5dd5adab2..3ecdca534 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -329,8 +329,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), if (file) grub_file_close (file); - if (file_path) - grub_free (file_path); + grub_free (file_path); if (address) efi_call_2 (b->free_pages, address, pages); diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index 09f2271ea..ea06b4cc7 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -500,8 +500,7 @@ grub_cmdline_get (const char *prompt) case GRUB_TERM_CTRL | 'k': if (lpos < llen) { - if (kill_buf) - grub_free (kill_buf); + grub_free (kill_buf); kill_buf = grub_malloc ((llen - lpos + 1) * sizeof (grub_uint32_t)); @@ -566,8 +565,7 @@ grub_cmdline_get (const char *prompt) { grub_size_t n = lpos; - if (kill_buf) - grub_free (kill_buf); + grub_free (kill_buf); kill_buf = grub_malloc (n + 1); if (grub_errno) diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 53ae4c54f..96f57dbe6 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -355,8 +355,7 @@ grub_lexer_unput (const char *text, yyscan_t yyscanner) { struct grub_lexer_param *lexerstate = yyget_extra (yyscanner)->lexerstate; - if (lexerstate->prefix) - grub_free (lexerstate->prefix); + grub_free (lexerstate->prefix); lexerstate->prefix = grub_strdup (text); if (! lexerstate->prefix) diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c index d61c90ec9..f2351dee9 100644 --- a/grub-core/video/readers/jpeg.c +++ b/grub-core/video/readers/jpeg.c @@ -750,8 +750,7 @@ grub_video_reader_jpeg (struct grub_video_bitmap **bitmap, grub_jpeg_decode_jpeg (data); for (i = 0; i < 4; i++) - if (data->huff_value[i]) - grub_free (data->huff_value[i]); + grub_free (data->huff_value[i]); grub_free (data); } diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c index 5728651e0..ae9879b16 100644 --- a/grub-core/video/readers/png.c +++ b/grub-core/video/readers/png.c @@ -625,8 +625,7 @@ grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n) } } - if (blank_line) - grub_free (blank_line); + grub_free (blank_line); data->cur_column = 0; data->first_line = 0; From a8fae12c5be48b4dafeec7c47d99132630be51cb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 17:18:53 +0200 Subject: [PATCH 1101/1414] minor cleanups --- grub-core/net/tftp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index d0ed7c43a..24f30eb7a 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -131,8 +131,9 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) grub_netbuff_clear (nb); break; case TFTP_DATA: - if ((err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + - sizeof (tftph->u.data.block))) != GRUB_ERR_NONE) + err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + + sizeof (tftph->u.data.block)); + if (err) return err; if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) { @@ -142,8 +143,11 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) sock->status = 2; /* Prevent garbage in broken cards. */ if (size > 1024) - if ((err = grub_netbuff_unput (nb, size - 1024)) != GRUB_ERR_NONE) - return err; + { + err = grub_netbuff_unput (nb, size - 1024); + if (err) + return err; + } } else grub_netbuff_clear (nb); From b1f9b7249afa234d64454b3db3c5a77a64db1e87 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 17:28:19 +0200 Subject: [PATCH 1102/1414] mknetdir support for ieee1275 --- util/grub-mknetdir.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index 61a7ec3ad..3b4f051c5 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -196,11 +196,17 @@ process_input_dir () config_opt="-c ${grubdir}/load.cfg " fi + prefix="/${subdir}/${platform}"; case "${platform}" in i386-pc) mkimage_target=i386-pc-pxe; netmodules="pxe"; - prefix="(pxe)/${subdir}/${platform}"; ext=0 ;; + sparc64-ieee1275) mkimage_target=sparc64-ieee1275-aout; + netmodules=""; + ext=img ;; + *-ieee1275) mkimage_target="${platform}"; + netmodules=""; + ext=elf ;; *) echo Unsupported platform ${platform}; exit 1;; esac From 2f804a7ff6cf37ac69584b88c63e6e5cc209da73 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 17:28:57 +0200 Subject: [PATCH 1103/1414] remove leftover directory From a27fe54f96b3dc19f3222b2872cd0e365059e1a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 17:51:46 +0200 Subject: [PATCH 1104/1414] missing part of previous commit --- util/grub-mknetdir.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index 3b4f051c5..a561004e6 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -45,6 +45,9 @@ debug=no debug_image= subdir=`echo /boot/grub | sed ${transform}` pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc +ppc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/powerpc-ieee1275 +sparc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/sparc64-ieee1275 +i386_ieee1275_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-ieee1275 # Usage: usage # Print the usage. @@ -223,6 +226,15 @@ if [ "${override_dir}" = "" ] ; then if test -e "${pc_dir}" ; then process_input_dir ${pc_dir} i386-pc fi + if test -e "${ppc_dir}" ; then + process_input_dir ${ppc_dir} powerpc-ieee1275 + fi + if test -e "${sparc_dir}" ; then + process_input_dir ${sparc_dir} sparc64-ieee1275 + fi + if test -e "${i386_ieee1275_dir}" ; then + process_input_dir ${sparc_dir} i386-ieee1275 + fi else source "${override_dir}"/modinfo.sh process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} From cf2bba0ef43bd2708d705ab3bf40fb841310b398 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 18:23:12 +0200 Subject: [PATCH 1105/1414] add missing quotes and fix variable name --- util/grub-mknetdir.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index a561004e6..fa0cafe54 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -224,16 +224,16 @@ EOF if [ "${override_dir}" = "" ] ; then if test -e "${pc_dir}" ; then - process_input_dir ${pc_dir} i386-pc + process_input_dir "${pc_dir}" i386-pc fi if test -e "${ppc_dir}" ; then - process_input_dir ${ppc_dir} powerpc-ieee1275 + process_input_dir "${ppc_dir}" powerpc-ieee1275 fi if test -e "${sparc_dir}" ; then process_input_dir ${sparc_dir} sparc64-ieee1275 fi if test -e "${i386_ieee1275_dir}" ; then - process_input_dir ${sparc_dir} i386-ieee1275 + process_input_dir "${i386_ieee1275_dir}" i386-ieee1275 fi else source "${override_dir}"/modinfo.sh From e552d93a8b28cac6fd1a1b4116980f80794a80ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 19:52:50 +0200 Subject: [PATCH 1106/1414] Add ofnet and tftp modules --- util/grub-mknetdir.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index fa0cafe54..a36e33cab 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -205,10 +205,10 @@ process_input_dir () netmodules="pxe"; ext=0 ;; sparc64-ieee1275) mkimage_target=sparc64-ieee1275-aout; - netmodules=""; + netmodules="ofnet"; ext=img ;; *-ieee1275) mkimage_target="${platform}"; - netmodules=""; + netmodules="ofnet"; ext=elf ;; *) echo Unsupported platform ${platform}; exit 1;; @@ -218,7 +218,7 @@ process_input_dir () source ${subdir}/grub.cfg EOF - $grub_mkimage ${config_opt} -d "${input_dir}" -O ${mkimage_target} --output=${grubdir}/core.$ext --prefix=$prefix $modules $netmodules || exit 1 + $grub_mkimage ${config_opt} -d "${input_dir}" -O ${mkimage_target} --output=${grubdir}/core.$ext --prefix=$prefix $modules $netmodules tftp || exit 1 echo "Netboot directory for ${platform} created. Configure your DHCP server to point to ${subdir}/${platform}/core.$ext" } From 9e322ce8de8526c2c752362749663e6c186f60e3 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Sun, 26 Jun 2011 21:48:52 +0200 Subject: [PATCH 1107/1414] Display the path of the file when file is not found * grub-core/fs/fat.c: Display the filename when file is not found. * grub-core/fs/fshelp.c: Likewise. * grub-core/fs/hfs.c: Likewise. * grub-core/fs/jfs.c: Likewise. * grub-core/fs/minix.c: Likewise. * grub-core/fs/ufs.c: Likewise. * grub-core/fs/btrfs.c: Likewise. * grub-core/commands/i386/pc/play.c: Likewise. --- ChangeLog | 13 +++++++++++++ grub-core/commands/i386/pc/play.c | 4 ++-- grub-core/fs/btrfs.c | 32 +++++++++++++++++++++++++++---- grub-core/fs/fat.c | 11 +++++++++-- grub-core/fs/fshelp.c | 2 +- grub-core/fs/hfs.c | 2 +- grub-core/fs/jfs.c | 2 +- grub-core/fs/minix.c | 2 +- grub-core/fs/ufs.c | 2 +- 9 files changed, 57 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17be445af..bd6e311bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-06-26 Yves Blusseau + + Display the path of the file when file is not found + + * grub-core/fs/fat.c: Display the filename when file is not found. + * grub-core/fs/fshelp.c: Likewise. + * grub-core/fs/hfs.c: Likewise. + * grub-core/fs/jfs.c: Likewise. + * grub-core/fs/minix.c: Likewise. + * grub-core/fs/ufs.c: Likewise. + * grub-core/fs/btrfs.c: Likewise. + * grub-core/commands/i386/pc/play.c: Likewise. + 2011-06-26 Szymon Janc * grub-core/commands/cmp.c (grub_cmd_cmp): Remove unnecessary NULL diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c index 57980eb92..1adf296ec 100644 --- a/grub-core/commands/i386/pc/play.c +++ b/grub-core/commands/i386/pc/play.c @@ -192,7 +192,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), file = grub_file_open (args[0]); if (! file) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", args[0]); if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo)) { @@ -227,7 +227,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), if (*end) /* Was not a number either, assume it was supposed to be a file name. */ - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", args[0]); grub_dprintf ("play","tempo = %d\n", tempo); diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 533529e3f..6470c9819 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1054,6 +1054,7 @@ find_path (struct grub_btrfs_data *data, const char *ctoken; grub_size_t ctokenlen; char *path_alloc = NULL; + char *origpath = NULL; unsigned symlinks_max = 32; *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; @@ -1062,6 +1063,9 @@ find_path (struct grub_btrfs_data *data, key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = 0; skip_default = 1; + origpath = grub_strdup (path); + if (!origpath) + return grub_errno; while (1) { @@ -1086,6 +1090,7 @@ find_path (struct grub_btrfs_data *data, if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) { grub_free (path_alloc); + grub_free (origpath); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } @@ -1098,13 +1103,16 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return err; } if (key_cmp (key, &key_out) != 0) { grub_free (direl); grub_free (path_alloc); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", origpath); + grub_free (origpath); + return err; } struct grub_btrfs_dir_item *cdirel; @@ -1116,6 +1124,7 @@ find_path (struct grub_btrfs_data *data, if (!direl) { grub_free (path_alloc); + grub_free (origpath); return grub_errno; } } @@ -1125,6 +1134,7 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return err; } @@ -1144,7 +1154,9 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", origpath); + grub_free (origpath); + return err; } if (!skip_default) @@ -1158,6 +1170,7 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); } @@ -1168,6 +1181,7 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return err; } tmp = grub_malloc (grub_le_to_cpu64 (inode.size) @@ -1176,6 +1190,7 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return grub_errno; } @@ -1186,12 +1201,14 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); grub_free (tmp); return grub_errno; } grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, grub_strlen (path) + 1); grub_free (path_alloc); + grub_free (origpath); path = path_alloc = tmp; if (path[0] == '/') { @@ -1218,6 +1235,7 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return err; } if (cdirel->key.object_id != key_out.object_id @@ -1225,7 +1243,9 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", origpath); + grub_free (origpath); + return err; } err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri)); @@ -1233,6 +1253,7 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); + grub_free (origpath); return err; } key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; @@ -1246,7 +1267,9 @@ find_path (struct grub_btrfs_data *data, { grub_free (direl); grub_free (path_alloc); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", origpath); + grub_free (origpath); + return err; } *key = cdirel->key; if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) @@ -1254,6 +1277,7 @@ find_path (struct grub_btrfs_data *data, break; default: grub_free (path_alloc); + grub_free (origpath); grub_free (direl); return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", cdirel->key.type); diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index f617bb0f4..c78d3fbe6 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -565,6 +565,7 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, const struct grub_dirhook_info *info)) { char *dirname, *dirp; + char *origpath = NULL; int call_hook; int found = 0; @@ -605,6 +606,10 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, return 0; } + origpath = grub_strdup (path); + if (!origpath) + return 0; + /* Extract a directory name. */ while (*path == '/') path++; @@ -616,7 +621,7 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, dirname = grub_malloc (len + 1); if (! dirname) - return 0; + goto fail; grub_memcpy (dirname, path, len); dirname[len] = '\0'; @@ -629,9 +634,11 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, grub_fat_iterate_dir (disk, data, iter_hook); if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook) - grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", origpath); + fail: grub_free (dirname); + grub_free (origpath); return found ? dirp : 0; } diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c index f879885ac..2ff78c423 100644 --- a/grub-core/fs/fshelp.c +++ b/grub-core/fs/fshelp.c @@ -197,7 +197,7 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, name = next; } - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path); } if (!path || path[0] != '/') diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index cb7679ecb..6f27c69c4 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -921,7 +921,7 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path, if (! grub_hfs_find_node (data, (char *) &key, data->cat_root, 0, (char *) &fdrec.frec, sizeof (fdrec.frec))) { - grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", origpath); goto fail; } diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index c131169d8..36ec5fd25 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -699,7 +699,7 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path) } grub_jfs_closedir (diro); - grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path); return grub_errno; } diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 64a64cca0..055f89095 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -424,7 +424,7 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path) pos += sizeof (ino) + data->filename_size; } while (pos < GRUB_MINIX_INODE_SIZE (data)); - grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path); return grub_errno; } diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 86fe8af65..0f4ea0019 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -514,7 +514,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) pos += grub_le_to_cpu16 (dirent.direntlen); } while (pos < INODE_SIZE (data)); - grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", path); return grub_errno; } From d36f20db4608fa7a8e66bdc86993fcd813e22c08 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 22:37:19 +0200 Subject: [PATCH 1108/1414] Don't do unaligned access when parsing DHCP packet --- grub-core/net/net.c | 11 ++++++++--- include/grub/net.h | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 2932986b2..560fa7a31 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -879,7 +879,10 @@ parse_dhcp_vendor (const char *name, void *vend, int limit) ptr = ptr0 = vend; - if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != GRUB_NET_BOOTP_RFC1048_MAGIC) + if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 + || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 + || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 + || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) return; ptr = ptr + sizeof (grub_uint32_t); while (ptr - ptr0 < limit) @@ -1078,8 +1081,10 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), ptr = inter->dhcp_ack->vendor; - if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) - != GRUB_NET_BOOTP_RFC1048_MAGIC) + if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 + || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 + || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 + || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); ptr = ptr + sizeof (grub_uint32_t); while (1) diff --git a/include/grub/net.h b/include/grub/net.h index 6595a8276..ee94ebcc6 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -394,7 +394,10 @@ struct grub_net_bootp_packet grub_uint8_t vendor[0]; } __attribute__ ((packed)); -#define GRUB_NET_BOOTP_RFC1048_MAGIC 0x63825363L +#define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 +#define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 +#define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 +#define GRUB_NET_BOOTP_RFC1048_MAGIC_3 0x63 struct grub_net_network_level_interface * grub_net_configure_by_dhcp_ack (const char *name, From 14f0752dcf5f55f9b50f0b6dce3362d53b180cce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 22:37:49 +0200 Subject: [PATCH 1109/1414] Print MAC address when listing cards --- grub-core/net/net.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 560fa7a31..34148f52c 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -576,9 +576,10 @@ grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)), struct grub_net_card *card; FOR_NET_CARDS(card) { - grub_printf ("%s ", card->name); + char buf[MAX_STR_HWADDR_LEN]; + hwaddr_to_str (&card->default_address, buf); + grub_printf ("%s %s\n", card->name, buf); } - grub_printf ("\n"); return GRUB_ERR_NONE; } From f8614119a02110e8ccd69499b5a03147e9535372 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 22:38:43 +0200 Subject: [PATCH 1110/1414] Few ofnet cleanups --- grub-core/net/drivers/ieee1275/ofnet.c | 47 ++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 2c264edb1..48c3cd635 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 @@ -37,7 +55,8 @@ card_close (struct grub_net_card *dev) } static grub_err_t -send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +send_card_buffer (const struct grub_net_card *dev, + struct grub_net_buff *pack) { int actual; int status; @@ -52,7 +71,8 @@ send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) } static grub_ssize_t -get_card_packet (struct grub_net_card *dev, struct grub_net_buff *nb) +get_card_packet (const struct grub_net_card *dev, + struct grub_net_buff *nb) { int actual, rc; @@ -125,20 +145,33 @@ grub_getbootp_real (void) static void grub_ofnet_findcards (void) { - struct grub_net_card *card; - grub_ieee1275_phandle_t devhandle; - grub_net_link_level_address_t lla; int i = 0; + auto int search_net_devices (struct grub_ieee1275_devalias *alias); int search_net_devices (struct grub_ieee1275_devalias *alias) { if (!grub_strcmp (alias->type, "network")) { + struct grub_ofnetcard_data *ofdata; + struct grub_net_card *card; + grub_ieee1275_phandle_t devhandle; + grub_net_link_level_address_t lla; + ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); + if (!ofdata) + { + grub_print_error (); + return 1; + } card = grub_malloc (sizeof (struct grub_net_card)); - struct grub_ofnetcard_data *ofdata = - grub_malloc (sizeof (struct grub_ofnetcard_data)); + if (!card) + { + grub_free (ofdata); + grub_print_error (); + return 1; + } + ofdata->path = grub_strdup (alias->path); grub_ieee1275_finddevice (ofdata->path, &devhandle); From 9d22909b8561f72a6503a1f26eab9652670db43f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 22:42:04 +0200 Subject: [PATCH 1111/1414] efinet support --- grub-core/Makefile.core.def | 8 +- grub-core/kern/x86_64/efi/callwrap.S | 14 +++ grub-core/net/drivers/efi/efinet.c | 165 +++++++++++++++++++++++++++ include/grub/efi/api.h | 81 +++++++++++++ 4 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 grub-core/net/drivers/efi/efinet.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 5c3ce99be..ac969e09c 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1588,10 +1588,16 @@ module = { module = { name = ofnet; - ieee1275 = net/drivers/ieee1275/ofnet.c; + common = net/drivers/ieee1275/ofnet.c; enable = ieee1275; }; +module = { + name = efinet; + common = net/drivers/efi/efinet.c; + enable = efi; +}; + module = { name = emunet; emu = net/drivers/emu/emunet.c; diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S index aae267872..cc2c8aa05 100644 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ b/grub-core/kern/x86_64/efi/callwrap.S @@ -95,6 +95,20 @@ FUNCTION(efi_wrap_6) addq $64, %rsp ret +FUNCTION(efi_wrap_7) + subq $96, %rsp + mov 96+16(%rsp), %rax + mov %rax, 48(%rsp) + mov 96+8(%rsp), %rax + mov %rax, 40(%rsp) + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + mov %rsi, %rcx + call *%rdi + addq $96, %rsp + ret + FUNCTION(efi_wrap_10) subq $96, %rsp mov 96+40(%rsp), %rax diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c new file mode 100644 index 000000000..a6e005601 --- /dev/null +++ b/grub-core/net/drivers/efi/efinet.c @@ -0,0 +1,165 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* GUID. */ +static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; + + +static grub_err_t +send_card_buffer (const struct grub_net_card *dev, + struct grub_net_buff *pack) +{ + grub_efi_status_t st; + grub_efi_simple_network_t *net = dev->data; + st = efi_call_7 (net->transmit, net, 0, pack->tail - pack->data, + pack->data, NULL, NULL, NULL); + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, "Couldn't send network packet."); + return GRUB_ERR_NONE; +} + +static grub_ssize_t +get_card_packet (const struct grub_net_card *dev, + struct grub_net_buff *nb) +{ + grub_efi_simple_network_t *net = dev->data; + grub_err_t err; + grub_efi_status_t st; + grub_efi_uintn_t bufsize = 1500; + + err = grub_netbuff_clear (nb); + if (err) + return -1; + + err = grub_netbuff_put (nb, 1500); + if (err) + return -1; + + st = efi_call_7 (net->receive, net, NULL, &bufsize, + nb->data, NULL, NULL, NULL); + if (st == GRUB_EFI_BUFFER_TOO_SMALL) + { + err = grub_netbuff_put (nb, bufsize - 1500); + if (err) + return -1; + st = efi_call_7 (net->receive, net, NULL, &bufsize, + nb->data, NULL, NULL, NULL); + } + if (st != GRUB_EFI_SUCCESS) + { + grub_netbuff_clear (nb); + return -1; + } + err = grub_netbuff_unput (nb, (nb->tail - nb->data) - bufsize); + if (err) + return -1; + + return bufsize; +} + +static struct grub_net_card_driver efidriver = + { + .name = "efinet", + .send = send_card_buffer, + .recv = get_card_packet + }; + + +static void +grub_efinet_findcards (void) +{ + grub_efi_uintn_t num_handles; + grub_efi_handle_t *handles; + grub_efi_handle_t *handle; + int i = 0; + + /* Find handles which support the disk io interface. */ + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &net_io_guid, + 0, &num_handles); + if (! handles) + return; + for (handle = handles; num_handles--; handle++) + { + grub_efi_simple_network_t *net; + struct grub_net_card *card; + + net = grub_efi_open_protocol (*handle, &net_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (! net) + /* This should not happen... Why? */ + continue; + + if (net->mode->state == GRUB_EFI_NETWORK_STOPPED + && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) + continue; + + if (net->mode->state == GRUB_EFI_NETWORK_STOPPED) + continue; + + if (net->mode->state == GRUB_EFI_NETWORK_STARTED + && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS) + continue; + + card = grub_zalloc (sizeof (struct grub_net_card)); + if (!card) + { + grub_print_error (); + grub_free (handles); + return; + } + + card->name = grub_xasprintf ("efinet%d", i++); + card->driver = &efidriver; + card->flags = 0; + card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + grub_memcpy (card->default_address.mac, + net->mode->current_address, + sizeof (card->default_address.mac)); + card->data = net; + + grub_net_card_register (card); + } + grub_free (handles); +} + +GRUB_MOD_INIT(efinet) +{ + grub_efinet_findcards (); +} + +GRUB_MOD_FINI(ofnet) +{ + struct grub_net_card *card; + FOR_NET_CARDS (card) + if (card->driver && !grub_strcmp (card->driver->name, "efinet")) + { + card->driver->fini (card); + card->driver = NULL; + } + grub_net_card_driver_unregister (&efidriver); +} + diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index ded03a1b3..a3dde0eff 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -84,6 +84,11 @@ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } +#define GRUB_EFI_SIMPLE_NETWORK_GUID \ + { 0xa19832b9, 0xac25, 0x11d3, \ + { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + #define GRUB_EFI_DEVICE_PATH_GUID \ { 0x09576e91, 0x6d3f, 0x11d2, \ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ @@ -1214,6 +1219,74 @@ struct grub_efi_block_io_media }; typedef struct grub_efi_block_io_media grub_efi_block_io_media_t; +typedef grub_uint8_t grub_efi_mac_t[32]; + +struct grub_efi_simple_network_mode +{ + grub_uint32_t state; + grub_uint32_t hwaddr_size; + grub_uint32_t media_header_size; + grub_uint32_t max_packet_size; + grub_uint32_t nvram_size; + grub_uint32_t nvram_access_size; + grub_uint32_t receive_filter_mask; + grub_uint32_t receive_filter_setting; + grub_uint32_t max_mcast_filter_count; + grub_uint32_t mcast_filter_count; + grub_efi_mac_t mcast_filter[16]; + grub_efi_mac_t current_address; + grub_efi_mac_t broadcast_address; + grub_efi_mac_t permanent_address; + grub_uint8_t if_type; + grub_uint8_t mac_changeable; + grub_uint8_t multitx_supported; + grub_uint8_t media_present_supported; + grub_uint8_t media_present; +}; + +enum + { + GRUB_EFI_NETWORK_STOPPED, + GRUB_EFI_NETWORK_STARTED, + GRUB_EFI_NETWORK_INITIALIZED, + }; + +struct grub_efi_simple_network +{ + grub_uint64_t revision; + grub_efi_status_t (*start) (struct grub_efi_simple_network *this); + void (*stop) (void); + grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, + grub_efi_uintn_t extra_rx, + grub_efi_uintn_t extra_tx); + void (*reset) (void); + void (*shutdown) (void); + void (*receive_filters) (void); + void (*station_address) (void); + void (*statistics) (void); + void (*mcastiptomac) (void); + void (*nvdata) (void); + void (*getstatus) (void); + grub_efi_status_t (*transmit) (struct grub_efi_simple_network *this, + grub_efi_uintn_t header_size, + grub_efi_uintn_t buffer_size, + void *buffer, + grub_efi_mac_t *src_addr, + grub_efi_mac_t *dest_addr, + grub_efi_uint16_t *protocol); + grub_efi_status_t (*receive) (struct grub_efi_simple_network *this, + grub_efi_uintn_t *header_size, + grub_efi_uintn_t *buffer_size, + void *buffer, + grub_efi_mac_t *src_addr, + grub_efi_mac_t *dest_addr, + grub_uint16_t *protocol); + void (*waitforpacket) (void); + struct grub_efi_simple_network_mode *mode; +}; +typedef struct grub_efi_simple_network grub_efi_simple_network_t; + + struct grub_efi_block_io { grub_efi_uint64_t revision; @@ -1243,6 +1316,7 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; #define efi_call_4(func, a, b, c, d) func(a, b, c, d) #define efi_call_5(func, a, b, c, d, e) func(a, b, c, d, e) #define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f) +#define efi_call_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g) #define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) func(a, b, c, d, e, f, g, h, i, j) #else @@ -1264,6 +1338,9 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; #define efi_call_6(func, a, b, c, d, e, f) \ efi_wrap_6(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f) +#define efi_call_7(func, a, b, c, d, e, f, g) \ + efi_wrap_7(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ + (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g) #define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \ efi_wrap_10(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g, \ @@ -1285,6 +1362,10 @@ grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1, grub_uint64_t arg2, grub_uint64_t arg3, grub_uint64_t arg4, grub_uint64_t arg5, grub_uint64_t arg6); +grub_uint64_t EXPORT_FUNC(efi_wrap_7) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6, grub_uint64_t arg7); grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1, grub_uint64_t arg2, grub_uint64_t arg3, grub_uint64_t arg4, grub_uint64_t arg5, From 0ff2c51b82c629e93fff4cc53c129b4d05a73667 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 26 Jun 2011 22:47:05 +0200 Subject: [PATCH 1112/1414] mknetdir support for EFI --- util/grub-mknetdir.in | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index a36e33cab..52598a8c9 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -48,6 +48,9 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc ppc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/powerpc-ieee1275 sparc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/sparc64-ieee1275 i386_ieee1275_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-ieee1275 +efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi +efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi +itanium_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/ia64-efi # Usage: usage # Print the usage. @@ -210,6 +213,9 @@ process_input_dir () *-ieee1275) mkimage_target="${platform}"; netmodules="ofnet"; ext=elf ;; + *-efi) mkimage_target="${platform}"; + netmodules="efinet"; + ext=efi ;; *) echo Unsupported platform ${platform}; exit 1;; esac @@ -235,6 +241,15 @@ if [ "${override_dir}" = "" ] ; then if test -e "${i386_ieee1275_dir}" ; then process_input_dir "${i386_ieee1275_dir}" i386-ieee1275 fi + if test -e "${efi32_dir}" ; then + process_input_dir "${efi32_dir}" i386-efi + fi + if test -e "${efi64_dir}" ; then + process_input_dir "${efi64_dir}" x86_64-efi + fi + if test -e "${itanium_dir}" ; then + process_input_dir "${itanium_dir}" ia64-efi + fi else source "${override_dir}"/modinfo.sh process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} From 59b455fceaee233e7221831e520c2dd76d42a466 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 06:31:25 +0200 Subject: [PATCH 1113/1414] Fix incorrect ISR PXE calls --- grub-core/net/drivers/i386/pc/pxe.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 084cdb876..144df964c 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -165,7 +165,10 @@ grub_pxe_recv (const struct grub_net_card *dev __attribute__ ((unused)), isr->func_flag = GRUB_PXE_ISR_IN_START; grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); if (isr->status || isr->func_flag != GRUB_PXE_ISR_OUT_OURS) - return -1; + { + in_progress = 0; + return -1; + } grub_memset (isr, 0, sizeof (*isr)); isr->func_flag = GRUB_PXE_ISR_IN_PROCESS; grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); @@ -180,7 +183,10 @@ grub_pxe_recv (const struct grub_net_card *dev __attribute__ ((unused)), while (isr->func_flag != GRUB_PXE_ISR_OUT_RECEIVE) { if (isr->status || isr->func_flag == GRUB_PXE_ISR_OUT_DONE) - return -1; + { + in_progress = 0; + return -1; + } grub_memset (isr, 0, sizeof (*isr)); isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); @@ -198,11 +204,15 @@ grub_pxe_recv (const struct grub_net_card *dev __attribute__ ((unused)), isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); if (isr->status || isr->func_flag != GRUB_PXE_ISR_OUT_RECEIVE) - return -1; + { + in_progress = 1; + return -1; + } grub_memcpy (ptr, LINEAR (isr->buffer), isr->buffer_len); ptr += isr->buffer_len; } + in_progress = 1; return len; } From ca80309d32c9d8890d5a16888eac80043a9a16ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 08:40:17 +0200 Subject: [PATCH 1114/1414] * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer): Fix prototype. (get_card_packet): Likewise. --- ChangeLog | 6 ++++++ grub-core/net/drivers/ieee1275/ofnet.c | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd6e311bd..62976120f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer): Fix + prototype. + (get_card_packet): Likewise. + 2011-06-26 Yves Blusseau Display the path of the file when file is not found diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 2c264edb1..0394e0dc0 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -37,7 +37,7 @@ card_close (struct grub_net_card *dev) } static grub_err_t -send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) +send_card_buffer (const struct grub_net_card *dev, struct grub_net_buff *pack) { int actual; int status; @@ -52,9 +52,8 @@ send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) } static grub_ssize_t -get_card_packet (struct grub_net_card *dev, struct grub_net_buff *nb) +get_card_packet (const struct grub_net_card *dev, struct grub_net_buff *nb) { - int actual, rc; struct grub_ofnetcard_data *data = dev->data; grub_uint64_t start_time; From 41bec7fec9b8a56172ab99997d5c86de9cffd405 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 08:43:13 +0200 Subject: [PATCH 1115/1414] * grub-core/disk/ahci.c (grub_ahci_readwrite_real): Use proper definitions for dprintf. * grub-core/disk/pata.c (grub_pata_readwrite): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/ahci.c | 3 ++- grub-core/disk/pata.c | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62976120f..df640a0ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/disk/ahci.c (grub_ahci_readwrite_real): Use proper + definitions for dprintf. + * grub-core/disk/pata.c (grub_pata_readwrite): Likewise. + 2011-06-27 Vladimir Serbinenko * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer): Fix diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 0f355aa53..415004fcf 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -590,7 +590,8 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, dev->command_table[0].prdt[0].size = (parms->size + (parms->size & 1) - 1) | GRUB_AHCI_INTERRUPT_ON_COMPLETE; - grub_dprintf ("ahci", "PRDT = %" PRIxGRUB_UINT64_T ", %x, %x (%x)\n", + grub_dprintf ("ahci", "PRDT = %" PRIxGRUB_UINT64_T ", %x, %x (%" + PRIuGRUB_SIZE ")\n", dev->command_table[0].prdt[0].data_base, dev->command_table[0].prdt[0].unused, dev->command_table[0].prdt[0].size, diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index 1cb42d04b..ac3b91a41 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -156,7 +156,8 @@ grub_pata_readwrite (struct grub_ata *disk, parms->taskfile.cmd, parms->taskfile.features, parms->taskfile.sectors); - grub_dprintf ("pata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n", + grub_dprintf ("pata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%" + PRIuGRUB_SIZE "\n", parms->taskfile.lba_high, parms->taskfile.lba_mid, parms->taskfile.lba_low, parms->size); From 9fc9ce3795196effead800fecffff70c0b3415bd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 08:54:55 +0200 Subject: [PATCH 1116/1414] Coreboot video support. * grub-core/Makefile.core.def (vga): Extend to coreboot and multiboot. (vbe): Likewise. * grub-core/kern/i386/coreboot/startup.S: Include int.S. * grub-core/kern/i386/pc/startup.S (grub_bios_interrupt): Moved from here ... * grub-core/kern/i386/int.S: ... here. * grub-core/video/i386/pc/vbe.c: Updated includes. * grub-core/video/i386/pc/vga.c: Likewise. * include/grub/i386/coreboot/memory.h (GRUB_MEMORY_MACHINE_SCRATCH_ADDR): New definition. (GRUB_MEMORY_MACHINE_SCRATCH_SEG): Likewise. (GRUB_MEMORY_MACHINE_SCRATCH_SIZE): Likewise. * include/grub/i386/pc/int.h (GRUB_CPU_INT_FLAGS_DEFAULT) [!PCBIOS]: Disable interrupts. * include/grub/i386/pc/vga.h: Removed. All users updated. --- ChangeLog | 20 ++++ grub-core/Makefile.am | 2 + grub-core/Makefile.core.def | 8 +- grub-core/kern/i386/coreboot/startup.S | 1 + grub-core/kern/i386/int.S | 140 +++++++++++++++++++++++++ grub-core/kern/i386/pc/startup.S | 100 +----------------- grub-core/video/i386/pc/vbe.c | 7 +- grub-core/video/i386/pc/vga.c | 5 +- include/grub/i386/coreboot/memory.h | 4 + include/grub/i386/pc/int.h | 5 + include/grub/i386/pc/vga.h | 28 ----- 11 files changed, 184 insertions(+), 136 deletions(-) create mode 100644 grub-core/kern/i386/int.S delete mode 100644 include/grub/i386/pc/vga.h diff --git a/ChangeLog b/ChangeLog index df640a0ef..311e65b05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-06-27 Vladimir Serbinenko + + Coreboot video support. + + * grub-core/Makefile.core.def (vga): Extend to coreboot and multiboot. + (vbe): Likewise. + * grub-core/kern/i386/coreboot/startup.S: Include int.S. + * grub-core/kern/i386/pc/startup.S (grub_bios_interrupt): Moved from + here ... + * grub-core/kern/i386/int.S: ... here. + * grub-core/video/i386/pc/vbe.c: Updated includes. + * grub-core/video/i386/pc/vga.c: Likewise. + * include/grub/i386/coreboot/memory.h + (GRUB_MEMORY_MACHINE_SCRATCH_ADDR): New definition. + (GRUB_MEMORY_MACHINE_SCRATCH_SEG): Likewise. + (GRUB_MEMORY_MACHINE_SCRATCH_SIZE): Likewise. + * include/grub/i386/pc/int.h (GRUB_CPU_INT_FLAGS_DEFAULT) [!PCBIOS]: + Disable interrupts. + * include/grub/i386/pc/vga.h: Removed. All users updated. + 2011-06-27 Vladimir Serbinenko * grub-core/disk/ahci.c (grub_ahci_readwrite_real): Use proper diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index a8862b309..c3ecba9cf 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -100,10 +100,12 @@ endif if COND_i386_coreboot KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h endif if COND_i386_multiboot KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h endif if COND_i386_qemu diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 927718359..7a0536b97 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1454,8 +1454,10 @@ module = { module = { name = vga; - i386_pc = video/i386/pc/vga.c; + common = video/i386/pc/vga.c; enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; }; module = { @@ -1533,8 +1535,10 @@ module = { module = { name = vbe; - i386_pc = video/i386/pc/vbe.c; + common = video/i386/pc/vbe.c; enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; }; module = { diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index cac023ddf..07c5437c0 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -87,3 +87,4 @@ codestart: */ #include "../realmode.S" +#include "../int.S" diff --git a/grub-core/kern/i386/int.S b/grub-core/kern/i386/int.S new file mode 100644 index 000000000..58ccfdaab --- /dev/null +++ b/grub-core/kern/i386/int.S @@ -0,0 +1,140 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 . + */ + +FUNCTION(grub_bios_interrupt) + pushf + cli +#ifndef GRUB_MACHINE_PCBIOS + sidt protidt +#endif + popf + pushl %ebp + pushl %ecx + pushl %eax + pushl %ebx + pushl %esi + pushl %edi + pushl %edx + + movb %al, intno + movl (%edx), %eax + movl %eax, LOCAL(bios_register_eax) + movw 4(%edx), %ax + movw %ax, LOCAL(bios_register_es) + movw 6(%edx), %ax + movw %ax, LOCAL(bios_register_ds) + movw 8(%edx), %ax + movw %ax, LOCAL(bios_register_flags) + + movl 12(%edx), %ebx + movl 16(%edx), %ecx + movl 20(%edx), %edi + movl 24(%edx), %esi + movl 28(%edx), %edx + + call prot_to_real + .code16 + pushf + cli +#ifndef GRUB_MACHINE_PCBIOS + lidt realidt +#endif + + mov %ds, %ax + push %ax + + /* movw imm16, %ax*/ + .byte 0xb8 +LOCAL(bios_register_es): + .short 0 + movw %ax, %es + /* movw imm16, %ax*/ + .byte 0xb8 +LOCAL(bios_register_ds): + .short 0 + movw %ax, %ds + + /* movw imm16, %ax*/ + .byte 0xb8 +LOCAL(bios_register_flags): + .short 0 + push %ax + popf + + /* movl imm32, %eax*/ + .byte 0x66, 0xb8 +LOCAL(bios_register_eax): + .long 0 + + /* int imm8. */ + .byte 0xcd +intno: + .byte 0 + + movl %eax, %cs:LOCAL(bios_register_eax) + movw %ds, %ax + movw %ax, %cs:LOCAL(bios_register_ds) + pop %ax + mov %ax, %ds + pushf + pop %ax + movw %ax, LOCAL(bios_register_flags) + mov %es, %ax + movw %ax, LOCAL(bios_register_es) + + popf + DATA32 call real_to_prot + .code32 + + popl %eax + + movl %ebx, 12(%eax) + movl %ecx, 16(%eax) + movl %edi, 20(%eax) + movl %esi, 24(%eax) + movl %edx, 28(%eax) + + movl %eax, %edx + + movl LOCAL(bios_register_eax), %eax + movl %eax, (%edx) + movw LOCAL(bios_register_es), %ax + movw %ax, 4(%edx) + movw LOCAL(bios_register_ds), %ax + movw %ax, 6(%edx) + movw LOCAL(bios_register_flags), %ax + movw %ax, 8(%edx) + + popl %edi + popl %esi + popl %ebx + popl %eax + popl %ecx + popl %ebp +#ifndef GRUB_MACHINE_PCBIOS + lidt protidt +#endif + ret +#ifndef GRUB_MACHINE_PCBIOS +realidt: + .word 0x100 + .long 0 +protidt: + .word 0 + .long 0 +#endif diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index e78a0aa9a..0fe114add 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -910,102 +910,4 @@ FUNCTION(grub_pxe_call) popl %ebp ret -FUNCTION(grub_bios_interrupt) - pushl %ebp - pushl %ecx - pushl %eax - pushl %ebx - pushl %esi - pushl %edi - pushl %edx - - movb %al, intno - movl (%edx), %eax - movl %eax, LOCAL(bios_register_eax) - movw 4(%edx), %ax - movw %ax, LOCAL(bios_register_es) - movw 6(%edx), %ax - movw %ax, LOCAL(bios_register_ds) - movw 8(%edx), %ax - movw %ax, LOCAL(bios_register_flags) - - movl 12(%edx), %ebx - movl 16(%edx), %ecx - movl 20(%edx), %edi - movl 24(%edx), %esi - movl 28(%edx), %edx - - call prot_to_real - .code16 - - mov %ds, %ax - push %ax - - /* movw imm16, %ax*/ - .byte 0xb8 -LOCAL(bios_register_es): - .short 0 - movw %ax, %es - /* movw imm16, %ax*/ - .byte 0xb8 -LOCAL(bios_register_ds): - .short 0 - movw %ax, %ds - - /* movw imm16, %ax*/ - .byte 0xb8 -LOCAL(bios_register_flags): - .short 0 - push %ax - popf - - /* movl imm32, %eax*/ - .byte 0x66, 0xb8 -LOCAL(bios_register_eax): - .long 0 - - /* int imm8. */ - .byte 0xcd -intno: - .byte 0 - - movl %eax, %cs:LOCAL(bios_register_eax) - movw %ds, %ax - movw %ax, %cs:LOCAL(bios_register_ds) - pop %ax - mov %ax, %ds - pushf - pop %ax - movw %ax, LOCAL(bios_register_flags) - mov %es, %ax - movw %ax, LOCAL(bios_register_es) - - DATA32 call real_to_prot - .code32 - - popl %eax - - movl %ebx, 12(%eax) - movl %ecx, 16(%eax) - movl %edi, 20(%eax) - movl %esi, 24(%eax) - movl %edx, 28(%eax) - - movl %eax, %edx - - movl LOCAL(bios_register_eax), %eax - movl %eax, (%edx) - movw LOCAL(bios_register_es), %ax - movw %ax, 4(%edx) - movw LOCAL(bios_register_ds), %ax - movw %ax, 6(%edx) - movw LOCAL(bios_register_flags), %ax - movw %ax, 8(%edx) - - popl %edi - popl %esi - popl %ebx - popl %eax - popl %ecx - popl %ebp - ret +#include "../int.S" diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index a109bcf43..c11b9a627 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -20,15 +20,14 @@ #include #include -#include -#include +#include #include #include #include #include #include #include -#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -377,7 +376,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, if (vbe_mode < 0x100) { /* If this is not a VESA mode, guess address. */ - framebuffer.ptr = (grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR; + framebuffer.ptr = (grub_uint8_t *) 0xa0000; } else { diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c index fe387a26b..08c9ca37d 100644 --- a/grub-core/video/i386/pc/vga.c +++ b/grub-core/video/i386/pc/vga.c @@ -18,8 +18,7 @@ #define grub_video_render_target grub_video_fbrender_target -#include -#include +#include #include #include #include @@ -34,7 +33,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define VGA_WIDTH 640 #define VGA_HEIGHT 350 -#define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) +#define VGA_MEM ((grub_uint8_t *) 0xa0000) #define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8)) static unsigned char text_mode; diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 0642280b9..2859b1d7c 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -28,6 +28,10 @@ #include #endif +#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 +#define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) +#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE 0x10000 + #define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */ #define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/pc/int.h index de23775d0..337752587 100644 --- a/include/grub/i386/pc/int.h +++ b/include/grub/i386/pc/int.h @@ -45,7 +45,12 @@ struct grub_bios_int_registers #define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200 #define GRUB_CPU_INT_FLAGS_DIRECTION 0x400 #define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800 +#ifdef GRUB_MACHINE_PCBIOS #define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT +#else +#define GRUB_CPU_INT_FLAGS_DEFAULT 0 +#endif + void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno, struct grub_bios_int_registers *regs); diff --git a/include/grub/i386/pc/vga.h b/include/grub/i386/pc/vga.h deleted file mode 100644 index ecc169022..000000000 --- a/include/grub/i386/pc/vga.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2007,2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_VGA_MACHINE_HEADER -#define GRUB_VGA_MACHINE_HEADER 1 - -#include -#include - -/* The VGA (at the beginning of upper memory). */ -#define GRUB_MEMORY_MACHINE_VGA_ADDR GRUB_MEMORY_MACHINE_UPPER - -#endif /* ! GRUB_VGA_MACHINE_HEADER */ From efff4b1cc3e390533a7333420cf980d304bd10bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 09:06:15 +0200 Subject: [PATCH 1117/1414] * util/grub-mkrescue.in: Rename "ata" to "pata" and add ahci when necessary. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 311e65b05..ca4145e33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-27 Vladimir Serbinenko + + * util/grub-mkrescue.in: Rename "ata" to "pata" and add ahci when + necessary. + 2011-06-27 Vladimir Serbinenko Coreboot video support. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 8367c4dd4..f054c43a9 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -275,7 +275,7 @@ if test -e "${pc_dir}" ; then fi # build multiboot core.img -make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "ata at_keyboard" +make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "pata ahci at_keyboard" if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 @@ -296,11 +296,11 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" fi -make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/qemu.img" "ata at_keyboard" +make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/qemu.img" "pata at_keyboard" if [ -e "${iso9660_dir}/boot/qemu.img" ] && [ -d "${rom_directory}" ]; then cp "${iso9660_dir}/boot/qemu.img" "${rom_directory}/qemu.img" fi -make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/coreboot.elf" "ata at_keyboard" +make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/coreboot.elf" "pata ahci at_keyboard" if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then cp "${iso9660_dir}/boot/coreboot.elf" "${rom_directory}/coreboot.elf" fi From 1e3d9b8612a3f2a4c907b98d6465fcf4e7a53c4e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 10:12:35 +0200 Subject: [PATCH 1118/1414] * grub-core/disk/scsi.c (grub_scsi_read): Limit SCSI reads to 32K because of underlying system restrictions. --- ChangeLog | 5 +++++ grub-core/disk/scsi.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca4145e33..360842279 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/disk/scsi.c (grub_scsi_read): Limit SCSI reads to 32K + because of underlying system restrictions. + 2011-06-27 Vladimir Serbinenko * util/grub-mkrescue.in: Rename "ata" to "pata" and add ahci when diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 35b8525c2..902564164 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -524,17 +524,36 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, scsi = disk->data; - /* Depending on the type, select a read function. */ - switch (scsi->devtype) + while (size) { - case grub_scsi_devtype_direct: - return grub_scsi_read10 (disk, sector, size, buf); + /* PATA doesn't support more than 32K reads. + Not sure about AHCI and USB. If it's confirmed that either of + them can do bigger reads reliably this value can be moved to 'scsi' + structure. */ + grub_size_t len = 32768 >> disk->log_sector_size; + grub_err_t err; + if (len > size) + len = size; + /* Depending on the type, select a read function. */ + switch (scsi->devtype) + { + case grub_scsi_devtype_direct: + err = grub_scsi_read10 (disk, sector, len, buf); + if (err) + return err; + break; - case grub_scsi_devtype_cdrom: - return grub_scsi_read12 (disk, sector, size, buf); + case grub_scsi_devtype_cdrom: + err = grub_scsi_read12 (disk, sector, len, buf); + if (err) + return err; + break; + } + size -= len; + sector += len; + buf += len << disk->log_sector_size; } - /* XXX: Never reached. */ return GRUB_ERR_NONE; #if 0 /* Workaround - it works - but very slowly, from some reason From f9b75e8a67f54b425b64c62ea68d7ced88c566bd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 27 Jun 2011 10:47:02 +0100 Subject: [PATCH 1119/1414] * grub-core/commands/videoinfo.c (hook): Indicate current video mode with `*'. (grub_cmd_videoinfo): Fetch current video mode. --- ChangeLog | 6 ++++++ grub-core/commands/videoinfo.c | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 360842279..1aabd6b18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-27 Colin Watson + + * grub-core/commands/videoinfo.c (hook): Indicate current video mode + with `*'. + (grub_cmd_videoinfo): Fetch current video mode. + 2011-06-27 Vladimir Serbinenko * grub-core/disk/scsi.c (grub_scsi_read): Limit SCSI reads to 32K diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 3e0c1a12e..91a87fecc 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -28,6 +28,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static unsigned height, width, depth; +static struct grub_video_mode_info *current_mode; static int hook (const struct grub_video_mode_info *info) @@ -41,7 +42,13 @@ hook (const struct grub_video_mode_info *info) if (info->mode_number == GRUB_VIDEO_MODE_NUMBER_INVALID) grub_printf (" "); else - grub_printf (" 0x%03x ", info->mode_number); + { + if (current_mode && info->mode_number == current_mode->mode_number) + grub_printf ("*"); + else + grub_printf (" "); + grub_printf (" 0x%03x ", info->mode_number); + } grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) @@ -122,6 +129,8 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), FOR_VIDEO_ADAPTERS (adapter) { + struct grub_video_mode_info info; + grub_printf ("Adapter '%s':\n", adapter->name); if (!adapter->iterate) @@ -130,7 +139,17 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), continue; } - if (adapter->id != id) + current_mode = NULL; + + if (adapter->id == id) + { + if (grub_video_get_info (&info) == GRUB_ERR_NONE) + current_mode = &info; + else + /* Don't worry about errors. */ + grub_errno = GRUB_ERR_NONE; + } + else { if (adapter->init ()) { @@ -145,6 +164,8 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), adapter->iterate (hook); + current_mode = NULL; + if (adapter->id != id) { if (adapter->fini ()) From b6f945dccbf99c7126cca5b01f4cea807ccffc9e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 12:13:21 +0200 Subject: [PATCH 1120/1414] * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer) Use right type in pointers on sparc64. (get_card_packet): Likewise. --- ChangeLog | 6 ++++++ grub-core/net/drivers/ieee1275/ofnet.c | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1aabd6b18..1a3237f88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer) Use right + type in pointers on sparc64. + (get_card_packet): Likewise. + 2011-06-27 Colin Watson * grub-core/commands/videoinfo.c (hook): Indicate current video mode diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 0394e0dc0..b5bb03dc8 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -39,7 +39,7 @@ card_close (struct grub_net_card *dev) static grub_err_t send_card_buffer (const struct grub_net_card *dev, struct grub_net_buff *pack) { - int actual; + grub_ssize_t actual; int status; struct grub_ofnetcard_data *data = dev->data; @@ -54,7 +54,8 @@ send_card_buffer (const struct grub_net_card *dev, struct grub_net_buff *pack) static grub_ssize_t get_card_packet (const struct grub_net_card *dev, struct grub_net_buff *nb) { - int actual, rc; + grub_ssize_t actual; + int rc; struct grub_ofnetcard_data *data = dev->data; grub_uint64_t start_time; From b28c56559b446bdc824fe650a641aa9e11923448 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 12:16:00 +0200 Subject: [PATCH 1121/1414] * util/ieee1275/grub-ofpathname.c (main): Handle --help and --version so that help2man doesn't fail. --- ChangeLog | 5 +++++ util/ieee1275/grub-ofpathname.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1a3237f88..37446af70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-27 Vladimir Serbinenko + + * util/ieee1275/grub-ofpathname.c (main): Handle --help and --version + so that help2man doesn't fail. + 2011-06-27 Vladimir Serbinenko * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer) Use right diff --git a/util/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c index 3ac6fce8b..a9bc2cfda 100644 --- a/util/ieee1275/grub-ofpathname.c +++ b/util/ieee1275/grub-ofpathname.c @@ -32,11 +32,16 @@ int main(int argc, char **argv) grub_util_init_nls (); - if (argc != 2) + if (argc != 2 || strcmp (argv[1], "--help") == 0) { printf("Usage: %s DEVICE\n", program_name); return 1; } + if (strcmp (argv[1], "--version") == 0) + { + printf ("%s\n", PACKAGE_STRING); + return 1; + } of_path = grub_util_devname_to_ofpath (argv[1]); printf("%s\n", of_path); From bdea37983323f19d0cf8d2ef529d4d0f88ba2d81 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 12:18:44 +0200 Subject: [PATCH 1122/1414] * grub-core/lib/relocator.c (malloc_in_range): Fix a memory corruption when handling leftovers. --- ChangeLog | 5 +++++ grub-core/lib/relocator.c | 13 +++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37446af70..e35b7c7ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/lib/relocator.c (malloc_in_range): Fix a memory corruption + when handling leftovers. + 2011-06-27 Vladimir Serbinenko * util/ieee1275/grub-ofpathname.c (main): Handle --help and --version diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index 6eb20b865..aa404731f 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -764,6 +764,9 @@ malloc_in_range (struct grub_relocator *rel, int inreg = 0, regbeg = 0, ncol = 0; #if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS int fwin = 0, fwb = 0, fwlefto = 0; +#endif +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + int last_lo = 0; #endif int last_start = 0; for (j = 0; j < N; j++) @@ -855,7 +858,7 @@ malloc_in_range (struct grub_relocator *rel, unsigned offend = alloc_end % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; struct grub_relocator_fw_leftover *lo - = events[last_start].leftover; + = events[last_lo].leftover; lo->freebytes[offstart / 8] &= ((1 << (8 - (start % 8))) - 1); grub_memset (lo->freebytes + (offstart + 7) / 8, 0, @@ -910,6 +913,7 @@ malloc_in_range (struct grub_relocator *rel, #if GRUB_RELOCATOR_HAVE_LEFTOVERS case REG_LEFTOVER_START: fwlefto++; + last_lo = j; break; case REG_LEFTOVER_END: @@ -1009,7 +1013,8 @@ malloc_in_range (struct grub_relocator *rel, curschu->extra = ne; } } -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS if (!oom && typepre == CHUNK_TYPE_FIRMWARE) { grub_addr_t fstart, fend; @@ -1021,7 +1026,6 @@ malloc_in_range (struct grub_relocator *rel, = ALIGN_UP (alloc_end, GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); -#if GRUB_RELOCATOR_HAVE_LEFTOVERS { struct grub_relocator_fw_leftover *lo1 = NULL; struct grub_relocator_fw_leftover *lo2 = NULL; @@ -1081,10 +1085,8 @@ malloc_in_range (struct grub_relocator *rel, curschu->pre = lo1; curschu->post = lo2; } -#endif } -#if GRUB_RELOCATOR_HAVE_LEFTOVERS if (typepre == CHUNK_TYPE_LEFTOVER) { curschu->pre = events[last_start].leftover; @@ -1092,7 +1094,6 @@ malloc_in_range (struct grub_relocator *rel, } #endif -#endif if (!oom) cural++; else From 5ebaad7eec21a1d209d781b8c0b17f993a238380 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 12:28:47 +0200 Subject: [PATCH 1123/1414] * include/grub/loader.h (grub_loader_unregister_preboot_hook): Export. --- ChangeLog | 4 ++++ include/grub/loader.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e35b7c7ff..866e2ccaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-27 Vladimir Serbinenko + + * include/grub/loader.h (grub_loader_unregister_preboot_hook): Export. + 2011-06-27 Vladimir Serbinenko * grub-core/lib/relocator.c (malloc_in_range): Fix a memory corruption diff --git a/include/grub/loader.h b/include/grub/loader.h index c71e8dd10..f38deb96a 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -61,6 +61,6 @@ void *EXPORT_FUNC(grub_loader_register_preboot_hook) (grub_err_t (*preboot_func) grub_loader_preboot_hook_prio_t prio); /* Unregister given preboot hook. */ -void grub_loader_unregister_preboot_hook (void *hnd); +void EXPORT_FUNC (grub_loader_unregister_preboot_hook) (void *hnd); #endif /* ! GRUB_LOADER_HEADER */ From 5ff1d945ed89aa6203fdc005a55dbb83b3380ea1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 12:31:37 +0200 Subject: [PATCH 1124/1414] Implement time command. * grub-core/Makefile.core.def (time): New module. * grub-core/commands/time.c: New file. * grub-core/script/parser.y: Remove "time" keyword. * grub-core/script/yylex.l: Likewise. --- ChangeLog | 9 +++++ grub-core/Makefile.core.def | 5 +++ grub-core/commands/time.c | 68 +++++++++++++++++++++++++++++++++++++ grub-core/script/parser.y | 2 -- grub-core/script/yylex.l | 1 - 5 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 grub-core/commands/time.c diff --git a/ChangeLog b/ChangeLog index 866e2ccaf..4cdbc2b15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-06-27 Vladimir Serbinenko + + Implement time command. + + * grub-core/Makefile.core.def (time): New module. + * grub-core/commands/time.c: New file. + * grub-core/script/parser.y: Remove "time" keyword. + * grub-core/script/yylex.l: Likewise. + 2011-06-27 Vladimir Serbinenko * include/grub/loader.h (grub_loader_unregister_preboot_hook): Export. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7a0536b97..b10c16d55 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1641,3 +1641,8 @@ module = { common = commands/keylayouts.c; enable = videomodules; }; + +module = { + name = time; + common = commands/time.c; +}; diff --git a/grub-core/commands/time.c b/grub-core/commands/time.c new file mode 100644 index 000000000..687495964 --- /dev/null +++ b/grub-core/commands/time.c @@ -0,0 +1,68 @@ +/* echo.c - Command to display a line of text */ +/* + * 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_time (grub_command_t ctxt __attribute__ ((unused)), + int argc, char **args) +{ + grub_command_t cmd; + grub_uint32_t start; + grub_uint32_t end; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "command expected"); + + cmd = grub_command_find (args[0]); + + if (!cmd) + return grub_error (GRUB_ERR_UNKNOWN_COMMAND, "Unknown command `%s'\n", + args[0]); + + start = grub_get_time_ms (); + (cmd->func) (cmd, argc - 1, &args[1]); + end = grub_get_time_ms (); + + grub_printf ("Elapsed time: %d.%03d seconds \n", (end - start) / 1000, + (end - start) % 1000); + + return grub_errno; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(time) +{ + cmd = grub_register_command ("time", grub_cmd_time, + N_("COMMAND [ARGS]"), + N_("Measure time used by COMMAND")); +} + +GRUB_MOD_FINI(time) +{ + grub_unregister_command (cmd); +} diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y index 683b3ac4b..cc20b5479 100644 --- a/grub-core/script/parser.y +++ b/grub-core/script/parser.y @@ -74,7 +74,6 @@ %token GRUB_PARSER_TOKEN_THEN "then" %token GRUB_PARSER_TOKEN_UNTIL "until" %token GRUB_PARSER_TOKEN_WHILE "while" -%token GRUB_PARSER_TOKEN_TIME "time" %token GRUB_PARSER_TOKEN_FUNCTION "function" %token GRUB_PARSER_TOKEN_NAME "name" %token GRUB_PARSER_TOKEN_WORD "word" @@ -147,7 +146,6 @@ argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); } | "until" { $$ = grub_script_add_arglist (state, 0, $1); } | "while" { $$ = grub_script_add_arglist (state, 0, $1); } | "function" { $$ = grub_script_add_arglist (state, 0, $1); } - | "time" { $$ = grub_script_add_arglist (state, 0, $1); } | word { $$ = $1; } ; diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 96f57dbe6..7195a880d 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -161,7 +161,6 @@ MULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n)) "}" { RECORD; return GRUB_PARSER_TOKEN_RBR; } "[[" { RECORD; return GRUB_PARSER_TOKEN_RSQBR2; } "]]" { RECORD; return GRUB_PARSER_TOKEN_LSQBR2; } -"time" { RECORD; return GRUB_PARSER_TOKEN_TIME; } "case" { RECORD; return GRUB_PARSER_TOKEN_CASE; } "do" { RECORD; return GRUB_PARSER_TOKEN_DO; } "done" { RECORD; return GRUB_PARSER_TOKEN_DONE; } From d0b526b2778db75c5cfd01182de7f3808f466a1a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 13:57:03 +0200 Subject: [PATCH 1125/1414] * grub-core/loader/i386/bsd.c (grub_bsd_load): Handle relocator failure if it happens. --- ChangeLog | 5 +++++ grub-core/loader/i386/bsd.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4cdbc2b15..c097af2f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/loader/i386/bsd.c (grub_bsd_load): Handle relocator failure + if it happens. + 2011-06-27 Vladimir Serbinenko Implement time command. diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 6487dc3df..dffe48257 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -1322,6 +1322,11 @@ grub_bsd_load (int argc, char *argv[]) goto fail; relocator = grub_relocator_new (); + if (!relocator) + { + grub_file_close (file); + goto fail; + } elf = grub_elf_file (file); if (elf) @@ -1343,7 +1348,7 @@ grub_bsd_load (int argc, char *argv[]) fail: if (grub_errno != GRUB_ERR_NONE) - grub_dl_unref (my_mod); + grub_dl_unref (my_mod); return grub_errno; } From ba7df45ee6be05bb9fd781041f915f112fa8e52c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 14:14:11 +0200 Subject: [PATCH 1126/1414] Chainloading on coreboot support. * grub-core/Makefile.core.def (chain): Add coreboot. * grub-core/loader/i386/coreboot/chainloader.c: New file. --- ChangeLog | 7 + grub-core/Makefile.core.def | 2 + grub-core/loader/i386/coreboot/chainloader.c | 145 +++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 grub-core/loader/i386/coreboot/chainloader.c diff --git a/ChangeLog b/ChangeLog index c097af2f7..9922f2a2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-27 Vladimir Serbinenko + + Chainloading on coreboot support. + + * grub-core/Makefile.core.def (chain): Add coreboot. + * grub-core/loader/i386/coreboot/chainloader.c: New file. + 2011-06-27 Vladimir Serbinenko * grub-core/loader/i386/bsd.c (grub_bsd_load): Handle relocator failure diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index b10c16d55..faed6cc85 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1298,7 +1298,9 @@ module = { name = chain; efi = loader/efi/chainloader.c; i386_pc = loader/i386/pc/chainloader.c; + i386_coreboot = loader/i386/corepayload.c; enable = i386_pc; + enable = i386_coreboot; enable = efi; }; diff --git a/grub-core/loader/i386/coreboot/chainloader.c b/grub-core/loader/i386/coreboot/chainloader.c new file mode 100644 index 000000000..3f85aa3a9 --- /dev/null +++ b/grub-core/loader/i386/coreboot/chainloader.c @@ -0,0 +1,145 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_addr_t entry; +static struct grub_relocator *relocator = NULL; + +static grub_err_t +grub_chain_boot (void) +{ + struct grub_relocator32_state state; + + grub_video_set_mode ("text", 0, 0); + + state.eip = entry; + return grub_relocator32_boot (relocator, state); +} + +static grub_err_t +grub_chain_unload (void) +{ + grub_relocator_unload (relocator); + relocator = NULL; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_chain_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load) +{ + grub_err_t err; + grub_relocator_chunk_t ch; + + if (phdr->p_type != PT_LOAD) + { + *do_load = 0; + return 0; + } + + *do_load = 1; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + phdr->p_paddr, phdr->p_memsz); + if (err) + return err; + + *addr = (grub_addr_t) get_virtual_current_address (ch); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_err_t err; + grub_file_t file; + grub_elf_t elf; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename expected"); + + grub_loader_unset (); + + file = grub_file_open (argv[0]); + if (!file) + return grub_errno; + + relocator = grub_relocator_new (); + if (!relocator) + { + grub_file_close (file); + return grub_errno; + } + + elf = grub_elf_file (file); + if (!elf) + { + grub_relocator_unload (relocator); + relocator = 0; + grub_file_close (file); + } + + if (!grub_elf_is_elf32 (elf)) + { + grub_relocator_unload (relocator); + relocator = 0; + grub_elf_close (elf); + } + + entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; + + err = grub_elf32_load (elf, grub_chain_elf32_hook, 0, 0); + + grub_elf_close (elf); + if (err) + return err; + + grub_loader_set (grub_chain_boot, grub_chain_unload, 0); + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_chain; + +GRUB_MOD_INIT (chain) +{ + cmd_chain = grub_register_command ("chainloader", grub_cmd_chain, + N_("FILE"), N_("Load another payload")); +} + +GRUB_MOD_FINI (chain) +{ + grub_unregister_command (cmd_chain); + grub_chain_unload (); +} From 5afeb5bdd615f18ef58316132112a3a9b6e4c823 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 19:26:52 +0200 Subject: [PATCH 1127/1414] * grub-core/disk/pata.c (grub_pata_initialize) [QEMU_MIPS]: Fix a mismerge. --- ChangeLog | 5 +++++ grub-core/disk/pata.c | 8 +++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9922f2a2b..a9dacd42b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/disk/pata.c (grub_pata_initialize) [QEMU_MIPS]: Fix a + mismerge. + 2011-06-27 Vladimir Serbinenko Chainloading on coreboot support. diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index ac3b91a41..95828e8f6 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -438,15 +438,13 @@ grub_pata_initialize (void) } #else static grub_err_t -grub_ata_initialize (void) +grub_pata_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]); + grub_pata_device_initialize (i, 0, grub_pata_ioaddress[i]); + grub_pata_device_initialize (i, 1, grub_pata_ioaddress[i]); } return 0; } From 8d5d8444bd95338d487e715e9c93fa3328137b9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 27 Jun 2011 19:30:16 +0200 Subject: [PATCH 1128/1414] * grub-core/Makefile.core.def (chain): Fix coreboot filename. --- ChangeLog | 4 ++++ grub-core/Makefile.core.def | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a9dacd42b..81d98716d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-27 Vladimir Serbinenko + + * grub-core/Makefile.core.def (chain): Fix coreboot filename. + 2011-06-27 Vladimir Serbinenko * grub-core/disk/pata.c (grub_pata_initialize) [QEMU_MIPS]: Fix a diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index faed6cc85..fd69e9c22 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1298,7 +1298,7 @@ module = { name = chain; efi = loader/efi/chainloader.c; i386_pc = loader/i386/pc/chainloader.c; - i386_coreboot = loader/i386/corepayload.c; + i386_coreboot = loader/i386/coreboot/chainloader.c; enable = i386_pc; enable = i386_coreboot; enable = efi; From 548947916b74f8b4b66f88a4cf08b233fd31047c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 28 Jun 2011 17:05:41 +0100 Subject: [PATCH 1129/1414] * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use default_bg_color rather than black. (grub_gfxterm_fullscreen): Likewise. (grub_gfxterm_background_color_cmd): Save new background color in default_bg_color. --- ChangeLog | 8 ++++++++ grub-core/term/gfxterm.c | 16 +++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81d98716d..4b8d8f149 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-06-28 Colin Watson + + * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use + default_bg_color rather than black. + (grub_gfxterm_fullscreen): Likewise. + (grub_gfxterm_background_color_cmd): Save new background color in + default_bg_color. + 2011-06-27 Vladimir Serbinenko * grub-core/Makefile.core.def (chain): Fix coreboot filename. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 9e3d8eeb1..2f8deac18 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -131,6 +131,7 @@ static unsigned int bitmap_width; static unsigned int bitmap_height; static struct grub_video_bitmap *bitmap; static int blend_text_bg; +static grub_video_rgba_color_t default_bg_color = { 0, 0, 0, 0 }; static struct grub_dirty_region dirty_region; @@ -266,7 +267,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, grub_video_set_active_render_target (render_target); - virtual_screen.bg_color_display = grub_video_map_rgba(0, 0, 0, 0); + virtual_screen.bg_color_display = + grub_video_map_rgba_color (default_bg_color); /* Clear out text buffer. */ for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) @@ -338,8 +340,8 @@ grub_gfxterm_fullscreen (void) double_redraw = mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - /* Make sure screen is black. */ - color = grub_video_map_rgb (0, 0, 0); + /* Make sure screen is set to the default background color. */ + color = grub_video_map_rgba_color (default_bg_color); grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); if (double_redraw) { @@ -1189,7 +1191,6 @@ 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; struct grub_video_render_target *old_target; if (argc != 1) @@ -1199,7 +1200,7 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), if (grub_video_get_info (NULL) != GRUB_ERR_NONE) return grub_errno; - if (grub_video_parse_color (args[0], &color) != GRUB_ERR_NONE) + if (grub_video_parse_color (args[0], &default_bg_color) != GRUB_ERR_NONE) return grub_errno; /* Destroy existing background bitmap if loaded. */ @@ -1216,9 +1217,10 @@ grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), 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 = grub_video_map_rgba_color (default_bg_color); grub_video_set_active_render_target (old_target); - virtual_screen.bg_color_display = grub_video_map_rgba_color (color); + virtual_screen.bg_color_display = + grub_video_map_rgba_color (default_bg_color); blend_text_bg = 1; /* Mark whole screen as dirty. */ From 574618a2e9a1dc8daf46c0e929acb0353f5f0101 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 14:09:36 +0200 Subject: [PATCH 1130/1414] unify prefix handling across platforms --- grub-core/Makefile.core.def | 5 +- grub-core/boot/i386/pc/diskboot.S | 2 +- grub-core/disk/efi/efidisk.c | 30 +++-- grub-core/kern/efi/init.c | 84 ++---------- grub-core/kern/emu/main.c | 16 +-- grub-core/kern/i386/coreboot/init.c | 5 +- grub-core/kern/i386/efi/init.c | 6 - grub-core/kern/i386/pc/init.c | 78 +++++------ grub-core/kern/ia64/efi/init.c | 6 - grub-core/kern/ieee1275/cmain.c | 4 + grub-core/kern/ieee1275/init.c | 90 ++++++------- grub-core/kern/ieee1275/openfw.c | 5 + grub-core/kern/main.c | 70 ++++++++-- grub-core/kern/mips/init.c | 4 +- grub-core/kern/sparc64/ieee1275/init.c | 174 ------------------------- include/grub/kernel.h | 5 +- include/grub/offsets.h | 4 +- 17 files changed, 189 insertions(+), 399 deletions(-) delete mode 100644 grub-core/kern/sparc64/ieee1275/init.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index ac969e09c..df852e09e 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -102,6 +102,7 @@ kernel = { ieee1275 = kern/ieee1275/mmap.c; ieee1275 = kern/ieee1275/openfw.c; ieee1275 = term/ieee1275/ofconsole.c; + ieee1275 = kern/ieee1275/init.c; terminfoinkernel = term/terminfo.c; terminfoinkernel = term/tparm.c; @@ -153,8 +154,6 @@ kernel = { i386_multiboot = kern/i386/multiboot_mmap.c; i386_multiboot = kern/i386/tsc.c; - i386_ieee1275 = kern/ieee1275/init.c; - mips = kern/mips/cache.S; mips = kern/mips/dl.c; mips = kern/mips/init.c; @@ -179,14 +178,12 @@ kernel = { extra_dist = video/sm712_init.c; mips_loongson = commands/keylayouts.c; - powerpc_ieee1275 = kern/ieee1275/init.c; powerpc_ieee1275 = kern/powerpc/cache.S; powerpc_ieee1275 = kern/powerpc/dl.c; sparc64_ieee1275 = kern/sparc64/cache.S; sparc64_ieee1275 = kern/sparc64/dl.c; sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c; - sparc64_ieee1275 = kern/sparc64/ieee1275/init.c; emu = disk/host.c; emu = gnulib/progname.c; diff --git a/grub-core/boot/i386/pc/diskboot.S b/grub-core/boot/i386/pc/diskboot.S index 92f223f0d..336c3bcca 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/grub-core/boot/i386/pc/diskboot.S @@ -83,7 +83,7 @@ LOCAL(setup_sectors): /* the maximum is limited to 0x7f because of Phoenix EDD */ xorl %eax, %eax - movb $0x7f, %al + movb $0x1, %al /* how many do we really want to read? */ cmpw %ax, 8(%di) /* compare against total number of sectors */ diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 35602513e..5dc753046 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -530,7 +530,7 @@ grub_efidisk_open (const char *name, struct grub_disk *disk) and total sectors should be replaced with total blocks. */ grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n", m, (unsigned long long) m->last_block, m->block_size); - disk->total_sectors = m->last_block; + disk->total_sectors = m->last_block + 1; if (m->block_size & (m->block_size - 1) || !m->block_size) return grub_error (GRUB_ERR_IO, "invalid sector size %d", m->block_size); @@ -788,19 +788,27 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) /* Find a partition which matches the hard drive device path. */ grub_memcpy (&hd, ldp, sizeof (hd)); - grub_partition_iterate (parent, find_partition); - - if (! tpart) + if (hd.partition_start == 0 + && hd.partition_size == grub_disk_get_size (parent)) { - grub_disk_close (parent); - return 0; + device_name = grub_strdup (parent->name); } + else + { + char *partition_name; - { - char *partition_name = grub_partition_get_name (tpart); - device_name = grub_xasprintf ("%s,%s", parent->name, partition_name); - grub_free (partition_name); - } + grub_partition_iterate (parent, find_partition); + + if (! tpart) + { + grub_disk_close (parent); + return 0; + } + + partition_name = grub_partition_get_name (tpart); + device_name = grub_xasprintf ("%s,%s", parent->name, partition_name); + grub_free (partition_name); + } grub_disk_close (parent); return device_name; diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 1b0a872b4..a7325acc6 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -43,83 +43,21 @@ grub_efi_init (void) } void -grub_efi_set_prefix (void) +grub_machine_get_bootlocation (char **device, char **path) { grub_efi_loaded_image_t *image = NULL; - char *device = NULL; - char *path = NULL; + char *p; - { - char *pptr = NULL; - if (grub_prefix[0] == '(') - { - pptr = grub_strrchr (grub_prefix, ')'); - if (pptr) - { - device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); - pptr++; - } - } - if (!pptr) - pptr = grub_prefix; - if (pptr[0]) - path = grub_strdup (pptr); - } + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (!image) + return; + *device = grub_efidisk_get_device_name (image->device_handle); + *path = grub_efi_get_filename (image->file_path); - if ((!device || device[0] == ',' || !device[0]) || !path) - image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (image) - { - if (!device) - device = grub_efidisk_get_device_name (image->device_handle); - else if (device[0] == ',' || !device[0]) - { - /* We have a partition, but still need to fill in the drive. */ - char *image_device, *comma, *new_device; - - image_device = grub_efidisk_get_device_name (image->device_handle); - comma = grub_strchr (image_device, ','); - if (comma) - { - char *drive = grub_strndup (image_device, comma - image_device); - new_device = grub_xasprintf ("%s%s", drive, device); - grub_free (drive); - } - else - new_device = grub_xasprintf ("%s%s", image_device, device); - - grub_free (image_device); - grub_free (device); - device = new_device; - } - } - - if (image && !path) - { - char *p; - - path = grub_efi_get_filename (image->file_path); - - /* Get the directory. */ - p = grub_strrchr (path, '/'); - if (p) - *p = '\0'; - } - - if (device && path) - { - char *prefix; - - prefix = grub_xasprintf ("(%s)%s", device, path); - if (prefix) - { - grub_env_set ("prefix", prefix); - grub_free (prefix); - } - } - - grub_free (device); - grub_free (path); + /* Get the directory. */ + p = grub_strrchr (*path, '/'); + if (p) + *p = '\0'; } void diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 0a7645992..096e97090 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -49,7 +49,7 @@ static jmp_buf main_env; /* Store the prefix specified by an argument. */ -static char *prefix = NULL; +static char *root_dev = NULL, *dir = DEFAULT_DIRECTORY; int grub_no_autoload; @@ -71,11 +71,10 @@ grub_machine_init (void) } void -grub_machine_set_prefix (void) +grub_machine_get_bootlocation (char **device, char **path) { - grub_env_set ("prefix", prefix); - free (prefix); - prefix = 0; + *device = root_dev; + *path = dir; } void @@ -84,6 +83,8 @@ grub_machine_fini (void) grub_console_fini (); } +char grub_prefix[64] = ""; + static struct option options[] = @@ -132,8 +133,6 @@ void grub_emu_init (void); int main (int argc, char *argv[]) { - char *root_dev = 0; - char *dir = DEFAULT_DIRECTORY; char *dev_map = DEFAULT_DEVICE_MAP; volatile int hold = 0; int opt; @@ -219,9 +218,6 @@ main (int argc, char *argv[]) dir = xstrdup (dir); else dir = grub_make_system_path_relative_to_its_root (dir); - prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1); - sprintf (prefix, "(%s)%s", root_dev, dir); - free (dir); /* Start GRUB! */ if (setjmp (main_env) == 0) diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index 434b9b5a8..ebbea2523 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -107,10 +107,9 @@ grub_machine_init (void) } void -grub_machine_set_prefix (void) +grub_machine_get_bootlocation (char **device __attribute__ ((unused)), + char **path __attribute__ ((unused))) { - /* Initialize the prefix. */ - grub_env_set ("prefix", grub_prefix); } void diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c index f73f828c6..6bd8f3e87 100644 --- a/grub-core/kern/i386/efi/init.c +++ b/grub-core/kern/i386/efi/init.c @@ -39,9 +39,3 @@ grub_machine_fini (void) { grub_efi_fini (); } - -void -grub_machine_set_prefix (void) -{ - grub_efi_set_prefix (); -} diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index d8c337bde..3aedaf6d8 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -45,52 +45,39 @@ struct mem_region static struct mem_region mem_regions[MAX_REGIONS]; static int num_regions; -static char * -make_install_device (void) +void +grub_machine_get_bootlocation (char **device, + char **path __attribute__ ((unused))) { + char *ptr; + + /* No hardcoded root partition - make it from the boot drive and the + partition number encoded at the install time. */ + if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL) + { + *device = grub_strdup ("pxe"); + return; + } + /* XXX: This should be enough. */ - char dev[100], *ptr = dev; +#define DEV_SIZE 100 + *device = grub_malloc (DEV_SIZE); + ptr = *device; + grub_snprintf (*device, DEV_SIZE, + "%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', + grub_boot_drive & 0x7f); + ptr += grub_strlen (ptr); - if (grub_prefix[0] != '(') - { - /* No hardcoded root partition - make it from the boot drive and the - partition number encoded at the install time. */ - if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL) - { - grub_strcpy (dev, "(pxe"); - ptr += sizeof ("(pxe") - 1; - } - else - { - grub_snprintf (dev, sizeof (dev), - "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', - grub_boot_drive & 0x7f); - ptr += grub_strlen (ptr); + if (grub_install_dos_part >= 0) + grub_snprintf (ptr, DEV_SIZE - (ptr - *device), + ",%u", grub_install_dos_part + 1); + ptr += grub_strlen (ptr); - if (grub_install_dos_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), - ",%u", grub_install_dos_part + 1); - ptr += grub_strlen (ptr); - - if (grub_install_bsd_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u", - grub_install_bsd_part + 1); - ptr += grub_strlen (ptr); - } - - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix); - grub_strcpy (grub_prefix, dev); - } - else if (grub_prefix[1] == ',' || grub_prefix[1] == ')') - { - /* We have a prefix, but still need to fill in the boot drive. */ - grub_snprintf (dev, sizeof (dev), - "(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f', - grub_boot_drive & 0x7f, grub_prefix + 1); - grub_strcpy (grub_prefix, dev); - } - - return grub_prefix; + if (grub_install_bsd_part >= 0) + grub_snprintf (ptr, DEV_SIZE - (ptr - *device), ",%u", + grub_install_bsd_part + 1); + ptr += grub_strlen (ptr); + *ptr = 0; } /* Add a memory region. */ @@ -211,13 +198,6 @@ grub_machine_init (void) grub_tsc_init (); } -void -grub_machine_set_prefix (void) -{ - /* Initialize the prefix. */ - grub_env_set ("prefix", make_install_device ()); -} - void grub_machine_fini (void) { diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index 6bb4219ac..e2fa58090 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -40,12 +40,6 @@ 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) { diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c index 2fbe809b2..eeb462c5e 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c @@ -60,6 +60,10 @@ grub_ieee1275_find_options (void) int is_olpc = 0; int is_qemu = 0; +#ifdef _sparc64 + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); +#endif + grub_ieee1275_finddevice ("/", &root); grub_ieee1275_finddevice ("/options", &options); grub_ieee1275_finddevice ("/openprom", &openprom); diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 3c55096a4..3c6332553 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef __sparc__ +#include +#endif /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) @@ -49,6 +52,10 @@ extern char _start[]; extern char _end[]; +#ifdef __sparc__ +grub_addr_t grub_ieee1275_original_stack; +#endif + void grub_exit (void) { @@ -71,51 +78,39 @@ grub_translate_ieee1275_path (char *filepath) } void -grub_machine_set_prefix (void) +grub_machine_get_bootlocation (char **device, char **path) { char bootpath[64]; /* XXX check length */ char *filename; - char *prefix; grub_bootp_t bootp_pckt; - char addr[GRUB_NET_MAX_STR_ADDR_LEN]; /* Set the net prefix when possible. */ if (grub_getbootp && (bootp_pckt = grub_getbootp())) { - grub_uint32_t n = bootp_pckt->siaddr; - grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d", - ((n >> 24) & 0xff), ((n >> 16) & 0xff), - ((n >> 8) & 0xff), ((n >> 0) & 0xff)); - prefix = grub_xasprintf ("(tftp,%s)%s", addr,grub_prefix); - grub_env_set ("prefix", prefix); - grub_free (prefix); + grub_uint32_t n = bootp_pckt->siaddr; + char addr[GRUB_NET_MAX_STR_ADDR_LEN]; + grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d", + ((n >> 24) & 0xff), ((n >> 16) & 0xff), + ((n >> 8) & 0xff), ((n >> 0) & 0xff)); + *device = grub_xasprintf ("(tftp,%s)", addr); return; } - if (grub_prefix[0]) - { - grub_env_set ("prefix", grub_prefix); - /* Prefix is hardcoded in the core image. */ - return; - } - if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, sizeof (bootpath), 0)) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); - grub_env_set ("prefix", ""); return; } /* Transform an OF device path to a GRUB path. */ - prefix = grub_ieee1275_encode_devname (bootpath); + *device = grub_ieee1275_encode_devname (bootpath); filename = grub_ieee1275_get_filename (bootpath); if (filename) { - char *newprefix; char *lastslash = grub_strrchr (filename, '\\'); /* Truncate at last directory. */ @@ -124,23 +119,22 @@ grub_machine_set_prefix (void) *lastslash = '\0'; grub_translate_ieee1275_path (filename); - newprefix = grub_xasprintf ("%s%s", prefix, filename); - if (newprefix) - { - grub_free (prefix); - prefix = newprefix; - } + *path = filename; } } - - grub_env_set ("prefix", prefix); - - grub_free (filename); - grub_free (prefix); } /* Claim some available memory in the first /memory node. */ -static void grub_claim_heap (void) +#ifdef __sparc__ +static void +grub_claim_heap (void) +{ + grub_mm_init_region ((void *) (grub_modules_get_end () + + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); +} +#else +static void +grub_claim_heap (void) { unsigned long total = 0; @@ -208,23 +202,14 @@ static void grub_claim_heap (void) else grub_machine_mmap_iterate (heap_init); } +#endif -static grub_uint64_t ieee1275_get_time_ms (void); - -void -grub_machine_init (void) +static void +grub_parse_cmdline (void) { - char args[256]; grub_ssize_t actual; + char args[256]; - grub_ieee1275_init (); - - grub_console_init_early (); - grub_claim_heap (); - grub_console_init_lately (); - grub_ofdisk_init (); - - /* Process commandline. */ if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args, sizeof args, &actual) == 0 && actual > 1) @@ -257,6 +242,21 @@ grub_machine_init (void) } } } +} + +static grub_uint64_t ieee1275_get_time_ms (void); + +void +grub_machine_init (void) +{ + grub_ieee1275_init (); + + grub_console_init_early (); + grub_claim_heap (); + grub_console_init_lately (); + grub_ofdisk_init (); + + grub_parse_cmdline (); grub_install_get_time_ms (ieee1275_get_time_ms); } diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index db4bec90a..8fc373c55 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -369,6 +369,11 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) ret = grub_strdup (args); else ret = grub_strndup (args, (grub_size_t)(comma - args)); + /* Consistently provide numbered partitions to GRUB. + OpenBOOT traditionally uses alphabetical partition + specifiers. */ + if (ret[0] >= 'a' && ret[0] <= 'z') + ret[0] = '1' + (ret[0] - 'a'); } } diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index cc9758988..4818d6af3 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -129,27 +129,74 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)), return grub_strdup (val); } -/* Set the root device according to the dl prefix. */ static void -grub_set_root_dev (void) +grub_set_prefix_and_root (void) { - const char *prefix; + char *device = NULL; + char *path = NULL; + char *fwdevice = NULL; + char *fwpath = NULL; grub_register_variable_hook ("root", 0, grub_env_write_root); - prefix = grub_env_get ("prefix"); + { + char *pptr = NULL; + if (grub_prefix[0] == '(') + { + pptr = grub_strrchr (grub_prefix, ')'); + if (pptr) + { + device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = grub_prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } + if ((!device || device[0] == ',' || !device[0]) || !path) + grub_machine_get_bootlocation (&fwdevice, &fwpath); - if (prefix) + if (!device && fwdevice) + device = fwdevice; + else if (fwdevice && (device[0] == ',' || !device[0])) { - char *dev; + /* We have a partition, but still need to fill in the drive. */ + char *comma, *new_device; - dev = grub_file_get_device_name (prefix); - if (dev) + comma = grub_strchr (fwdevice, ','); + if (comma) { - grub_env_set ("root", dev); - grub_free (dev); + char *drive = grub_strndup (fwdevice, comma - fwdevice); + new_device = grub_xasprintf ("%s%s", drive, device); + grub_free (drive); } + else + new_device = grub_xasprintf ("%s%s", fwdevice, device); + + grub_free (fwdevice); + grub_free (device); + device = new_device; } + if (fwpath && !path) + path = fwpath; + if (device) + { + char *prefix; + + prefix = grub_xasprintf ("(%s)%s", device, path ? : ""); + if (prefix) + { + grub_env_set ("prefix", prefix); + grub_free (prefix); + } + grub_env_set ("root", device); + } + + grub_free (device); + grub_free (path); + grub_print_error (); } /* Load the normal mode module and execute the normal mode if possible. */ @@ -187,8 +234,7 @@ grub_main (void) /* It is better to set the root device as soon as possible, for convenience. */ - grub_machine_set_prefix (); - grub_set_root_dev (); + grub_set_prefix_and_root (); grub_env_export ("root"); grub_env_export ("prefix"); diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c index bfa08f56a..353f679e6 100644 --- a/grub-core/kern/mips/init.c +++ b/grub-core/kern/mips/init.c @@ -38,7 +38,7 @@ grub_get_rtc (void) } void -grub_machine_set_prefix (void) +grub_machine_get_bootlocation (char **device __attribute__ ((unused)), + char **path __attribute__ ((unused))) { - grub_env_set ("prefix", grub_prefix); } diff --git a/grub-core/kern/sparc64/ieee1275/init.c b/grub-core/kern/sparc64/ieee1275/init.c deleted file mode 100644 index 72ee1f136..000000000 --- a/grub-core/kern/sparc64/ieee1275/init.c +++ /dev/null @@ -1,174 +0,0 @@ -/* init.c -- Initialize GRUB on SPARC64. */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_addr_t grub_ieee1275_original_stack; - -void -grub_exit (void) -{ - grub_ieee1275_exit (); -} - -static grub_uint64_t -ieee1275_get_time_ms (void) -{ - grub_uint32_t msecs = 0; - - grub_ieee1275_milliseconds (&msecs); - - return msecs; -} - -grub_uint32_t -grub_get_rtc (void) -{ - return ieee1275_get_time_ms (); -} - -grub_addr_t -grub_arch_modules_addr (void) -{ - extern char _end[]; - return (grub_addr_t) _end; -} - -void -grub_machine_set_prefix (void) -{ - if (grub_prefix[0] != '(') - { - char bootpath[IEEE1275_MAX_PATH_LEN]; - char *prefix, *path, *colon; - grub_ssize_t actual; - - if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", - &bootpath, sizeof (bootpath), &actual)) - { - /* Should never happen. */ - grub_printf ("/chosen/bootpath property missing!\n"); - grub_env_set ("prefix", ""); - return; - } - - /* Transform an OF device path to a GRUB path. */ - colon = grub_strchr (bootpath, ':'); - if (colon) - { - char *part = colon + 1; - - /* Consistently provide numbered partitions to GRUB. - OpenBOOT traditionally uses alphabetical partition - specifiers. */ - if (part[0] >= 'a' && part[0] <= 'z') - part[0] = '1' + (part[0] - 'a'); - } - prefix = grub_ieee1275_encode_devname (bootpath); - - path = grub_xasprintf("%s%s", prefix, grub_prefix); - - grub_strcpy (grub_prefix, path); - - grub_free (path); - grub_free (prefix); - } - - grub_env_set ("prefix", grub_prefix); -} - -static void -grub_heap_init (void) -{ - grub_mm_init_region ((void *) (grub_modules_get_end () - + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); -} - -static void -grub_parse_cmdline (void) -{ - grub_ssize_t actual; - char args[256]; - - if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args, - sizeof args, &actual) == 0 - && actual > 1) - { - int i = 0; - - while (i < actual) - { - char *command = &args[i]; - char *end; - char *val; - - end = grub_strchr (command, ';'); - if (end == 0) - i = actual; /* No more commands after this one. */ - else - { - *end = '\0'; - i += end - command + 1; - while (grub_isspace(args[i])) - i++; - } - - /* Process command. */ - val = grub_strchr (command, '='); - if (val) - { - *val = '\0'; - grub_env_set (command, val + 1); - } - } - } -} - -void -grub_machine_init (void) -{ - grub_ieee1275_init (); - grub_console_init_early (); - grub_heap_init (); - grub_console_init_lately (); - - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); - grub_ofdisk_init (); - - grub_parse_cmdline (); - grub_install_get_time_ms (ieee1275_get_time_ms); -} - -void -grub_machine_fini (void) -{ - grub_ofdisk_fini (); - grub_console_fini (); -} diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 2ecc73df4..6a5f91c3d 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -84,12 +84,13 @@ void grub_machine_init (void); void EXPORT_FUNC(grub_machine_fini) (void); /* The machine-specific prefix initialization. */ -void grub_machine_set_prefix (void); +void +grub_machine_get_bootlocation (char **device, char **path); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); -#if ! defined (ASM_FILE) && !defined (GRUB_MACHINE_EMU) +#if ! defined (ASM_FILE) extern char grub_prefix[]; #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index af724096d..c04961fc6 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -169,8 +169,10 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 #define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x0 #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN 0x1 #define GRUB_KERNEL_MIPS_LOONGSON_MOD_ALIGN 0x1 #define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x1 @@ -179,7 +181,7 @@ /* 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 rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 +#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x8000 #ifdef GRUB_MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c From cae730b4526f250a3d5073c00911e35b7abdd7d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 16:56:35 +0200 Subject: [PATCH 1131/1414] Automatically determine prefix when netbooted on EFI --- grub-core/disk/efi/efidisk.c | 153 ++++++++--------------------- grub-core/kern/efi/efi.c | 48 +++++++++ grub-core/kern/efi/init.c | 6 ++ grub-core/net/drivers/efi/efinet.c | 49 ++++++++- grub-core/net/net.c | 53 ++++++++-- include/grub/efi/api.h | 35 +++++++ include/grub/efi/efi.h | 8 ++ include/grub/net.h | 8 +- 8 files changed, 237 insertions(+), 123 deletions(-) diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 5dc753046..07f0f6859 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -84,54 +84,6 @@ find_last_device_path (const grub_efi_device_path_t *dp) return p; } -/* Compare device paths. */ -static int -compare_device_paths (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2) -{ - if (! dp1 || ! dp2) - /* Return non-zero. */ - return 1; - - while (1) - { - grub_efi_uint8_t type1, type2; - grub_efi_uint8_t subtype1, subtype2; - grub_efi_uint16_t len1, len2; - int ret; - - type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1); - type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); - - if (type1 != type2) - return (int) type2 - (int) type1; - - subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1); - subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); - - if (subtype1 != subtype2) - return (int) subtype1 - (int) subtype2; - - len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1); - len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); - - if (len1 != len2) - return (int) len1 - (int) len2; - - ret = grub_memcmp (dp1, dp2, len1); - if (ret != 0) - return ret; - - if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1)) - break; - - dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1); - dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); - } - - return 0; -} - static struct grub_efidisk_data * make_devices (void) { @@ -214,7 +166,7 @@ find_parent_device (struct grub_efidisk_data *devices, if (parent == d) continue; - if (compare_device_paths (parent->device_path, dp) == 0) + if (grub_efi_compare_device_paths (parent->device_path, dp) == 0) { /* Found. */ if (! parent->last_device_path) @@ -249,7 +201,7 @@ iterate_child_devices (struct grub_efidisk_data *devices, ldp->length[0] = sizeof (*ldp); ldp->length[1] = 0; - if (compare_device_paths (dp, d->device_path) == 0) + if (grub_efi_compare_device_paths (dp, d->device_path) == 0) if (hook (p)) { grub_free (dp); @@ -273,11 +225,11 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d) { int ret; - ret = compare_device_paths (find_last_device_path ((*p)->device_path), - find_last_device_path (d->device_path)); + ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path), + find_last_device_path (d->device_path)); if (ret == 0) - ret = compare_device_paths ((*p)->device_path, - d->device_path); + ret = grub_efi_compare_device_paths ((*p)->device_path, + d->device_path); if (ret == 0) return; else if (ret > 0) @@ -706,7 +658,35 @@ grub_efidisk_get_device_handle (grub_disk_t disk) char * grub_efidisk_get_device_name (grub_efi_handle_t *handle) { - grub_efi_device_path_t *dp, *ldp; + grub_efi_device_path_t *dp, *ldp, *sdp; + /* This is a hard disk partition. */ + grub_disk_t parent = 0; + auto int find_parent_disk (const char *name); + + /* Find the disk which is the parent of a given hard disk partition. */ + int find_parent_disk (const char *name) + { + grub_disk_t disk; + + disk = grub_disk_open (name); + if (! disk) + return 1; + + if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID) + { + struct grub_efidisk_data *d; + + d = disk->data; + if (grub_efi_compare_device_paths (d->device_path, sdp) == 0) + { + parent = disk; + return 1; + } + } + + grub_disk_close (disk); + return 0; + } dp = grub_efi_get_device_path (handle); if (! dp) @@ -720,40 +700,12 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) { - /* This is a hard disk partition. */ - grub_disk_t parent = 0; grub_partition_t tpart = NULL; char *device_name; grub_efi_device_path_t *dup_dp, *dup_ldp; grub_efi_hard_drive_device_path_t hd; - auto int find_parent_disk (const char *name); auto int find_partition (grub_disk_t disk, const grub_partition_t part); - /* Find the disk which is the parent of a given hard disk partition. */ - int find_parent_disk (const char *name) - { - grub_disk_t disk; - - disk = grub_disk_open (name); - if (! disk) - return 1; - - if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID) - { - struct grub_efidisk_data *d; - - d = disk->data; - if (compare_device_paths (d->device_path, dup_dp) == 0) - { - parent = disk; - return 1; - } - } - - grub_disk_close (disk); - return 0; - } - /* Find the identical partition. */ int find_partition (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t part) @@ -780,6 +732,8 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) dup_ldp->length[0] = sizeof (*dup_ldp); dup_ldp->length[1] = 0; + sdp = dup_dp; + grub_efidisk_iterate (find_parent_disk); grub_free (dup_dp); @@ -816,36 +770,15 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) else { /* This should be an entire disk. */ - auto int find_disk (const char *name); char *device_name = 0; - int find_disk (const char *name) - { - grub_disk_t disk; + sdp = dp; - disk = grub_disk_open (name); - if (! disk) - return 1; - - if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID) - { - struct grub_efidisk_data *d; - - d = disk->data; - if (compare_device_paths (d->device_path, dp) == 0) - { - device_name = grub_strdup (disk->name); - grub_disk_close (disk); - return 1; - } - } - - grub_disk_close (disk); - return 0; - - } - - grub_efidisk_iterate (find_disk); + grub_efidisk_iterate (find_parent_disk); + if (!parent) + return NULL; + device_name = grub_strdup (parent->name); + grub_disk_close (parent); return device_name; } diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index c95058733..d0994a940 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -746,3 +746,51 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) dp = (grub_efi_device_path_t *) ((char *) dp + len); } } + +/* Compare device paths. */ +int +grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2) +{ + if (! dp1 || ! dp2) + /* Return non-zero. */ + return 1; + + while (1) + { + grub_efi_uint8_t type1, type2; + grub_efi_uint8_t subtype1, subtype2; + grub_efi_uint16_t len1, len2; + int ret; + + type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1); + type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); + + if (type1 != type2) + return (int) type2 - (int) type1; + + subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1); + subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); + + if (subtype1 != subtype2) + return (int) subtype1 - (int) subtype2; + + len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1); + len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); + + if (len1 != len2) + return (int) len1 - (int) len2; + + ret = grub_memcmp (dp1, dp2, len1); + if (ret != 0) + return ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1)) + break; + + dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1); + dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); + } + + return 0; +} diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index a7325acc6..4dfb06284 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -42,6 +42,10 @@ grub_efi_init (void) grub_efidisk_init (); } +void (*grub_efi_net_config) (grub_efi_handle_t hnd, + char **device, + char **path); + void grub_machine_get_bootlocation (char **device, char **path) { @@ -53,6 +57,8 @@ grub_machine_get_bootlocation (char **device, char **path) return; *device = grub_efidisk_get_device_name (image->device_handle); *path = grub_efi_get_filename (image->file_path); + if (!*device && grub_efi_net_config) + grub_efi_net_config (image->device_handle, device, path); /* Get the directory. */ p = grub_strrchr (*path, '/'); diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index a6e005601..29bc66183 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -27,14 +27,14 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* GUID. */ static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; - +static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; static grub_err_t send_card_buffer (const struct grub_net_card *dev, struct grub_net_buff *pack) { grub_efi_status_t st; - grub_efi_simple_network_t *net = dev->data; + grub_efi_simple_network_t *net = dev->efi_net; st = efi_call_7 (net->transmit, net, 0, pack->tail - pack->data, pack->data, NULL, NULL, NULL); if (st != GRUB_EFI_SUCCESS) @@ -46,7 +46,7 @@ static grub_ssize_t get_card_packet (const struct grub_net_card *dev, struct grub_net_buff *nb) { - grub_efi_simple_network_t *net = dev->data; + grub_efi_simple_network_t *net = dev->efi_net; grub_err_t err; grub_efi_status_t st; grub_efi_uintn_t bufsize = 1500; @@ -139,21 +139,62 @@ grub_efinet_findcards (void) grub_memcpy (card->default_address.mac, net->mode->current_address, sizeof (card->default_address.mac)); - card->data = net; + card->efi_net = net; + card->efi_handle = *handle; grub_net_card_register (card); } grub_free (handles); } +static void +grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, + char **path) +{ + struct grub_net_card *card; + grub_efi_device_path_t *dp; + + dp = grub_efi_get_device_path (hnd); + if (! dp) + return; + + FOR_NET_CARDS (card) + { + grub_efi_device_path_t *cdp; + struct grub_efi_pxe *pxe; + struct grub_efi_pxe_mode *pxe_mode; + if (card->driver != &efidriver) + continue; + cdp = grub_efi_get_device_path (card->efi_handle); + if (! cdp) + continue; + if (grub_efi_compare_device_paths (dp, cdp) != 0) + continue; + pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (! pxe) + continue; + pxe_mode = pxe->mode; + grub_net_configure_by_dhcp_ack (card->name, card, 0, + (struct grub_net_bootp_packet *) + &pxe_mode->dhcp_ack, + sizeof (pxe_mode->dhcp_ack), + 1, device, path); + return; + } +} + + GRUB_MOD_INIT(efinet) { grub_efinet_findcards (); + grub_efi_net_config = grub_efi_net_config_real; } GRUB_MOD_FINI(ofnet) { struct grub_net_card *card; + grub_efi_net_config = 0; FOR_NET_CARDS (card) if (card->driver && !grub_strcmp (card->driver->name, "efinet")) { diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 34148f52c..2ecb709b9 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -936,7 +936,8 @@ grub_net_configure_by_dhcp_ack (const char *name, const struct grub_net_card *card, grub_net_interface_flags_t flags, const struct grub_net_bootp_packet *bp, - grub_size_t size) + grub_size_t size, + int is_def, char **device, char **path) { grub_net_network_level_address_t addr; grub_net_link_level_address_t hwaddr; @@ -945,6 +946,11 @@ grub_net_configure_by_dhcp_ack (const char *name, addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bp->your_ip; + if (device) + *device = 0; + if (path) + *path = 0; + grub_memcpy (hwaddr.mac, bp->mac_addr, bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len : sizeof (hwaddr.mac)); @@ -975,26 +981,57 @@ grub_net_configure_by_dhcp_ack (const char *name, if (size > OFFSET_OF (boot_file, bp)) set_env_limn_ro (name, "boot_file", (char *) bp->boot_file, sizeof (bp->boot_file)); + if (is_def) + default_server = 0; if (size > OFFSET_OF (server_name, bp) && bp->server_name[0]) { set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, sizeof (bp->server_name)); - if (!default_server) + if (is_def && !default_server) { default_server = grub_strdup (bp->server_name); - grub_errno = GRUB_ERR_NONE; - } + grub_print_error (); + } + if (device && !*device) + { + *device = grub_xasprintf ("tftp,%s", bp->server_name); + grub_print_error (); + } } - if (!default_server) + if (is_def && !default_server) { default_server = grub_xasprintf ("%d.%d.%d.%d", ((grub_uint8_t *) &bp->server_ip)[0], ((grub_uint8_t *) &bp->server_ip)[1], ((grub_uint8_t *) &bp->server_ip)[2], ((grub_uint8_t *) &bp->server_ip)[3]); - grub_errno = GRUB_ERR_NONE; - } + grub_print_error (); + } + + if (device && !*device) + { + *device = grub_xasprintf ("tftp,%d.%d.%d.%d", + ((grub_uint8_t *) &bp->server_ip)[0], + ((grub_uint8_t *) &bp->server_ip)[1], + ((grub_uint8_t *) &bp->server_ip)[2], + ((grub_uint8_t *) &bp->server_ip)[3]); + grub_print_error (); + } + if (size > OFFSET_OF (boot_file, bp) && path) + { + *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); + grub_print_error (); + if (*path) + { + char *slash; + slash = grub_strrchr (*path, '/'); + if (slash) + *slash = 0; + else + **path = 0; + } + } if (size > OFFSET_OF (vendor, bp)) parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp)); @@ -1025,7 +1062,7 @@ grub_net_process_dhcp (struct grub_net_buff *nb, } grub_net_configure_by_dhcp_ack (name, card, 0, (const struct grub_net_bootp_packet *) nb->data, - (nb->tail - nb->data)); + (nb->tail - nb->data), 0, 0, 0); grub_free (name); if (grub_errno) grub_print_error (); diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index a3dde0eff..5cd1686ea 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -89,6 +89,11 @@ { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } +#define GRUB_EFI_PXE_GUID \ + { 0x03c4e603, 0xac28, 0x11d3, \ + { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + #define GRUB_EFI_DEVICE_PATH_GUID \ { 0x09576e91, 0x6d3f, 0x11d2, \ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ @@ -1118,6 +1123,36 @@ struct grub_efi_simple_text_output_interface }; typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; +typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; + +typedef struct grub_efi_pxe_mode +{ + grub_uint8_t unused[52]; + grub_efi_pxe_packet_t dhcp_discover; + grub_efi_pxe_packet_t dhcp_ack; + grub_efi_pxe_packet_t proxy_offer; + grub_efi_pxe_packet_t pxe_discover; + grub_efi_pxe_packet_t pxe_reply; +} grub_efi_pxe_mode_t; + +typedef struct grub_efi_pxe +{ + grub_uint64_t rev; + void (*start) (void); + void (*stop) (void); + void (*dhcp) (void); + void (*discover) (void); + void (*mftp) (void); + void (*udpwrite) (void); + void (*udpread) (void); + void (*setipfilter) (void); + void (*arp) (void); + void (*setparams) (void); + void (*setstationip) (void); + void (*setpackets) (void); + struct grub_efi_pxe_mode *mode; +} grub_efi_pxe_t; + #define GRUB_EFI_BLACK 0x00 #define GRUB_EFI_BLUE 0x01 #define GRUB_EFI_GREEN 0x02 diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index e9c57dd11..e98f99507 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -62,6 +62,14 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo grub_efi_uint32_t descriptor_version, grub_efi_memory_descriptor_t *virtual_map); +int +EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2); + +extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, + char **device, + char **path); + void grub_efi_mm_init (void); void grub_efi_mm_fini (void); void grub_efi_init (void); diff --git a/include/grub/net.h b/include/grub/net.h index ee94ebcc6..6aaf391d5 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -109,6 +109,11 @@ struct grub_net_card grub_net_card_flags_t flags; union { + struct + { + struct grub_efi_simple_network *efi_net; + void *efi_handle; + }; void *data; int data_num; }; @@ -404,7 +409,8 @@ grub_net_configure_by_dhcp_ack (const char *name, const struct grub_net_card *card, grub_net_interface_flags_t flags, const struct grub_net_bootp_packet *bp, - grub_size_t size); + grub_size_t size, + int is_def, char **device, char **path); void grub_net_process_dhcp (struct grub_net_buff *nb, From 6708faafdea4e3b27879e089e772babb78bfe7f2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 17:58:23 +0200 Subject: [PATCH 1132/1414] Fix broken blksize negotiation, fix broken seek and change a way net device is filled n i386-pc --- grub-core/kern/file.c | 4 -- grub-core/kern/i386/pc/init.c | 8 ++-- grub-core/net/drivers/i386/pc/pxe.c | 73 +++++++++++++++++++++++------ grub-core/net/net.c | 28 +++++++---- grub-core/net/tftp.c | 26 +++++++--- include/grub/i386/pc/kernel.h | 2 + include/grub/net.h | 2 +- include/grub/net/tftp.h | 6 --- 8 files changed, 105 insertions(+), 44 deletions(-) diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c index 2407e72c5..f69ef6fd4 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -25,7 +25,6 @@ #include #include -grub_err_t (*grub_file_net_seek) (struct grub_file *file, grub_off_t offset) = NULL; void (*EXPORT_VAR (grub_grubnet_fini)) (void); grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX]; @@ -183,9 +182,6 @@ grub_file_seek (grub_file_t file, grub_off_t offset) return -1; } - if (file->device->net && grub_file_net_seek) - grub_file_net_seek (file, offset); - old = file->offset; file->offset = offset; diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 3aedaf6d8..24fe8fed9 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -45,9 +45,10 @@ struct mem_region static struct mem_region mem_regions[MAX_REGIONS]; static int num_regions; +void (*grub_pc_net_config) (char **device, char **path); + void -grub_machine_get_bootlocation (char **device, - char **path __attribute__ ((unused))) +grub_machine_get_bootlocation (char **device, char **path) { char *ptr; @@ -55,7 +56,8 @@ grub_machine_get_bootlocation (char **device, partition number encoded at the install time. */ if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL) { - *device = grub_strdup ("pxe"); + if (grub_pc_net_config) + grub_pc_net_config (device, path); return; } diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 144df964c..51f4023a6 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -45,6 +46,22 @@ struct grub_pxe_undi_open grub_uint8_t mcast[8][6]; } __attribute__ ((packed)); +struct grub_pxe_undi_info +{ + grub_uint16_t status; + grub_uint16_t base_io; + grub_uint16_t int_number; + grub_uint16_t mtu; + grub_uint16_t hwtype; + grub_uint16_t hwaddrlen; + grub_uint8_t current_addr[16]; + grub_uint8_t permanent_addr[16]; + grub_uint32_t romaddr; + grub_uint16_t rxbufct; + grub_uint16_t txbufct; +} __attribute__ ((packed)); + + struct grub_pxe_undi_isr { grub_uint16_t status; @@ -259,7 +276,7 @@ struct grub_net_card grub_pxe_card = void grub_pxe_unload (void) { - if (grub_pxe_pxenv) + if (pxe_rm_entry) { grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, @@ -269,17 +286,11 @@ grub_pxe_unload (void) } } -GRUB_MOD_INIT(pxe) +static void +grub_pc_net_config_real (char **device, char **path) { - struct grub_pxe_bangpxe *pxenv; - struct grub_pxenv_get_cached_info ci; struct grub_net_bootp_packet *bp; - struct grub_pxe_undi_open *ou; - - pxenv = grub_pxe_scan (); - if (! pxenv) - return; - + struct grub_pxenv_get_cached_info ci; ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK; ci.buffer = 0; ci.buffer_size = 0; @@ -289,9 +300,41 @@ GRUB_MOD_INIT(pxe) bp = LINEAR (ci.buffer); - grub_memcpy (grub_pxe_card.default_address.mac, bp->mac_addr, - bp->hw_len < sizeof (grub_pxe_card.default_address.mac) - ? bp->hw_len : sizeof (grub_pxe_card.default_address.mac)); + grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, + bp, GRUB_PXE_BOOTP_SIZE, + 1, device, path); +} + +GRUB_MOD_INIT(pxe) +{ + struct grub_pxe_bangpxe *pxenv; + struct grub_pxe_undi_open *ou; + struct grub_pxe_undi_info *ui; + unsigned i; + + pxenv = grub_pxe_scan (); + if (! pxenv) + return; + + ui = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (ui, 0, sizeof (*ui)); + grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry); + + grub_memcpy (grub_pxe_card.default_address.mac, ui->current_addr, + sizeof (grub_pxe_card.default_address.mac)); + for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) + if (grub_pxe_card.default_address.mac[i] != 0) + break; + if (i != sizeof (grub_pxe_card.default_address.mac)) + { + for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) + if (grub_pxe_card.default_address.mac[i] != 0xff) + break; + } + if (i == sizeof (grub_pxe_card.default_address.mac)) + grub_memcpy (grub_pxe_card.default_address.mac, ui->permanent_addr, + sizeof (grub_pxe_card.default_address.mac)); + grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; @@ -303,11 +346,11 @@ GRUB_MOD_INIT(pxe) return; grub_net_card_register (&grub_pxe_card); - grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, - bp, GRUB_PXE_BOOTP_SIZE); + grub_pc_net_config = grub_pc_net_config_real; } GRUB_MOD_FINI(pxe) { + grub_pc_net_config = 0; grub_pxe_unload (); } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 2ecb709b9..a56860eed 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -664,6 +664,7 @@ grub_net_open_real (const char *name) else ret->server = NULL; ret->fs = &grub_net_fs; + ret->offset = 0; return ret; } } @@ -784,7 +785,7 @@ grub_net_poll_cards (unsigned time) /* Read from the packets list*/ static grub_ssize_t -grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) +grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) { grub_net_socket_t sock = file->device->net->socket; struct grub_net_buff *nb; @@ -802,6 +803,7 @@ grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) amount = len; len -= amount; total += amount; + file->device->net->offset += amount; if (buf) { grub_memcpy (ptr, nb->data, amount); @@ -829,28 +831,40 @@ grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) return total; } -/* Read from the packets list*/ static grub_err_t grub_net_seek_real (struct grub_file *file, grub_off_t offset) { grub_net_socket_t sock = file->device->net->socket; struct grub_net_buff *nb; - grub_size_t len = offset - file->offset; + grub_size_t len = offset - file->device->net->offset; if (!len) return GRUB_ERR_NONE; /* We cant seek backwards past the current packet. */ - if (file->offset > offset) + if (file->device->net->offset > offset) { nb = sock->packs.first->nb; - return grub_netbuff_push (nb, file->offset - offset); + return grub_netbuff_push (nb, file->device->net->offset - offset); } - grub_net_fs_read (file, NULL, len); + grub_net_fs_read_real (file, NULL, len); return GRUB_ERR_NONE; } +static grub_ssize_t +grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) +{ + if (file->offset != file->device->net->offset) + { + grub_err_t err; + err = grub_net_seek_real (file, file->offset); + if (err) + return err; + } + return grub_net_fs_read_real (file, buf, len); +} + static char * grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), const char *val __attribute__ ((unused))) @@ -1384,7 +1398,6 @@ GRUB_MOD_INIT(net) grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; - grub_file_net_seek = grub_net_seek_real; grub_grubnet_fini = grub_grubnet_fini_real; } @@ -1400,6 +1413,5 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; - grub_file_net_seek = NULL; grub_grubnet_fini = NULL; } diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 24f30eb7a..b112f643e 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -11,6 +11,13 @@ GRUB_MOD_LICENSE ("GPLv3+"); +typedef struct tftp_data +{ + grub_uint64_t file_size; + grub_uint64_t block; + grub_uint32_t block_size; +} *tftp_data_t; + static grub_err_t tftp_open (struct grub_file *file, const char *filename) { @@ -85,9 +92,9 @@ tftp_open (struct grub_file *file, const char *filename) if (file->device->net->socket->status != 0) break; /* Retry. */ - /*err = grub_net_send_udp_packet (file->device->net->socket, &nb); - if (err) - return err; */ + err = grub_net_send_udp_packet (file->device->net->socket, &nb); + if (err) + return err; } if (file->device->net->socket->status == 0) @@ -110,11 +117,11 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) nb_ack.head = nbdata; nb_ack.end = nbdata + sizeof (nbdata); - tftph = (struct tftphdr *) nb->data; switch (grub_be_to_cpu16 (tftph->opcode)) { case TFTP_OACK: + data->block_size = 512; for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) { if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) @@ -122,6 +129,11 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) data->file_size = grub_strtoul (ptr + sizeof ("tsize\0") - 1, 0, 0); } + if (grub_memcmp (ptr, "blksize\0", sizeof ("blksize\0") - 1) == 0) + { + data->block_size = grub_strtoul (ptr + sizeof ("blksize\0") - 1, + 0, 0); + } while (ptr < nb->tail && *ptr) ptr++; ptr++; @@ -139,12 +151,12 @@ tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) { data->block++; unsigned size = nb->tail - nb->data; - if (size < 1024) + if (size < data->block_size) sock->status = 2; /* Prevent garbage in broken cards. */ - if (size > 1024) + if (size > data->block_size) { - err = grub_netbuff_unput (nb, size - 1024); + err = grub_netbuff_unput (nb, size - data->block_size); if (err) return err; } diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 1de37a5d5..dd50aa833 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -44,6 +44,8 @@ extern grub_int32_t grub_install_bsd_part; /* The boot BIOS drive number. */ extern grub_uint8_t EXPORT_VAR(grub_boot_drive); +extern void (*EXPORT_VAR(grub_pc_net_config)) (char **device, char **path); + #endif /* ! ASM_FILE */ #endif /* ! KERNEL_MACHINE_HEADER */ diff --git a/include/grub/net.h b/include/grub/net.h index 6aaf391d5..494826625 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -242,11 +242,11 @@ typedef struct grub_net char *server; grub_net_app_level_t protocol; grub_net_socket_t socket; + grub_off_t offset; grub_fs_t fs; } *grub_net_t; extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); -extern grub_err_t (*EXPORT_VAR (grub_file_net_seek)) (struct grub_file *file, grub_off_t offset); extern void (*EXPORT_VAR (grub_grubnet_fini)) (void); struct grub_net_network_level_interface diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h index c67380817..0d8cbd1de 100644 --- a/include/grub/net/tftp.h +++ b/include/grub/net/tftp.h @@ -43,12 +43,6 @@ /* * own here because this is cleaner, and maps to the same data layout. * */ -typedef struct tftp_data - { - int file_size; - int block; - } *tftp_data_t; - struct tftphdr { grub_uint16_t opcode; From cbe20661f64d0820c3768ec1fe319436be192f22 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 18:05:40 +0200 Subject: [PATCH 1133/1414] minor stylistic cleanup --- grub-core/net/tftp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index b112f643e..700f0effd 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -75,7 +75,8 @@ tftp_open (struct grub_file *file, const char *filename) rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; - if ((err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen))) != GRUB_ERR_NONE) + err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); + if (err) return err; file->device->net->socket->out_port = TFTP_SERVER_PORT; From 0c51bb63c5ef4555dab8aeedcaed309160111cd7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 18:57:24 +0200 Subject: [PATCH 1134/1414] add missing brackets in efi_wrap macroses --- include/grub/efi/api.h | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 5cd1686ea..b20baa015 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -1359,27 +1359,31 @@ typedef struct grub_efi_block_io grub_efi_block_io_t; #define efi_call_0(func) \ efi_wrap_0(func) #define efi_call_1(func, a) \ - efi_wrap_1(func, (grub_uint64_t) a) + efi_wrap_1(func, (grub_uint64_t) (a)) #define efi_call_2(func, a, b) \ - efi_wrap_2(func, (grub_uint64_t) a, (grub_uint64_t) b) + efi_wrap_2(func, (grub_uint64_t) (a), (grub_uint64_t) (b)) #define efi_call_3(func, a, b, c) \ - efi_wrap_3(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c) + efi_wrap_3(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c)) #define efi_call_4(func, a, b, c, d) \ - efi_wrap_4(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ - (grub_uint64_t) d) + efi_wrap_4(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d)) #define efi_call_5(func, a, b, c, d, e) \ - efi_wrap_5(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ - (grub_uint64_t) d, (grub_uint64_t) e) + efi_wrap_5(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e)) #define efi_call_6(func, a, b, c, d, e, f) \ - efi_wrap_6(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ - (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f) + efi_wrap_6(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f)) #define efi_call_7(func, a, b, c, d, e, f, g) \ - efi_wrap_7(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ - (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g) + efi_wrap_7(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f), (grub_uint64_t) (g)) #define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \ - efi_wrap_10(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ - (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g, \ - (grub_uint64_t) h, (grub_uint64_t) i, (grub_uint64_t) j) + efi_wrap_10(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f), (grub_uint64_t) (g), (grub_uint64_t) (h), \ + (grub_uint64_t) (i), (grub_uint64_t) (j)) grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); From c4d038f632e39faba9506122af29d926cff9267e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 20:11:29 +0200 Subject: [PATCH 1135/1414] Don't react to adressed bootp packets unless in bootp transaction --- grub-core/kern/emu/main.c | 10 +++++--- grub-core/net/ip.c | 51 +++++++++++++++++++-------------------- grub-core/net/net.c | 12 ++++----- grub-core/net/udp.c | 7 +++--- include/grub/net.h | 2 +- 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 096e97090..2092d03cb 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -49,7 +49,7 @@ static jmp_buf main_env; /* Store the prefix specified by an argument. */ -static char *root_dev = NULL, *dir = DEFAULT_DIRECTORY; +static char *root_dev = NULL, *dir = NULL; int grub_no_autoload; @@ -139,14 +139,18 @@ main (int argc, char *argv[]) set_program_name (argv[0]); + dir = xstrdup (DEFAULT_DIRECTORY); + while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1) switch (opt) { case 'r': - root_dev = optarg; + free (root_dev); + root_dev = xstrdup (optarg); break; case 'd': - dir = optarg; + free (dir); + dir = xstrdup (optarg); break; case 'm': dev_map = optarg; diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 776937a6e..8b06f7d11 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -65,50 +65,49 @@ grub_net_recv_ip_packets (struct grub_net_buff * nb, { struct iphdr *iph = (struct iphdr *) nb->data; grub_err_t err; - struct grub_net_network_level_interface *inf; + struct grub_net_network_level_interface *inf = NULL; err = grub_netbuff_pull (nb, sizeof (*iph)); if (err) return err; - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + /* DHCP needs special treatment since we don't know IP yet. */ { - if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 - && inf->address.ipv4 == iph->dest - && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) - break; + struct udphdr *udph; + udph = (struct udphdr *) nb->data; + if (iph->protocol == IP_UDP && grub_be_to_cpu16 (udph->dst) == 68) + { + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + if (inf->card == card + && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV + && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) + { + err = grub_netbuff_pull (nb, sizeof (*udph)); + if (err) + return err; + grub_net_process_dhcp (nb, inf->card); + grub_netbuff_free (nb); + } + return GRUB_ERR_NONE; + } } + if (!inf) { FOR_NET_NETWORK_LEVEL_INTERFACES (inf) + { if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC + && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 + && inf->address.ipv4 == iph->dest && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) - break; - } - if (!inf) - { - if (iph->protocol == IP_UDP - && grub_net_hwaddr_cmp (&card->default_address, hwaddress) == 0) - { - struct udphdr *udph; - udph = (struct udphdr *) nb->data; - err = grub_netbuff_pull (nb, sizeof (*udph)); - if (err) - return err; - if (grub_be_to_cpu16 (udph->dst) == 68) - grub_net_process_dhcp (nb, card); - } - grub_netbuff_free (nb); - return GRUB_ERR_NONE; + break; + } } switch (iph->protocol) { case IP_UDP: return grub_net_recv_udp_packet (nb, inf); - break; default: grub_netbuff_free (nb); break; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index a56860eed..d5f9e374e 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -119,7 +119,7 @@ match_net (const grub_net_network_level_netaddress_t *net, return 0; switch (net->type) { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: return 0; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { @@ -238,8 +238,8 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) { switch (target->type) { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: - grub_strcpy (buf, "promisc"); + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: + grub_strcpy (buf, "temporary"); return; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { @@ -521,8 +521,8 @@ print_net_address (const grub_net_network_level_netaddress_t *target) { switch (target->type) { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC: - grub_printf ("promisc\n"); + case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: + grub_printf ("temporary\n"); break; case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: { @@ -1257,7 +1257,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), grub_free (ifaces); return grub_errno; } - ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC; + ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV; grub_memcpy (&ifaces[j].hwaddress, &card->default_address, sizeof (ifaces[j].hwaddress)); j++; diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index 95134c0cf..b9339e49a 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -32,8 +32,11 @@ grub_net_recv_udp_packet (struct grub_net_buff * nb, { struct udphdr *udph; grub_net_socket_t sock; + grub_err_t err; udph = (struct udphdr *) nb->data; - grub_netbuff_pull (nb, sizeof (*udph)); + err = grub_netbuff_pull (nb, sizeof (*udph)); + if (err) + return err; FOR_NET_SOCKETS (sock) { @@ -54,8 +57,6 @@ grub_net_recv_udp_packet (struct grub_net_buff * nb, return GRUB_ERR_NONE; } } - if (grub_be_to_cpu16 (udph->dst) == 68) - grub_net_process_dhcp (nb, inf->card); grub_netbuff_free (nb); return GRUB_ERR_NONE; } diff --git a/include/grub/net.h b/include/grub/net.h index 494826625..630fd33fb 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -123,7 +123,7 @@ struct grub_net_network_level_interface; typedef enum grub_network_level_protocol_id { - GRUB_NET_NETWORK_LEVEL_PROTOCOL_PROMISC, + GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV, GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 } grub_network_level_protocol_id_t; From 77546584e1466b4702a60b83df674ca4337b2627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 2 Jul 2011 21:22:19 +0200 Subject: [PATCH 1136/1414] Use @PACKAGE@ instead of hardcoded name when sourcing grub-mkconfig_lib. --- ChangeLog | 14 ++++++++++++++ util/grub-mkconfig.in | 2 +- util/grub.d/00_header.in | 2 +- util/grub.d/10_hurd.in | 2 +- util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- util/grub.d/10_netbsd.in | 2 +- util/grub.d/10_windows.in | 2 +- util/grub.d/20_linux_xen.in | 2 +- util/grub.d/30_os-prober.in | 2 +- util/update-grub_lib.in | 2 +- 11 files changed, 24 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b8d8f149..e091265d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-07-02 GrĂ©goire Sutre + + * util/grub-mkconfig.in: Use @PACKAGE@ instead of hardcoded name when + sourcing grub-mkconfig_lib. + * util/update-grub_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/10_netbsd.in: Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + * util/grub.d/30_os-prober.in: Likewise. + 2011-06-28 Colin Watson * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 4d627c057..cf94d1065 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -95,7 +95,7 @@ do esac done -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib if [ "x$EUID" = "x" ] ; then EUID=`id -u` diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 9da1511f5..7b8871d4d 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -25,7 +25,7 @@ libdir=@libdir@ locale_dir=`echo ${GRUB_PREFIX}/locale | sed ${transform}` grub_lang=`echo $LANG | cut -d . -f 1` -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib # Do this as early as possible, since other commands might depend on it. # (e.g. the `loadfont' command might need lvm or raid modules) diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 8c54eab97..9ca01f0a8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -20,7 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib CLASS="--class gnu --class os" diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 3600c74f9..2ade4ea35 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 1d1eb403f..97e7c6523 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index ffd31ad93..c257aeb3c 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index fd068dd2d..941267a9f 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -20,7 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib case "`uname 2>/dev/null`" in CYGWIN*) ;; diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 083391c40..c0b255598 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index d9d4b0a96..c0b5d7cd7 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -21,7 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then exit 0 diff --git a/util/update-grub_lib.in b/util/update-grub_lib.in index 998452e67..430ce1308 100644 --- a/util/update-grub_lib.in +++ b/util/update-grub_lib.in @@ -18,6 +18,6 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ -. ${libdir}/grub/grub-mkconfig_lib +. ${libdir}/@PACKAGE@/grub-mkconfig_lib grub_warn "update-grub_lib is deprecated, use grub-mkconfig_lib instead" From 7e0c2d162afd175580074eb7386811e0694aaed3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 2 Jul 2011 22:13:33 +0200 Subject: [PATCH 1137/1414] Restructurisations, cleanups and few bugfixes --- grub-core/net/arp.c | 3 +- grub-core/net/net.c | 94 +++++++---------- grub-core/net/tftp.c | 226 ++++++++++++++++++++++++----------------- grub-core/net/udp.c | 65 +++++++++--- include/grub/net.h | 25 +++-- include/grub/net/udp.h | 16 +++ 6 files changed, 251 insertions(+), 178 deletions(-) diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index fecde3282..d726f2c3a 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -144,7 +144,8 @@ grub_net_arp_receive (struct grub_net_buff *nb) FOR_NET_NETWORK_LEVEL_INTERFACES (inf) { /* Am I the protocol address target? */ - if (grub_memcmp (target_protocol_address, &inf->address.ipv4, 6) == 0 + if (inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 + && grub_memcmp (target_protocol_address, &inf->address.ipv4, 4) == 0 && grub_be_to_cpu16 (arp_header->op) == ARP_REQUEST) { grub_net_link_level_address_t aux; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index d5f9e374e..595379a99 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -630,25 +631,27 @@ grub_net_open_real (const char *name) { protnamelen = comma - name; server = comma + 1; + protname = name; } else { protnamelen = grub_strlen (name); server = default_server; + protname = name; } } if (!server) { grub_error (GRUB_ERR_NET_BAD_ADDRESS, "no server"); return NULL; - } + } FOR_NET_APP_LEVEL (proto) { if (grub_memcmp (proto->name, protname, protnamelen) == 0 && proto->name[protnamelen] == 0) { - grub_net_t ret = grub_malloc (sizeof (*ret)); + grub_net_t ret = grub_zalloc (sizeof (*ret)); if (!ret) return NULL; ret->protocol = proto; @@ -665,6 +668,7 @@ grub_net_open_real (const char *name) ret->server = NULL; ret->fs = &grub_net_fs; ret->offset = 0; + ret->eof = 0; return ret; } } @@ -686,61 +690,26 @@ grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)) static grub_err_t grub_net_fs_open (struct grub_file *file, const char *name) { - grub_err_t err; - grub_net_network_level_address_t addr; - struct grub_net_network_level_interface *inf; - grub_net_network_level_address_t gateway; - grub_net_socket_t socket; - static int port = 25300; - - err = grub_net_resolve_address (file->device->net->server, &addr); - if (err) - return err; - - err = grub_net_route_address (addr, &gateway, &inf); - if (err) - return err; - - socket = (grub_net_socket_t) grub_malloc (sizeof (*socket)); - if (socket == NULL) - return grub_errno; - - socket->inf = inf; - socket->out_nla = addr; - socket->in_port = port++; - socket->status = 0; - socket->app = file->device->net->protocol; - socket->packs.first = NULL; - socket->packs.last = NULL; - file->device->net->socket = socket; - grub_net_socket_register (socket); - - err = file->device->net->protocol->open (file,name); - if (err) - goto fail; - file->not_easily_seekable = 1; - - return GRUB_ERR_NONE; -fail: - grub_net_socket_unregister (socket); - grub_free (socket); - return err; + file->device->net->packs.first = NULL; + file->device->net->packs.last = NULL; + file->device->net->name = grub_strdup (name); + if (!file->device->net->name) + return grub_errno; + return file->device->net->protocol->open (file, name); } static grub_err_t grub_net_fs_close (grub_file_t file) { - grub_net_socket_t sock = file->device->net->socket; - while (sock->packs.first) + while (file->device->net->packs.first) { - grub_netbuff_free (sock->packs.first->nb); - grub_net_remove_packet (sock->packs.first); + grub_netbuff_free (file->device->net->packs.first->nb); + grub_net_remove_packet (file->device->net->packs.first); } - grub_net_socket_unregister (sock); - grub_free (sock); + file->device->net->protocol->close (file); + grub_free (file->device->net->name); return GRUB_ERR_NONE; - } static void @@ -787,9 +756,9 @@ grub_net_poll_cards (unsigned time) static grub_ssize_t grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) { - grub_net_socket_t sock = file->device->net->socket; + grub_net_t sock = file->device->net; struct grub_net_buff *nb; - char *ptr = buf; + char *ptr = buf; grub_size_t amount, total = 0; int try = 0; while (try <= 3) @@ -820,7 +789,7 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) if (!len) return total; } - if (sock->status == 1) + if (!sock->eof) { try++; grub_net_poll_cards (200); @@ -834,18 +803,29 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_net_seek_real (struct grub_file *file, grub_off_t offset) { - grub_net_socket_t sock = file->device->net->socket; - struct grub_net_buff *nb; grub_size_t len = offset - file->device->net->offset; if (!len) return GRUB_ERR_NONE; - /* We cant seek backwards past the current packet. */ if (file->device->net->offset > offset) - { - nb = sock->packs.first->nb; - return grub_netbuff_push (nb, file->device->net->offset - offset); + { + grub_err_t err; + while (file->device->net->packs.first) + { + grub_netbuff_free (file->device->net->packs.first->nb); + grub_net_remove_packet (file->device->net->packs.first); + } + file->device->net->protocol->close (file); + + file->device->net->packs.first = NULL; + file->device->net->packs.last = NULL; + file->device->net->offset = 0; + file->device->net->eof = 0; + err = file->device->net->protocol->open (file, file->device->net->name); + if (err) + return err; + len = offset; } grub_net_fs_read_real (file, NULL, len); diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 700f0effd..6ffe27669 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -16,8 +16,107 @@ typedef struct tftp_data grub_uint64_t file_size; grub_uint64_t block; grub_uint32_t block_size; + int have_oack; + grub_net_socket_t sock; } *tftp_data_t; +static grub_err_t +tftp_receive (grub_net_socket_t sock __attribute__ ((unused)), + struct grub_net_buff *nb, + void *f) +{ + grub_file_t file = f; + struct tftphdr *tftph = (void *) nb->data; + char nbdata[512]; + tftp_data_t data = file->data; + grub_err_t err; + char *ptr; + struct grub_net_buff nb_ack; + + nb_ack.head = nbdata; + nb_ack.end = nbdata + sizeof (nbdata); + + tftph = (struct tftphdr *) nb->data; + switch (grub_be_to_cpu16 (tftph->opcode)) + { + case TFTP_OACK: + data->block_size = 512; + data->have_oack = 1; + for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) + { + if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) + { + data->file_size = grub_strtoul (ptr + sizeof ("tsize\0") - 1, + 0, 0); + } + if (grub_memcmp (ptr, "blksize\0", sizeof ("blksize\0") - 1) == 0) + { + data->block_size = grub_strtoul (ptr + sizeof ("blksize\0") - 1, + 0, 0); + } + while (ptr < nb->tail && *ptr) + ptr++; + ptr++; + } + data->block = 0; + grub_netbuff_free (nb); + break; + case TFTP_DATA: + err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + + sizeof (tftph->u.data.block)); + if (err) + return err; + if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) + { + unsigned size = nb->tail - nb->data; + data->block++; + if (size < data->block_size) + { + file->device->net->eof = 1; + } + /* Prevent garbage in broken cards. */ + if (size > data->block_size) + { + err = grub_netbuff_unput (nb, size - data->block_size); + if (err) + return err; + } + /* If there is data, puts packet in socket list. */ + if ((nb->tail - nb->data) > 0) + grub_net_put_packet (&file->device->net->packs, nb); + else + grub_netbuff_free (nb); + } + else + { + grub_netbuff_free (nb); + return GRUB_ERR_NONE; + } + break; + case TFTP_ERROR: + grub_netbuff_free (nb); + return grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg); + } + grub_netbuff_clear (&nb_ack); + grub_netbuff_reserve (&nb_ack, 512); + err = grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) + + sizeof (tftph->u.ack.block)); + if (err) + return err; + + tftph = (struct tftphdr *) nb_ack.data; + tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); + tftph->u.ack.block = grub_cpu_to_be16 (data->block); + + err = grub_net_send_udp_packet (data->sock, &nb_ack); + if (file->device->net->eof) + { + grub_net_udp_close (data->sock); + data->sock = NULL; + } + return err; +} + static grub_err_t tftp_open (struct grub_file *file, const char *filename) { @@ -31,17 +130,17 @@ tftp_open (struct grub_file *file, const char *filename) tftp_data_t data; grub_err_t err; - data = grub_malloc (sizeof (*data)); + data = grub_zalloc (sizeof (*data)); if (!data) return grub_errno; - file->device->net->socket->data = (void *) data; nb.head = open_data; nb.end = open_data + sizeof (open_data); grub_netbuff_clear (&nb); grub_netbuff_reserve (&nb, 1500); - if ((err = grub_netbuff_push (&nb, sizeof (*tftph))) != GRUB_ERR_NONE) + err = grub_netbuff_push (&nb, sizeof (*tftph)); + if (err) return err; tftph = (struct tftphdr *) nb.data; @@ -78,11 +177,21 @@ tftp_open (struct grub_file *file, const char *filename) err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); if (err) return err; - file->device->net->socket->out_port = TFTP_SERVER_PORT; - err = grub_net_send_udp_packet (file->device->net->socket, &nb); + file->not_easily_seekable = 1; + file->data = data; + data->sock = grub_net_udp_open (file->device->net->server, + TFTP_SERVER_PORT, tftp_receive, + file); + if (!data->sock) + return grub_errno; + + err = grub_net_send_udp_packet (data->sock, &nb); if (err) - return err; + { + grub_net_udp_close (data->sock); + return err; + } /* Receive OACK packet. */ for (i = 0; i < 3; i++) @@ -90,106 +199,34 @@ tftp_open (struct grub_file *file, const char *filename) grub_net_poll_cards (100); if (grub_errno) return grub_errno; - if (file->device->net->socket->status != 0) + if (data->have_oack) break; /* Retry. */ - err = grub_net_send_udp_packet (file->device->net->socket, &nb); + err = grub_net_send_udp_packet (data->sock, &nb); if (err) - return err; + { + grub_net_udp_close (data->sock); + return err; + } } - if (file->device->net->socket->status == 0) - return grub_error (GRUB_ERR_TIMEOUT, "Time out opening tftp."); + if (!data->have_oack) + { + grub_net_udp_close (data->sock); + return grub_error (GRUB_ERR_TIMEOUT, "Time out opening tftp."); + } file->size = data->file_size; return GRUB_ERR_NONE; } static grub_err_t -tftp_receive (grub_net_socket_t sock, struct grub_net_buff *nb) +tftp_close (struct grub_file *file) { - struct tftphdr *tftph; - char nbdata[128]; - tftp_data_t data = sock->data; - grub_err_t err; - char *ptr; - struct grub_net_buff nb_ack; - - nb_ack.head = nbdata; - nb_ack.end = nbdata + sizeof (nbdata); - - tftph = (struct tftphdr *) nb->data; - switch (grub_be_to_cpu16 (tftph->opcode)) - { - case TFTP_OACK: - data->block_size = 512; - for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) - { - if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) - { - data->file_size = grub_strtoul (ptr + sizeof ("tsize\0") - 1, - 0, 0); - } - if (grub_memcmp (ptr, "blksize\0", sizeof ("blksize\0") - 1) == 0) - { - data->block_size = grub_strtoul (ptr + sizeof ("blksize\0") - 1, - 0, 0); - } - while (ptr < nb->tail && *ptr) - ptr++; - ptr++; - } - sock->status = 1; - data->block = 0; - grub_netbuff_clear (nb); - break; - case TFTP_DATA: - err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + - sizeof (tftph->u.data.block)); - if (err) - return err; - if (grub_be_to_cpu16 (tftph->u.data.block) == data->block + 1) - { - data->block++; - unsigned size = nb->tail - nb->data; - if (size < data->block_size) - sock->status = 2; - /* Prevent garbage in broken cards. */ - if (size > data->block_size) - { - err = grub_netbuff_unput (nb, size - data->block_size); - if (err) - return err; - } - } - else - grub_netbuff_clear (nb); - - break; - case TFTP_ERROR: - grub_netbuff_clear (nb); - return grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg); - break; - } - grub_netbuff_clear (&nb_ack); - grub_netbuff_reserve (&nb_ack, 128); - err = grub_netbuff_push (&nb_ack, sizeof (tftph->opcode) - + sizeof (tftph->u.ack.block)); - if (err) - return err; - - tftph = (struct tftphdr *) nb_ack.data; - tftph->opcode = grub_cpu_to_be16 (TFTP_ACK); - tftph->u.ack.block = grub_cpu_to_be16 (data->block); - - err = grub_net_send_udp_packet (sock, &nb_ack); - return err; -} - -static grub_err_t -tftp_close (struct grub_file *file __attribute__ ((unused))) -{ - grub_free (file->device->net->socket->data); + tftp_data_t data = file->data; + if (data->sock) + grub_net_udp_close (data->sock); + grub_free (data); return GRUB_ERR_NONE; } @@ -197,7 +234,6 @@ static struct grub_net_app_protocol grub_tftp_protocol = { .name = "tftp", .open = tftp_open, - .read = tftp_receive, .close = tftp_close }; diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index b9339e49a..47a67a967 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -4,6 +4,46 @@ #include #include +grub_net_socket_t +grub_net_udp_open (char *server, + grub_uint16_t out_port, + grub_err_t (*recv_hook) (grub_net_socket_t sock, + struct grub_net_buff *nb, + void *data), + void *recv_hook_data) +{ + grub_err_t err; + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inf; + grub_net_network_level_address_t gateway; + grub_net_socket_t socket; + static int in_port = 25300; + + err = grub_net_resolve_address (server, &addr); + if (err) + return NULL; + + err = grub_net_route_address (addr, &gateway, &inf); + if (err) + return NULL; + + socket = grub_zalloc (sizeof (*socket)); + if (socket == NULL) + return NULL; + + socket->x_out_port = out_port; + socket->x_inf = inf; + socket->x_out_nla = addr; + socket->x_in_port = in_port++; + socket->x_status = GRUB_NET_SOCKET_START; + socket->recv_hook = recv_hook; + socket->recv_hook_data = recv_hook_data; + + grub_net_socket_register (socket); + + return socket; +} + grub_err_t grub_net_send_udp_packet (const grub_net_socket_t socket, struct grub_net_buff *nb) @@ -16,14 +56,14 @@ grub_net_send_udp_packet (const grub_net_socket_t socket, return err; udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16 (socket->in_port); - udph->dst = grub_cpu_to_be16 (socket->out_port); + udph->src = grub_cpu_to_be16 (socket->x_in_port); + udph->dst = grub_cpu_to_be16 (socket->x_out_port); /* No chechksum. */ udph->chksum = 0; udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - return grub_net_send_ip_packet (socket->inf, &(socket->out_nla), nb); + return grub_net_send_ip_packet (socket->x_inf, &(socket->x_out_nla), nb); } grub_err_t @@ -40,20 +80,17 @@ grub_net_recv_udp_packet (struct grub_net_buff * nb, FOR_NET_SOCKETS (sock) { - if (grub_be_to_cpu16 (udph->dst) == sock->in_port - && inf == sock->inf && sock->app) + if (grub_be_to_cpu16 (udph->dst) == sock->x_in_port + && inf == sock->x_inf && sock->recv_hook) { - if (sock->status == 0) - sock->out_port = grub_be_to_cpu16 (udph->src); + if (sock->x_status == GRUB_NET_SOCKET_START) + { + sock->x_out_port = grub_be_to_cpu16 (udph->src); + sock->x_status = GRUB_NET_SOCKET_ESTABLISHED; + } /* App protocol remove its own reader. */ - sock->app->read (sock, nb); - - /* If there is data, puts packet in socket list. */ - if ((nb->tail - nb->data) > 0) - grub_net_put_packet (&sock->packs, nb); - else - grub_netbuff_free (nb); + sock->recv_hook (sock, nb, sock->recv_hook_data); return GRUB_ERR_NONE; } } diff --git a/include/grub/net.h b/include/grub/net.h index 630fd33fb..0656787a6 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -201,22 +201,23 @@ struct grub_net_app_protocol int (*hook) (const char *filename, const struct grub_dirhook_info *info)); grub_err_t (*open) (struct grub_file *file, const char *filename); - grub_err_t (*read) (grub_net_socket_t sock, struct grub_net_buff *nb); grub_err_t (*close) (struct grub_file *file); - grub_err_t (*label) (grub_device_t device, char **label); }; struct grub_net_socket { struct grub_net_socket *next; - int status; - int in_port; - int out_port; - grub_net_app_level_t app; - grub_net_network_level_address_t out_nla; - struct grub_net_network_level_interface *inf; - grub_net_packets_t packs; - void *data; + + enum { GRUB_NET_SOCKET_START, + GRUB_NET_SOCKET_ESTABLISHED, + GRUB_NET_SOCKET_CLOSED } x_status; + int x_in_port; + int x_out_port; + grub_err_t (*recv_hook) (grub_net_socket_t sock, struct grub_net_buff *nb, + void *recv); + void *recv_hook_data; + grub_net_network_level_address_t x_out_nla; + struct grub_net_network_level_interface *x_inf; }; extern struct grub_net_socket *grub_net_sockets; @@ -240,10 +241,12 @@ grub_net_socket_unregister (grub_net_socket_t sock) typedef struct grub_net { char *server; + char *name; grub_net_app_level_t protocol; - grub_net_socket_t socket; + grub_net_packets_t packs; grub_off_t offset; grub_fs_t fs; + int eof; } *grub_net_t; extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index eacf3325c..272612299 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -11,6 +11,22 @@ struct udphdr grub_uint16_t chksum; } __attribute__ ((packed)); + +grub_net_socket_t +grub_net_udp_open (char *server, + grub_uint16_t out_port, + grub_err_t (*recv_hook) (grub_net_socket_t sock, + struct grub_net_buff *nb, + void *data), + void *recv_hook_data); + +static inline void +grub_net_udp_close (grub_net_socket_t sock) +{ + grub_net_socket_unregister (sock); + grub_free (sock); +} + grub_err_t grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb); From 671a78acb0648d3d73c95ab0f021f907499aacc0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 14:34:10 +0200 Subject: [PATCH 1138/1414] cleanup pxe and efi network release --- grub-core/Makefile.core.def | 6 ---- grub-core/commands/i386/pc/pxecmd.c | 54 ----------------------------- grub-core/net/drivers/efi/efinet.c | 17 ++++----- grub-core/net/drivers/i386/pc/pxe.c | 50 ++++++++++++++++++++------ grub-core/net/net.c | 13 ------- include/grub/net.h | 23 ++---------- 6 files changed, 47 insertions(+), 116 deletions(-) delete mode 100644 grub-core/commands/i386/pc/pxecmd.c diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2c9f48076..7004aaf23 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -714,12 +714,6 @@ module = { common = commands/probe.c; }; -module = { - name = pxecmd; - i386_pc = commands/i386/pc/pxecmd.c; - enable = i386_pc; -}; - module = { name = read; common = commands/read.c; diff --git a/grub-core/commands/i386/pc/pxecmd.c b/grub-core/commands/i386/pc/pxecmd.c deleted file mode 100644 index dffa15a3a..000000000 --- a/grub-core/commands/i386/pc/pxecmd.c +++ /dev/null @@ -1,54 +0,0 @@ -/* pxe.c - command to control the pxe driver */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - if (! grub_pxe_pxenv) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment"); - - grub_pxe_unload (); - - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(pxecmd) -{ - cmd = grub_register_command ("pxe_unload", grub_cmd_pxe_unload, - 0, - N_("Unload PXE environment.")); -} - -GRUB_MOD_FINI(pxecmd) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 1328cd57c..4b2ffc038 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -184,23 +184,18 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, } } - GRUB_MOD_INIT(efinet) { grub_efinet_findcards (); grub_efi_net_config = grub_efi_net_config_real; } -GRUB_MOD_FINI(ofnet) +GRUB_MOD_FINI(efinet) { - struct grub_net_card *card; - grub_efi_net_config = 0; - FOR_NET_CARDS (card) - if (card->driver && !grub_strcmp (card->driver->name, "efinet")) - { - card->driver->fini (card); - card->driver = NULL; - } - grub_net_card_driver_unregister (&efidriver); + struct grub_net_card *card, *next; + + FOR_NET_CARDS_SAFE (card, next) + if (card->driver && grub_strcmp (card->driver->name, "efinet") == 0) + grub_net_card_unregister (card); } diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 51f4023a6..81607eb57 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -22,8 +22,8 @@ #include #include #include -#include #include +#include #include #include @@ -273,19 +273,36 @@ struct grub_net_card grub_pxe_card = .name = "pxe" }; -void -grub_pxe_unload (void) +static grub_err_t +grub_pxe_fini_hw (int noreturn __attribute__ ((unused))) { if (pxe_rm_entry) - { - grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, - (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, - pxe_rm_entry); - grub_net_card_unregister (&grub_pxe_card); - grub_pxe_pxenv = 0; - } + grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, + (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, + pxe_rm_entry); + + return GRUB_ERR_NONE; } +static grub_err_t +grub_pxe_restore_hw (void) +{ + struct grub_pxe_undi_open *ou; + ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (ou, 0, sizeof (*ou)); + ou->pkt_filter = 4; + grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); + + if (ou->status) + { + grub_net_card_unregister (&grub_pxe_card); + return grub_error (GRUB_ERR_IO, "can't open UNDI"); + } + return GRUB_ERR_NONE; +} + +static void *fini_hnd; + static void grub_pc_net_config_real (char **device, char **path) { @@ -303,6 +320,7 @@ grub_pc_net_config_real (char **device, char **path) grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, bp, GRUB_PXE_BOOTP_SIZE, 1, device, path); + } GRUB_MOD_INIT(pxe) @@ -347,10 +365,20 @@ GRUB_MOD_INIT(pxe) grub_net_card_register (&grub_pxe_card); grub_pc_net_config = grub_pc_net_config_real; + fini_hnd = grub_loader_register_preboot_hook (grub_pxe_fini_hw, + grub_pxe_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(pxe) { + struct grub_net_card *card, *next; + grub_pc_net_config = 0; - grub_pxe_unload (); + grub_pxe_fini_hw (0); + grub_net_card_unregister (&grub_pxe_card); + FOR_NET_CARDS_SAFE (card, next) + if (card->driver && grub_strcmp (card->driver->name, "pxe") == 0) + grub_net_card_unregister (card); + grub_loader_unregister_preboot_hook (fini_hnd); } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 595379a99..96bbd1712 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -52,7 +52,6 @@ struct grub_net_route struct grub_net_route *grub_net_routes = NULL; struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; struct grub_net_card *grub_net_cards = NULL; -struct grub_net_card_driver *grub_net_card_drivers = NULL; struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; static struct grub_fs grub_net_fs; @@ -1321,16 +1320,6 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), return err; } -static void -grub_grubnet_fini_real (void) -{ - struct grub_net_card *card; - - FOR_NET_CARDS (card) - if (card->driver) - card->driver->fini (card); -} - static struct grub_fs grub_net_fs = { .name = "netfs", @@ -1378,7 +1367,6 @@ GRUB_MOD_INIT(net) grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; - grub_grubnet_fini = grub_grubnet_fini_real; } GRUB_MOD_FINI(net) @@ -1393,5 +1381,4 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; - grub_grubnet_fini = NULL; } diff --git a/include/grub/net.h b/include/grub/net.h index 0656787a6..e9a3793db 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -60,32 +60,12 @@ struct grub_net_card_driver { struct grub_net_card_driver *next; char *name; - grub_err_t (*init) (struct grub_net_card *dev); - grub_err_t (*fini) (struct grub_net_card *dev); grub_err_t (*send) (const struct grub_net_card *dev, struct grub_net_buff *buf); grub_ssize_t (*recv) (const struct grub_net_card *dev, struct grub_net_buff *buf); }; -extern struct grub_net_card_driver *grub_net_card_drivers; - -static inline void -grub_net_card_driver_register (struct grub_net_card_driver *driver) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_card_drivers), - GRUB_AS_LIST (driver)); -} - -static inline void -grub_net_card_driver_unregister (struct grub_net_card_driver *driver) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_card_drivers), - GRUB_AS_LIST (driver)); -} - -#define FOR_NET_CARD_DRIVERS(var) for (var = grub_net_card_drivers; var; var = var->next) - typedef struct grub_net_packet { struct grub_net_packet *next; @@ -250,7 +230,6 @@ typedef struct grub_net } *grub_net_t; extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); -extern void (*EXPORT_VAR (grub_grubnet_fini)) (void); struct grub_net_network_level_interface { @@ -350,6 +329,8 @@ grub_net_card_unregister (struct grub_net_card *card) } #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) +#define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = var->next; var; var = next, next = var->next) + struct grub_net_session * grub_net_open_tcp (char *address, grub_uint16_t port); From 275f8264e42781db403a26871462a6a25e53bb50 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 14:55:28 +0200 Subject: [PATCH 1139/1414] Prevent garbage from getting into aout header --- util/grub-mkimage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 9fc37df2b..042bcf2df 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1278,6 +1278,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], aout_size = core_size + sizeof (*aout_head); aout_img = xmalloc (aout_size); aout_head = aout_img; + grub_memset (aout_head, 0, sizeof (*aout_head)); aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) | AOUT32_OMAGIC); aout_head->a_text = grub_host_to_target32 (core_size); From 382077365b92c5727f748dcd87f90ea30dd320ad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 15:10:47 +0200 Subject: [PATCH 1140/1414] Fix mod_gap definition --- include/grub/offsets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grub/offsets.h b/include/grub/offsets.h index c04961fc6..e8170fcbe 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -169,7 +169,7 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 #define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 -#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0 #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 #define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN 0x1 @@ -181,7 +181,7 @@ /* 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 rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x8000 +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 #ifdef GRUB_MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c From 0bc2cd0f82b274ab67fea73da9c5ead92b63a05f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 16:37:14 +0200 Subject: [PATCH 1141/1414] Reintroduce open/close of net cards. Clean up ofnet. --- grub-core/Makefile.am | 3 - grub-core/kern/ieee1275/init.c | 44 +++--- grub-core/kern/ieee1275/openfw.c | 111 ++++++++------ grub-core/net/drivers/efi/efinet.c | 2 +- grub-core/net/drivers/i386/pc/pxe.c | 54 ++----- grub-core/net/drivers/ieee1275/ofnet.c | 203 +++++++++++++------------ grub-core/net/ethernet.c | 10 +- grub-core/net/net.c | 71 ++++++++- include/grub/i386/pc/pxe.h | 2 - include/grub/ieee1275/ieee1275.h | 10 +- include/grub/ieee1275/ofnet.h | 66 -------- include/grub/net.h | 22 +-- 12 files changed, 313 insertions(+), 285 deletions(-) delete mode 100644 include/grub/ieee1275/ofnet.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index c3ecba9cf..2edf85a50 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -115,7 +115,6 @@ endif if COND_i386_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h @@ -175,7 +174,6 @@ endif if COND_powerpc_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h @@ -183,7 +181,6 @@ endif if COND_sparc64_ieee1275 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ofnet.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 3c6332553..81b06c88e 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -77,25 +76,16 @@ grub_translate_ieee1275_path (char *filepath) } } +void (*grub_ieee1275_net_config) (const char *dev, + char **device, + char **path); void grub_machine_get_bootlocation (char **device, char **path) { char bootpath[64]; /* XXX check length */ char *filename; - grub_bootp_t bootp_pckt; - - /* Set the net prefix when possible. */ - if (grub_getbootp && (bootp_pckt = grub_getbootp())) - { - grub_uint32_t n = bootp_pckt->siaddr; - char addr[GRUB_NET_MAX_STR_ADDR_LEN]; - grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d", - ((n >> 24) & 0xff), ((n >> 16) & 0xff), - ((n >> 8) & 0xff), ((n >> 0) & 0xff)); - *device = grub_xasprintf ("(tftp,%s)", addr); - return; - } - + char *type; + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, sizeof (bootpath), 0)) { @@ -106,7 +96,27 @@ grub_machine_get_bootlocation (char **device, char **path) /* Transform an OF device path to a GRUB path. */ - *device = grub_ieee1275_encode_devname (bootpath); + type = grub_ieee1275_get_device_type (bootpath); + if (type && grub_strcmp (type, "network") == 0) + { + char *dev, *canon; + char *ptr; + dev = grub_ieee1275_get_aliasdevname (bootpath); + canon = grub_ieee1275_canonicalise_devname (dev); + ptr = canon + grub_strlen (canon) - 1; + while (ptr > canon && (*ptr == ',' || *ptr == ':')) + ptr--; + ptr++; + *ptr = 0; + + if (grub_ieee1275_net_config) + grub_ieee1275_net_config (canon, device, path); + grub_free (dev); + grub_free (canon); + } + else + *device = grub_ieee1275_encode_devname (bootpath); + grub_free (type); filename = grub_ieee1275_get_filename (bootpath); if (filename) @@ -264,8 +274,6 @@ grub_machine_init (void) void grub_machine_fini (void) { - if (grub_grubnet_fini) - grub_grubnet_fini (); grub_ofdisk_fini (); grub_console_fini (); } diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 8fc373c55..2cecd8c7f 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -22,16 +22,15 @@ #include #include #include -#include #include #include -grub_bootp_t (*grub_getbootp) (void); enum grub_ieee1275_parse_type { GRUB_PARSE_FILENAME, GRUB_PARSE_PARTITION, - GRUB_PARSE_DEVICE + GRUB_PARSE_DEVICE, + GRUB_PARSE_DEVICE_TYPE }; /* Walk children of 'devpath', calling hook for each. */ @@ -322,14 +321,9 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) { char type[64]; /* XXX check size. */ char *device = grub_ieee1275_get_devname (path); - char *args = grub_ieee1275_get_devargs (path); char *ret = 0; grub_ieee1275_phandle_t dev; - if (!args) - /* Shouldn't happen. */ - return 0; - /* We need to know what type of device it is in order to parse the full file path properly. */ if (grub_ieee1275_finddevice (device, &dev)) @@ -344,55 +338,86 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) goto fail; } - if (!grub_strcmp ("block", type)) + switch (ptype) { - /* The syntax of the device arguments is defined in the CHRP and PReP - IEEE1275 bindings: "[partition][,[filename]]". */ - char *comma = grub_strchr (args, ','); + case GRUB_PARSE_DEVICE: + ret = grub_strdup (device); + break; + case GRUB_PARSE_DEVICE_TYPE: + ret = grub_strdup (type); + break; + case GRUB_PARSE_FILENAME: + { + char *comma; + char *args; - if (ptype == GRUB_PARSE_FILENAME) - { - if (comma) - { - char *filepath = comma + 1; + if (grub_strcmp ("block", type) != 0) + goto unknown; - /* Make sure filepath has leading backslash. */ - if (filepath[0] != '\\') - ret = grub_xasprintf ("\\%s", filepath); - else - ret = grub_strdup (filepath); + args = grub_ieee1275_get_devargs (path); + if (!args) + /* Shouldn't happen. */ + return 0; + + /* The syntax of the device arguments is defined in the CHRP and PReP + IEEE1275 bindings: "[partition][,[filename]]". */ + comma = grub_strchr (args, ','); + + if (comma) + { + char *filepath = comma + 1; + + /* Make sure filepath has leading backslash. */ + if (filepath[0] != '\\') + ret = grub_xasprintf ("\\%s", filepath); + else + ret = grub_strdup (filepath); } + grub_free (args); } - else if (ptype == GRUB_PARSE_PARTITION) - { - if (!comma) - ret = grub_strdup (args); - else - ret = grub_strndup (args, (grub_size_t)(comma - args)); - /* Consistently provide numbered partitions to GRUB. - OpenBOOT traditionally uses alphabetical partition - specifiers. */ - if (ret[0] >= 'a' && ret[0] <= 'z') - ret[0] = '1' + (ret[0] - 'a'); - } - } + break; + case GRUB_PARSE_PARTITION: + { + char *comma; + char *args; - else if (!grub_strcmp ("network", type)) - { - if (ptype == GRUB_PARSE_DEVICE) - ret = grub_strdup(device); - } - else - { + if (grub_strcmp ("block", type) != 0) + goto unknown; + + args = grub_ieee1275_get_devargs (path); + if (!args) + /* Shouldn't happen. */ + return 0; + + comma = grub_strchr (args, ','); + if (!comma) + ret = grub_strdup (args); + else + ret = grub_strndup (args, (grub_size_t)(comma - args)); + /* Consistently provide numbered partitions to GRUB. + OpenBOOT traditionally uses alphabetical partition + specifiers. */ + if (ret[0] >= 'a' && ret[0] <= 'z') + ret[0] = '1' + (ret[0] - 'a'); + grub_free (args); + } + break; + default: + unknown: grub_printf ("Unsupported type %s for device %s\n", type, device); } fail: grub_free (device); - grub_free (args); return ret; } +char * +grub_ieee1275_get_device_type (const char *path) +{ + return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE_TYPE); +} + char * grub_ieee1275_get_aliasdevname (const char *path) { diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 4b2ffc038..5c6aac608 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -195,7 +195,7 @@ GRUB_MOD_FINI(efinet) struct grub_net_card *card, *next; FOR_NET_CARDS_SAFE (card, next) - if (card->driver && grub_strcmp (card->driver->name, "efinet") == 0) + if (card->driver == &efidriver) grub_net_card_unregister (card); } diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 81607eb57..aa10cbbfa 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -261,20 +260,8 @@ grub_pxe_send (const struct grub_net_card *dev __attribute__ ((unused)), return 0; } -struct grub_net_card_driver grub_pxe_card_driver = -{ - .send = grub_pxe_send, - .recv = grub_pxe_recv -}; - -struct grub_net_card grub_pxe_card = -{ - .driver = &grub_pxe_card_driver, - .name = "pxe" -}; - static grub_err_t -grub_pxe_fini_hw (int noreturn __attribute__ ((unused))) +grub_pxe_close (const struct grub_net_card *dev __attribute__ ((unused))) { if (pxe_rm_entry) grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, @@ -285,7 +272,7 @@ grub_pxe_fini_hw (int noreturn __attribute__ ((unused))) } static grub_err_t -grub_pxe_restore_hw (void) +grub_pxe_open (const struct grub_net_card *dev __attribute__ ((unused))) { struct grub_pxe_undi_open *ou; ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; @@ -294,14 +281,23 @@ grub_pxe_restore_hw (void) grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); if (ou->status) - { - grub_net_card_unregister (&grub_pxe_card); - return grub_error (GRUB_ERR_IO, "can't open UNDI"); - } + return grub_error (GRUB_ERR_IO, "can't open UNDI"); return GRUB_ERR_NONE; } -static void *fini_hnd; +struct grub_net_card_driver grub_pxe_card_driver = +{ + .open = grub_pxe_open, + .close = grub_pxe_close, + .send = grub_pxe_send, + .recv = grub_pxe_recv +}; + +struct grub_net_card grub_pxe_card = +{ + .driver = &grub_pxe_card_driver, + .name = "pxe" +}; static void grub_pc_net_config_real (char **device, char **path) @@ -355,30 +351,12 @@ GRUB_MOD_INIT(pxe) grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - grub_memset (ou, 0, sizeof (*ou)); - ou->pkt_filter = 4; - grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); - - if (ou->status) - return; - grub_net_card_register (&grub_pxe_card); grub_pc_net_config = grub_pc_net_config_real; - fini_hnd = grub_loader_register_preboot_hook (grub_pxe_fini_hw, - grub_pxe_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(pxe) { - struct grub_net_card *card, *next; - grub_pc_net_config = 0; - grub_pxe_fini_hw (0); grub_net_card_unregister (&grub_pxe_card); - FOR_NET_CARDS_SAFE (card, next) - if (card->driver && grub_strcmp (card->driver->name, "pxe") == 0) - grub_net_card_unregister (card); - grub_loader_unregister_preboot_hook (fini_hnd); } diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index e5a6bfcad..cc29d0987 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -25,8 +24,15 @@ GRUB_MOD_LICENSE ("GPLv3+"); +struct grub_ofnetcard_data +{ + char *path; + grub_ieee1275_ihandle_t handle; + grub_uint32_t mtu; +}; + static grub_err_t -card_open (struct grub_net_card *dev) +card_open (const struct grub_net_card *dev) { int status; struct grub_ofnetcard_data *data = dev->data; @@ -44,14 +50,13 @@ card_open (struct grub_net_card *dev) return GRUB_ERR_NONE; } -static grub_err_t -card_close (struct grub_net_card *dev) +static void +card_close (const struct grub_net_card *dev) { struct grub_ofnetcard_data *data = dev->data; if (data->handle) grub_ieee1275_close (data->handle); - return GRUB_ERR_NONE; } static grub_err_t @@ -93,8 +98,8 @@ get_card_packet (const struct grub_net_card *dev, struct grub_net_buff *nb) static struct grub_net_card_driver ofdriver = { .name = "ofnet", - .init = card_open, - .fini = card_close, + .open = card_open, + .close = card_close, .send = send_card_buffer, .recv = get_card_packet }; @@ -112,39 +117,87 @@ bootp_response_properties[] = { .name = "bootpreply-packet", .offset = 0x2a}, }; -static grub_bootp_t -grub_getbootp_real (void) +static void +grub_ieee1275_net_config_real (const char *devpath, char **device, char **path) { - grub_bootp_t packet = grub_malloc (sizeof *packet); - char *bootp_response; - grub_ssize_t size; - unsigned int i; + struct grub_net_card *card; - for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) - if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, - bootp_response_properties[i].name, - &size) >= 0) - break; + /* FIXME: Check that it's the right card. */ + FOR_NET_CARDS (card) + { + char *bootp_response; + char *cardpath; + char *canon; - if (size < 0) - return NULL; + grub_ssize_t size = -1; + unsigned int i; - bootp_response = grub_malloc (size); - if (grub_ieee1275_get_property (grub_ieee1275_chosen, - bootp_response_properties[i].name, - bootp_response, size, 0) < 0) - return NULL; + if (card->driver != &ofdriver) + continue; - grub_memcpy (packet, bootp_response + bootp_response_properties[i].offset, sizeof (*packet)); - grub_free (bootp_response); - return packet; + cardpath = ((struct grub_ofnetcard_data *) card->data)->path; + canon = grub_ieee1275_canonicalise_devname (cardpath); + if (grub_strcmp (devpath, canon) != 0) + { + grub_free (canon); + continue; + } + grub_free (canon); + + for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) + if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, + bootp_response_properties[i].name, + &size) >= 0) + break; + + if (size < 0) + return; + + bootp_response = grub_malloc (size); + if (!bootp_response) + { + grub_print_error (); + return; + } + if (grub_ieee1275_get_property (grub_ieee1275_chosen, + bootp_response_properties[i].name, + bootp_response, size, 0) < 0) + return; + + grub_net_configure_by_dhcp_ack (card->name, card, 0, + (struct grub_net_bootp_packet *) + &bootp_response + + bootp_response_properties[i].offset, + size - bootp_response_properties[i].offset, + 1, device, path); + return; + } +} + +static char * +find_alias (const char *fullname) +{ + char *ret = NULL; + auto int find_alias_hook (struct grub_ieee1275_devalias *alias); + + int find_alias_hook (struct grub_ieee1275_devalias *alias) + { + if (grub_strcmp (alias->path, fullname) == 0) + { + ret = grub_strdup (alias->name); + return 1; + } + return 0; + } + + grub_devalias_iterate (find_alias_hook); + grub_errno = GRUB_ERR_NONE; + return ret; } static void grub_ofnet_findcards (void) { - int i = 0; - auto int search_net_devices (struct grub_ieee1275_devalias *alias); int search_net_devices (struct grub_ieee1275_devalias *alias) @@ -155,6 +208,7 @@ grub_ofnet_findcards (void) struct grub_net_card *card; grub_ieee1275_phandle_t devhandle; grub_net_link_level_address_t lla; + char *shortname; ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); if (!ofdata) @@ -162,7 +216,7 @@ grub_ofnet_findcards (void) grub_print_error (); return 1; } - card = grub_malloc (sizeof (struct grub_net_card)); + card = grub_zalloc (sizeof (struct grub_net_card)); if (!card) { grub_free (ofdata); @@ -177,11 +231,19 @@ grub_ofnet_findcards (void) if (grub_ieee1275_get_integer_property (devhandle, "max-frame-size", &(ofdata->mtu), sizeof (ofdata->mtu), 0)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve mtu size."); + { + ofdata->mtu = 1500; + } - if (grub_ieee1275_get_property - (devhandle, "mac-address", &(lla.mac), 6, 0)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); + if (grub_ieee1275_get_property (devhandle, "mac-address", + &(lla.mac), 6, 0) + && grub_ieee1275_get_property (devhandle, "local-mac-address", + &(lla.mac), 6, 0)) + { + grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); + grub_print_error (); + return 0; + } lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; card->default_address = lla; @@ -189,7 +251,11 @@ grub_ofnet_findcards (void) card->driver = NULL; card->data = ofdata; card->flags = 0; - card->name = grub_xasprintf ("eth%d", i++); + shortname = find_alias (alias->path); + card->name = grub_xasprintf ("ofnet_%s", shortname ? : alias->path); + grub_free (shortname); + + card->driver = &ofdriver; grub_net_card_register (card); return 0; } @@ -200,69 +266,18 @@ grub_ofnet_findcards (void) grub_ieee1275_devices_iterate (search_net_devices); } -static void -grub_ofnet_probecards (void) -{ - struct grub_net_card *card; - struct grub_net_card_driver *driver; - struct grub_net_network_level_interface *inter; - grub_bootp_t bootp_pckt; - grub_net_network_level_address_t addr; - grub_net_network_level_netaddress_t net; - bootp_pckt = grub_getbootp (); - - /* Assign correspondent driver for each device. */ - FOR_NET_CARDS (card) - { - FOR_NET_CARD_DRIVERS (driver) - { - if (driver->init (card) == GRUB_ERR_NONE) - { - card->driver = driver; - if (bootp_pckt - && grub_memcmp (bootp_pckt->chaddr, card->default_address.mac, 6) == 0) - { - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = bootp_pckt->yiaddr; - grub_net_add_addr ("bootp_cli_addr", card, addr, - card->default_address, 0); - FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, "bootp_cli_addr") == 0) - break; - net.type = addr.type; - net.ipv4.base = addr.ipv4; - net.ipv4.masksize = 24; - grub_net_add_route ("bootp-router", net, inter); - } - break; - } - } - } - grub_free (bootp_pckt); - -} - GRUB_MOD_INIT(ofnet) { - struct grub_net_card *card; - grub_getbootp = grub_getbootp_real; - grub_net_card_driver_register (&ofdriver); grub_ofnet_findcards (); - grub_ofnet_probecards (); - FOR_NET_CARDS (card) - if (card->driver == NULL) - grub_net_card_unregister (card); + grub_ieee1275_net_config = grub_ieee1275_net_config_real; } GRUB_MOD_FINI(ofnet) { - struct grub_net_card *card; - FOR_NET_CARDS (card) - if (card->driver && !grub_strcmp (card->driver->name, "ofnet")) - { - card->driver->fini (card); - card->driver = NULL; - } - grub_net_card_driver_unregister (&ofdriver); - grub_getbootp = NULL; + struct grub_net_card *card, *next; + + FOR_NET_CARDS_SAFE (card, next) + if (card->driver && grub_strcmp (card->driver->name, "ofnet") == 0) + grub_net_card_unregister (card); + grub_ieee1275_net_config = 0; } diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 175d0b65f..3006c9d93 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -25,7 +25,15 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, grub_memcpy (eth->src, inf->hwaddress.mac, 6); eth->type = grub_cpu_to_be16 (ethertype); - + if (!inf->card->opened) + { + err = GRUB_ERR_NONE; + if (inf->card->driver->open) + err = inf->card->driver->open (inf->card); + if (err) + return err; + inf->card->opened = 1; + } return inf->card->driver->send (inf->card, nb); } diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 96bbd1712..a3b76cae0 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -58,6 +59,7 @@ static struct grub_fs grub_net_fs; static inline void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) { + inter->card->num_ifaces--; *inter->prev = inter->next; if (inter->next) inter->next->prev = inter->prev; @@ -65,6 +67,24 @@ grub_net_network_level_interface_unregister (struct grub_net_network_level_inter inter->prev = 0; } +void +grub_net_card_unregister (struct grub_net_card *card) +{ + struct grub_net_network_level_interface *inf, *next; + FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(inf, next) + if (inf->card == card) + grub_net_network_level_interface_unregister (inf); + if (card->opened) + { + if (card->driver->close) + card->driver->close (card); + card->opened = 0; + } + grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards), + GRUB_AS_LIST (card)); +} + + static inline void grub_net_route_register (struct grub_net_route *route) { @@ -336,6 +356,7 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa grub_register_variable_hook (name, 0, addr_set_env); } + inter->card->num_ifaces++; inter->prev = &grub_net_network_level_interfaces; inter->next = grub_net_network_level_interfaces; if (inter->next) @@ -345,7 +366,7 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa struct grub_net_network_level_interface * grub_net_add_addr (const char *name, - const struct grub_net_card *card, + struct grub_net_card *card, grub_net_network_level_address_t addr, grub_net_link_level_address_t hwaddress, grub_net_interface_flags_t flags) @@ -714,6 +735,20 @@ grub_net_fs_close (grub_file_t file) static void receive_packets (struct grub_net_card *card) { + if (card->num_ifaces == 0) + return; + if (!card->opened) + { + grub_err_t err = GRUB_ERR_NONE; + if (card->driver->open) + err = card->driver->open (card); + if (err) + { + grub_errno = GRUB_ERR_NONE; + return; + } + card->opened = 1; + } while (1) { /* Maybe should be better have a fixed number of packets for each card @@ -926,7 +961,7 @@ parse_dhcp_vendor (const char *name, void *vend, int limit) struct grub_net_network_level_interface * grub_net_configure_by_dhcp_ack (const char *name, - const struct grub_net_card *card, + struct grub_net_card *card, grub_net_interface_flags_t flags, const struct grub_net_bootp_packet *bp, grub_size_t size, @@ -1042,7 +1077,7 @@ grub_net_configure_by_dhcp_ack (const char *name, void grub_net_process_dhcp (struct grub_net_buff *nb, - const struct grub_net_card *card) + struct grub_net_card *card) { char *name; struct grub_net_network_level_interface *inf; @@ -1228,6 +1263,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), if (j) ifaces[j].prev = &ifaces[j-1].next; ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); + card->num_ifaces++; if (!ifaces[j].name) { unsigned i; @@ -1331,6 +1367,29 @@ static struct grub_fs grub_net_fs = .uuid = NULL, .mtime = NULL, }; + +static grub_err_t +grub_net_fini_hw (int noreturn __attribute__ ((unused))) +{ + struct grub_net_card *card; + FOR_NET_CARDS (card) + if (card->opened) + { + if (card->driver->close) + card->driver->close (card); + card->opened = 0; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_net_restore_hw (void) +{ + return GRUB_ERR_NONE; +} + +static void *fini_hnd; + static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp, cmd_bootp; static grub_command_t cmd_dhcp, cmd_lsaddr; @@ -1367,6 +1426,11 @@ GRUB_MOD_INIT(net) grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; + fini_hnd = grub_loader_register_preboot_hook (grub_net_fini_hw, + grub_net_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); + grub_net_fini_hw (0); + grub_loader_unregister_preboot_hook (fini_hnd); } GRUB_MOD_FINI(net) @@ -1381,4 +1445,5 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; + grub_loader_unregister_preboot_hook (fini_hnd); } diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h index 781b53df5..376a18962 100644 --- a/include/grub/i386/pc/pxe.h +++ b/include/grub/i386/pc/pxe.h @@ -287,8 +287,6 @@ int EXPORT_FUNC(grub_pxe_call) (int func, void * data, grub_uint32_t pxe_rm_entr extern struct grub_pxe_bangpxe *grub_pxe_pxenv; -void grub_pxe_unload (void); - #endif #endif /* GRUB_CPU_PXE_H */ diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 87294610d..81590ee4b 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -64,12 +64,9 @@ struct grub_ieee1275_common_hdr typedef grub_uint32_t grub_ieee1275_ihandle_t; typedef grub_uint32_t grub_ieee1275_phandle_t; -struct grub_ofnetcard_data -{ - char *path; - grub_ieee1275_ihandle_t handle; - grub_uint32_t mtu; -}; +extern void (*EXPORT_VAR(grub_ieee1275_net_config)) (const char *dev, + char **device, + char **path); /* Maps a device alias to a pathname. */ extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); @@ -203,5 +200,6 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) alias)); char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); +char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/include/grub/ieee1275/ofnet.h b/include/grub/ieee1275/ofnet.h deleted file mode 100644 index c7284df38..000000000 --- a/include/grub/ieee1275/ofnet.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,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_OFNET_HEADER -#define GRUB_OFNET_HEADER 1 - -#include -#include -#include - -struct grub_ofnet -{ - /* The net name. */ - const char *name; - - /* The OF device string. */ - char *dev; - /*server ip*/ - char *sip; - /*client ip*/ - char *cip; - /*gateway*/ - char *gat; - /**/ - int type; -}; - -typedef struct grub_ofnet *grub_ofnet_t; - -struct grub_bootp { - grub_uint8_t op; /* 1 = BOOTREQUEST, 2 = BOOTREPLY */ - grub_uint8_t htype; /* Hardware address type. */ - grub_uint8_t hlen; /* Hardware address length */ - grub_uint8_t hops; /* Used by gateways in cross-gateway booting. */ - grub_uint32_t xid; /* Transaction ID */ - grub_uint16_t secs; /* Seconds elapsed. */ - grub_uint16_t unused; /* Unused. */ - grub_uint32_t ciaddr; /* Client IP address, */ - grub_uint32_t yiaddr; /* Client IP address filled by server. */ - grub_uint32_t siaddr; /* Server IP address. */ - grub_uint32_t giaddr; /* Gateway IP address. */ - unsigned char chaddr [16]; /* Client hardware address */ - char sname [64]; /* Server name */ - char file [128]; /* Boot filename */ - unsigned char vend [64]; -}; - -typedef struct grub_bootp* grub_bootp_t; - -extern grub_bootp_t (*EXPORT_VAR (grub_getbootp)) (void); -#endif /* ! GRUB_NET_HEADER */ diff --git a/include/grub/net.h b/include/grub/net.h index e9a3793db..85fdef365 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -60,6 +60,8 @@ struct grub_net_card_driver { struct grub_net_card_driver *next; char *name; + grub_err_t (*open) (const struct grub_net_card *dev); + void (*close) (const struct grub_net_card *dev); grub_err_t (*send) (const struct grub_net_card *dev, struct grub_net_buff *buf); grub_ssize_t (*recv) (const struct grub_net_card *dev, @@ -87,6 +89,8 @@ struct grub_net_card struct grub_net_card_driver *driver; grub_net_link_level_address_t default_address; grub_net_card_flags_t flags; + int num_ifaces; + int opened; union { struct @@ -236,7 +240,7 @@ struct grub_net_network_level_interface struct grub_net_network_level_interface *next; struct grub_net_network_level_interface **prev; char *name; - const struct grub_net_card *card; + struct grub_net_card *card; grub_net_network_level_address_t address; grub_net_link_level_address_t hwaddress; grub_net_interface_flags_t flags; @@ -284,7 +288,7 @@ grub_net_session_recv (struct grub_net_session *session, void *buf, struct grub_net_network_level_interface * grub_net_add_addr (const char *name, - const struct grub_net_card *card, + struct grub_net_card *card, grub_net_network_level_address_t addr, grub_net_link_level_address_t hwaddress, grub_net_interface_flags_t flags); @@ -321,12 +325,8 @@ grub_net_card_register (struct grub_net_card *card) GRUB_AS_LIST (card)); } -static inline void -grub_net_card_unregister (struct grub_net_card *card) -{ - grub_list_remove (GRUB_AS_LIST_P (&grub_net_cards), - GRUB_AS_LIST (card)); -} +void +grub_net_card_unregister (struct grub_net_card *card); #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) #define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = var->next; var; var = next, next = var->next) @@ -390,7 +390,7 @@ struct grub_net_bootp_packet struct grub_net_network_level_interface * grub_net_configure_by_dhcp_ack (const char *name, - const struct grub_net_card *card, + struct grub_net_card *card, grub_net_interface_flags_t flags, const struct grub_net_bootp_packet *bp, grub_size_t size, @@ -398,7 +398,7 @@ grub_net_configure_by_dhcp_ack (const char *name, void grub_net_process_dhcp (struct grub_net_buff *nb, - const struct grub_net_card *card); + struct grub_net_card *card); int grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, @@ -418,6 +418,8 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) +#define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = var->next; var; var = next, next = var->next) + grub_err_t grub_net_send_link_layer (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, grub_net_link_level_address_t *target); From a07a81b33550ed050cbd70b18f8eb0d9177559fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 20:24:20 +0200 Subject: [PATCH 1142/1414] CMOS support on sparc. * gentpl.py (cmos): Add powerpc and sparc. * grub-core/Makefile.core.def (datetime): Add lib/ieee1275/cmos.c on powerpc and sparc. * grub-core/lib/cmos_datetime.c (grub_get_datetime) [__powerpc__ || __sparc__]: Rename to grub_get_datetime_cmos. (grub_set_datetime) [__powerpc__ || __sparc__]: Likewise to grub_set_datetime_cmos. * grub-core/lib/ieee1275/cmos.c: New file. * grub-core/lib/ieee1275/datetime.c (no_ieee1275_rtc): New vaiable. (find_rtc): Set no_ieee1275_rtc on error. (grub_get_datetime): Call grub_get_datetime_cmos on error. (grub_set_datetime): Call grub_set_datetime_cmos on error. * include/grub/cmos.h (grub_cmos_read): Return grub_err_t since it may fail. Move value to argument. All users updated (grub_cmos_write): Likewise. (grub_cmos_read) [__powerpc__ || __sparc__]: Rewritten. (grub_cmos_write) [__powerpc__ || __sparc__]: Likewise. * include/grub/datetime.h [__powerpc__ || __sparc__]: Declare grub_get_datetime_cmos and grub_set_datetime_cmos. --- ChangeLog | 24 ++++++++++ gentpl.py | 4 +- grub-core/Makefile.core.def | 3 ++ grub-core/commands/i386/cmostest.c | 14 ++++-- grub-core/lib/cmos_datetime.c | 68 ++++++++++++++++++++------- grub-core/lib/ieee1275/cmos.c | 75 ++++++++++++++++++++++++++++++ grub-core/lib/ieee1275/datetime.c | 14 +++++- include/grub/cmos.h | 48 +++++++++++++++++-- include/grub/datetime.h | 7 +++ 9 files changed, 231 insertions(+), 26 deletions(-) create mode 100644 grub-core/lib/ieee1275/cmos.c diff --git a/ChangeLog b/ChangeLog index e091265d4..694a97972 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2011-07-05 Vladimir Serbinenko + + CMOS support on sparc. + + * gentpl.py (cmos): Add powerpc and sparc. + * grub-core/Makefile.core.def (datetime): Add lib/ieee1275/cmos.c on + powerpc and sparc. + * grub-core/lib/cmos_datetime.c (grub_get_datetime) + [__powerpc__ || __sparc__]: Rename to grub_get_datetime_cmos. + (grub_set_datetime) [__powerpc__ || __sparc__]: Likewise to + grub_set_datetime_cmos. + * grub-core/lib/ieee1275/cmos.c: New file. + * grub-core/lib/ieee1275/datetime.c (no_ieee1275_rtc): New vaiable. + (find_rtc): Set no_ieee1275_rtc on error. + (grub_get_datetime): Call grub_get_datetime_cmos on error. + (grub_set_datetime): Call grub_set_datetime_cmos on error. + * include/grub/cmos.h (grub_cmos_read): Return grub_err_t since it may + fail. Move value to argument. All users updated + (grub_cmos_write): Likewise. + (grub_cmos_read) [__powerpc__ || __sparc__]: Rewritten. + (grub_cmos_write) [__powerpc__ || __sparc__]: Likewise. + * include/grub/datetime.h [__powerpc__ || __sparc__]: Declare + grub_get_datetime_cmos and grub_set_datetime_cmos. + 2011-07-02 GrĂ©goire Sutre * util/grub-mkconfig.in: Use @PACKAGE@ instead of hardcoded name when diff --git a/gentpl.py b/gentpl.py index 6e2df076b..31cde1e81 100644 --- a/gentpl.py +++ b/gentpl.py @@ -30,7 +30,9 @@ 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_loongson", "mips_qemu_mips"]; GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") +GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", + "sparc64_ieee1275", "powerpc_ieee1275"] +GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi") GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] GROUPS["usb"] = GROUPS["pci"] diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fd69e9c22..16c940c61 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1192,6 +1192,9 @@ module = { efi = lib/efi/datetime.c; sparc64_ieee1275 = lib/ieee1275/datetime.c; powerpc_ieee1275 = lib/ieee1275/datetime.c; + sparc64_ieee1275 = lib/ieee1275/cmos.c; + powerpc_ieee1275 = lib/ieee1275/cmos.c; + mips_arc = lib/arc/datetime.c; enable = noemu; }; diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index c79bd0387..6439159bd 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -46,12 +46,17 @@ grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), { int byte, bit; grub_err_t err; + grub_uint8_t value; err = parse_args (argc, argv, &byte, &bit); if (err) return err; - if (grub_cmos_read (byte) & (1 << bit)) + err = grub_cmos_read (byte, &value); + if (err) + return err; + + if (value & (1 << bit)) return GRUB_ERR_NONE; return grub_error (GRUB_ERR_TEST_FAILURE, "false"); @@ -63,13 +68,16 @@ grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)), { int byte, bit; grub_err_t err; + grub_uint8_t value; err = parse_args (argc, argv, &byte, &bit); + if (err) + return err; + err = grub_cmos_read (byte, &value); if (err) return err; - grub_cmos_write (byte, grub_cmos_read (byte) & (~(1 << bit))); - return GRUB_ERR_NONE; + return grub_cmos_write (byte, value & (~(1 << bit))); } static grub_command_t cmd, cmd_clean; diff --git a/grub-core/lib/cmos_datetime.c b/grub-core/lib/cmos_datetime.c index 73c5a03c0..86cd91180 100644 --- a/grub-core/lib/cmos_datetime.c +++ b/grub-core/lib/cmos_datetime.c @@ -23,30 +23,44 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#if !defined (__powerpc__) && !defined (__sparc__) +#define grub_get_datetime_cmos grub_get_datetime +#define grub_set_datetime_cmos grub_set_datetime +#endif + grub_err_t -grub_get_datetime (struct grub_datetime *datetime) +grub_get_datetime_cmos (struct grub_datetime *datetime) { int is_bcd, is_12hour; grub_uint8_t value, flag; + grub_err_t err; - flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); + err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag); + if (err) + return err; is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); - value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR); + err = grub_cmos_read (GRUB_CMOS_INDEX_YEAR, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); datetime->year = value; datetime->year += (value < 80) ? 2000 : 1900; - value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH); + err = grub_cmos_read (GRUB_CMOS_INDEX_MONTH, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); datetime->month = value; - value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH); + err = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); @@ -54,7 +68,9 @@ grub_get_datetime (struct grub_datetime *datetime) is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR); - value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR); + err = grub_cmos_read (GRUB_CMOS_INDEX_HOUR, &value); + if (err) + return err; if (is_12hour) { is_12hour = (value & 0x80); @@ -71,13 +87,18 @@ grub_get_datetime (struct grub_datetime *datetime) datetime->hour = value; - value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE); + err = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE, &value); + if (err) + return err; + if (is_bcd) value = grub_bcd_to_num (value); datetime->minute = value; - value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND); + err = grub_cmos_read (GRUB_CMOS_INDEX_SECOND, &value); + if (err) + return err; if (is_bcd) value = grub_bcd_to_num (value); @@ -87,12 +108,15 @@ grub_get_datetime (struct grub_datetime *datetime) } grub_err_t -grub_set_datetime (struct grub_datetime *datetime) +grub_set_datetime_cmos (struct grub_datetime *datetime) { int is_bcd, is_12hour; grub_uint8_t value, flag; + grub_err_t err; - flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); + err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag); + if (err) + return err; is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); @@ -102,21 +126,27 @@ grub_set_datetime (struct grub_datetime *datetime) if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); + if (err) + return err; value = datetime->month; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); + if (err) + return err; value = datetime->day; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); + if (err) + return err; value = datetime->hour; @@ -138,21 +168,27 @@ grub_set_datetime (struct grub_datetime *datetime) if (is_12hour) value |= 0x80; - grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); + if (err) + return err; value = datetime->minute; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); + if (err) + return err; value = datetime->second; if (is_bcd) value = grub_num_to_bcd (value); - grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); + err = grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); + if (err) + return err; return 0; } diff --git a/grub-core/lib/ieee1275/cmos.c b/grub-core/lib/ieee1275/cmos.c new file mode 100644 index 000000000..fa57db9e7 --- /dev/null +++ b/grub-core/lib/ieee1275/cmos.c @@ -0,0 +1,75 @@ +/* + * 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 + +volatile grub_uint8_t *grub_cmos_port = 0; +grub_err_t +grub_cmos_find_port (void) +{ + auto int hook (struct grub_ieee1275_devalias *alias); + int hook (struct grub_ieee1275_devalias *alias) + { + grub_ieee1275_phandle_t dev; + grub_uint32_t addr[2]; + grub_ssize_t actual; + /* Enough to check if it's "m5819" */ + char compat[100]; + if (grub_ieee1275_finddevice (alias->path, &dev)) + return 0; + if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat), + 0)) + return 0; + if (grub_strcmp (compat, "m5819") != 0) + return 0; + if (grub_ieee1275_get_integer_property (dev, "address", + addr, sizeof (addr), &actual)) + return 0; + if (actual == 4) + { + grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0]; + return 1; + } + +#if GRUB_CPU_SIZEOF_VOID_P == 8 + if (actual == 8) + { + grub_cmos_port = (volatile grub_uint8_t *) + ((((grub_addr_t) addr[0]) << 32) | addr[1]); + return 1; + } +#else + if (actual == 8 && addr[0] == 0) + { + grub_cmos_port = (volatile grub_uint8_t *) addr[1]; + return 1; + } +#endif + return 0; + } + + grub_ieee1275_devices_iterate (hook); + if (!grub_cmos_port) + return grub_error (GRUB_ERR_IO, "no cmos found"); + + return GRUB_ERR_NONE; +} diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c index 4105c639b..1947135fe 100644 --- a/grub-core/lib/ieee1275/datetime.c +++ b/grub-core/lib/ieee1275/datetime.c @@ -21,10 +21,14 @@ #include #include #include +#if defined (__powerpc__) || defined (__sparc__) +#include +#endif GRUB_MOD_LICENSE ("GPLv3+"); static char *rtc = 0; +static int no_ieee1275_rtc = 0; static void find_rtc (void) @@ -42,6 +46,8 @@ find_rtc (void) } grub_ieee1275_devices_iterate (hook); + if (!rtc) + no_ieee1275_rtc = 1; } grub_err_t @@ -64,10 +70,12 @@ grub_get_datetime (struct grub_datetime *datetime) int status; grub_ieee1275_ihandle_t ihandle; + if (no_ieee1275_rtc) + return grub_get_datetime_cmos (datetime); if (!rtc) find_rtc (); if (!rtc) - return grub_error (GRUB_ERR_IO, "no RTC found"); + return grub_get_datetime_cmos (datetime); status = grub_ieee1275_open (rtc, &ihandle); if (status == -1) @@ -114,10 +122,12 @@ grub_set_datetime (struct grub_datetime *datetime) int status; grub_ieee1275_ihandle_t ihandle; + if (no_ieee1275_rtc) + return grub_set_datetime_cmos (datetime); if (!rtc) find_rtc (); if (!rtc) - return grub_error (GRUB_ERR_IO, "no RTC found"); + return grub_set_datetime_cmos (datetime); status = grub_ieee1275_open (rtc, &ihandle); if (status == -1) diff --git a/include/grub/cmos.h b/include/grub/cmos.h index f508e3bf6..331513cd7 100644 --- a/include/grub/cmos.h +++ b/include/grub/cmos.h @@ -20,8 +20,10 @@ #define GRUB_CMOS_H 1 #include +#if !defined (__powerpc__) && !defined (__sparc__) #include #include +#endif #define GRUB_CMOS_INDEX_SECOND 0 #define GRUB_CMOS_INDEX_SECOND_ALARM 1 @@ -55,18 +57,56 @@ grub_num_to_bcd (grub_uint8_t a) return (((a / 10) << 4) + (a % 10)); } -static inline grub_uint8_t -grub_cmos_read (grub_uint8_t index) +#if !defined (__powerpc__) && !defined (__sparc__) +static inline grub_err_t +grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) { grub_outb (index, GRUB_CMOS_ADDR_REG); - return grub_inb (GRUB_CMOS_DATA_REG); + *val = grub_inb (GRUB_CMOS_DATA_REG); + return GRUB_ERR_NONE; } -static inline void +static inline grub_err_t grub_cmos_write (grub_uint8_t index, grub_uint8_t value) { grub_outb (index, GRUB_CMOS_ADDR_REG); grub_outb (value, GRUB_CMOS_DATA_REG); + return GRUB_ERR_NONE; +} +#else +grub_err_t grub_cmos_find_port (void); +extern volatile grub_uint8_t *grub_cmos_port; + +static inline grub_err_t +grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) +{ + if (!grub_cmos_port) + { + grub_err_t err; + err = grub_cmos_find_port (); + if (err) + return err; + } + grub_cmos_port[0] = index; + *val = grub_cmos_port[1]; + return GRUB_ERR_NONE; } +static inline grub_err_t +grub_cmos_write (grub_uint8_t index, grub_uint8_t val) +{ + if (!grub_cmos_port) + { + grub_err_t err; + err = grub_cmos_find_port (); + if (err) + return err; + } + grub_cmos_port[0] = index; + grub_cmos_port[1] = val; + return GRUB_ERR_NONE; +} + +#endif + #endif /* GRUB_CMOS_H */ diff --git a/include/grub/datetime.h b/include/grub/datetime.h index c20fc8c36..dea0f8ea9 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -125,4 +125,11 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) return 1; } +#if defined (__powerpc__) || defined (__sparc__) +grub_err_t +grub_get_datetime_cmos (struct grub_datetime *datetime); +grub_err_t +grub_set_datetime_cmos (struct grub_datetime *datetime); +#endif + #endif /* ! KERNEL_DATETIME_HEADER */ From d73459943924af0345797052934ab61417a5f84d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 21:00:01 +0200 Subject: [PATCH 1143/1414] MIPS qemu at_keyboard support. * gentpl.py (videoinkernel): Add qemu-mips. * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add necessary headers. * grub-core/Makefile.core.def (kernel): Add at_keyboard and layout. * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Init new modules. * grub-core/term/at_keyboard.c (grub_keyboard_controller_init) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Don't consider original set. * grub-core/term/serial.c (grub_serial_register) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Make com0 explicitly active. --- ChangeLog | 14 +++++++++++++ gentpl.py | 2 +- grub-core/Makefile.am | 13 ++++++++++++ grub-core/Makefile.core.def | 2 ++ grub-core/kern/mips/qemu_mips/init.c | 20 ++++++++++++++++++ grub-core/term/at_keyboard.c | 4 ++-- grub-core/term/serial.c | 11 ++++++++++ include/grub/mips/qemu_mips/at_keyboard.h | 25 +++++++++++++++++++++++ 8 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 include/grub/mips/qemu_mips/at_keyboard.h diff --git a/ChangeLog b/ChangeLog index 694a97972..644a7cf6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-07-05 Vladimir Serbinenko + + MIPS qemu at_keyboard support. + + * gentpl.py (videoinkernel): Add qemu-mips. + * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add necessary headers. + * grub-core/Makefile.core.def (kernel): Add at_keyboard and layout. + * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Init new + modules. + * grub-core/term/at_keyboard.c (grub_keyboard_controller_init) + [GRUB_MACHINE_MIPS_QEMU_MIPS]: Don't consider original set. + * grub-core/term/serial.c (grub_serial_register) + [GRUB_MACHINE_MIPS_QEMU_MIPS]: Make com0 explicitly active. + 2011-07-05 Vladimir Serbinenko CMOS support on sparc. diff --git a/gentpl.py b/gentpl.py index 31cde1e81..e431293eb 100644 --- a/gentpl.py +++ b/gentpl.py @@ -37,7 +37,7 @@ GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] GROUPS["usb"] = GROUPS["pci"] # If gfxterm is main output console integrate it into kernel -GROUPS["videoinkernel"] = ["mips_loongson"] +GROUPS["videoinkernel"] = ["mips_loongson", "mips_qemu_mips"] GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index c3ecba9cf..28a143413 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -145,7 +145,20 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h endif if COND_mips_qemu_mips +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 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +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/serial.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h endif if COND_mips_loongson diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 16c940c61..328f7186f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -162,6 +162,8 @@ kernel = { mips_qemu_mips = kern/mips/qemu_mips/init.c; mips_qemu_mips = term/ns8250.c; mips_qemu_mips = term/serial.c; + mips_qemu_mips = term/at_keyboard.c; + mips_qemu_mips = commands/keylayouts.c; mips_arc = kern/mips/arc/init.c; mips_arc = term/arc/console.c; diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index 2180b347a..2016aeb3d 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -12,6 +12,16 @@ extern void grub_serial_init (void); extern void grub_terminfo_init (void); +extern void grub_at_keyboard_init (void); +extern void grub_video_init (void); +extern void grub_bitmap_init (void); +extern void grub_font_init (void); +extern void grub_gfxterm_init (void); +extern void grub_at_keyboard_init (void); +extern void grub_serial_init (void); +extern void grub_terminfo_init (void); +extern void grub_keylayouts_init (void); +extern void grub_boot_init (void); void grub_machine_init (void) @@ -27,8 +37,18 @@ grub_machine_init (void) grub_install_get_time_ms (grub_rtc_get_time_ms); + grub_video_init (); + grub_bitmap_init (); + grub_font_init (); + grub_gfxterm_init (); + + grub_keylayouts_init (); + grub_at_keyboard_init (); + grub_terminfo_init (); grub_serial_init (); + + grub_boot_init (); } void diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index e86df6f35..b81e76230 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -259,7 +259,7 @@ grub_keyboard_controller_write (grub_uint8_t c) grub_outb (c, KEYBOARD_REG_DATA); } -#if !defined (GRUB_MACHINE_MIPS_LOONGSON) && !defined (GRUB_MACHINE_QEMU) +#if !defined (GRUB_MACHINE_MIPS_LOONGSON) && !defined (GRUB_MACHINE_QEMU) && !defined (GRUB_MACHINE_MIPS_QEMU_MIPS) static grub_uint8_t grub_keyboard_controller_read (void) @@ -569,7 +569,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_LOONGSON) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) grub_keyboard_controller_orig = 0; grub_keyboard_orig_set = 2; #else diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index add112f4a..0381349a4 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -313,6 +313,17 @@ grub_serial_register (struct grub_serial_port *port) grub_term_register_input_inactive ("serial_*", in); grub_term_register_output_inactive ("serial_*", out); } +#elif defined (GRUB_MACHINE_MIPS_QEMU_MIPS) + if (grub_strcmp (port->name, "com0") == 0) + { + grub_term_register_input_active ("serial_*", in); + grub_term_register_output_active ("serial_*", out); + } + else + { + 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); diff --git a/include/grub/mips/qemu_mips/at_keyboard.h b/include/grub/mips/qemu_mips/at_keyboard.h new file mode 100644 index 000000000..37cc625d1 --- /dev/null +++ b/include/grub/mips/qemu_mips/at_keyboard.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 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_MACHINE_AT_KEYBOARD_HEADER +#define GRUB_MACHINE_AT_KEYBOARD_HEADER 1 + +#define KEYBOARD_REG_DATA 0xb4000060 +#define KEYBOARD_REG_STATUS 0xb4000064 + +#endif From 748ccabea1fe40d6240f1abaa5e0612920b366ea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 21:42:36 +0200 Subject: [PATCH 1144/1414] MIPS qemu flash support. * grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]: Check magic. * grub-core/kern/mips/qemu_mips/init.c (probe_mem): New function. (grub_machine_init): Probe memory if its size isn't known. * util/grub-mkimage.c (image_targets): Add flash targets. (generate_image): Handle flash targets. --- ChangeLog | 11 +++++ grub-core/boot/mips/startup_raw.S | 16 ++++++- grub-core/kern/mips/qemu_mips/init.c | 28 ++++++++++- util/grub-mkimage.c | 69 +++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 644a7cf6a..3772dc028 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-07-05 Vladimir Serbinenko + + MIPS qemu flash support. + + * grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]: Check + magic. + * grub-core/kern/mips/qemu_mips/init.c (probe_mem): New function. + (grub_machine_init): Probe memory if its size isn't known. + * util/grub-mkimage.c (image_targets): Add flash targets. + (generate_image): Handle flash targets. + 2011-07-05 Vladimir Serbinenko MIPS qemu at_keyboard support. diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index e6dfadaf9..4ecff5efd 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -54,8 +54,22 @@ 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 + 4) | 0x80000000) + lw $t1, %lo (((16 << 20) - 264 + 4) | 0x80000000) ($t0) + + lui $t2, 0x1234 + ori $t2, 0x5678 + + bne $t1, $t2, 1f + nop + lui $t0, %hi (((16 << 20) - 264) | 0x80000000) - lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0) + b 2f + lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0) + +1: + li $s4, 0 +2: #endif #ifdef GRUB_MACHINE_MIPS_LOONGSON diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index 2016aeb3d..0c3113fe2 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -23,11 +23,36 @@ extern void grub_terminfo_init (void); extern void grub_keylayouts_init (void); extern void grub_boot_init (void); +static inline int +probe_mem (grub_addr_t addr) +{ + volatile grub_uint8_t *ptr = (grub_uint8_t *) (0xa0000000 | addr); + grub_uint8_t c = *ptr; + *ptr = 0xAA; + if (*ptr != 0xAA) + return 0; + *ptr = 0x55; + if (*ptr != 0x55) + return 0; + *ptr = c; + return 1; +} + void grub_machine_init (void) { grub_addr_t modend; + if (grub_arch_memsize == 0) + { + int i; + + for (i = 27; i >= 0; i--) + if (probe_mem (grub_arch_memsize | (1 << i))) + grub_arch_memsize |= (1 << i); + grub_arch_memsize++; + } + /* FIXME: measure this. */ grub_arch_cpuclock = 64000000; @@ -40,7 +65,6 @@ grub_machine_init (void) grub_video_init (); grub_bitmap_init (); grub_font_init (); - grub_gfxterm_init (); grub_keylayouts_init (); grub_at_keyboard_init (); @@ -49,6 +73,8 @@ grub_machine_init (void) grub_serial_init (); grub_boot_init (); + + grub_gfxterm_init (); } void diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 9fc37df2b..002696d07 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -67,7 +67,8 @@ struct image_target_desc IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, - IMAGE_FULOONG_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC + IMAGE_FULOONG_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, + IMAGE_QEMU_MIPS_FLASH } id; enum { @@ -466,6 +467,50 @@ 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-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_QEMU_MIPS_FLASH, + .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 + }, + { + .dirname = "mipsel-qemu_mips", + .names = { "mipsel-qemu_mips-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU_MIPS_FLASH, + .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 + }, { .dirname = "mips-qemu_mips", .names = { "mips-qemu_mips-elf", NULL }, @@ -1389,6 +1434,28 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = rom_size; } break; + case IMAGE_QEMU_MIPS_FLASH: + { + char *rom_img; + size_t rom_size; + + if (core_size > 512 * 1024) + grub_util_error ("firmware image is too big"); + rom_size = 512 * 1024; + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, core_img, core_size); + + memset (rom_img + core_size, 0, + rom_size - core_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + } + break; case IMAGE_MIPS_ARC: { char *ecoff_img; From 93c06ff9c6490af246ce3620c11d5cc638903e7f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jul 2011 23:46:15 +0200 Subject: [PATCH 1145/1414] VGA text support in qemu-mips * grub-core/Makefile.core.def (kernel): Add term/i386/pc/vga_text.c, term/i386/vga_common.c and kern/vga_init.c on qemu-mips. * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Init vga text. * grub-core/kern/i386/qemu/init.c: Renamed to ... * grub-core/kern/vga_init.c: ... this. * grub-core/kern/vga_init.c (VGA_ADDR) [__mips__]: Adjust. (grub_qemu_init_cirrus) [__mips__]: Skip PCI and adjust the I/O base. * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN) [__mips__]: Adjust. * include/grub/vga.h [GRUB_MACHINE_MIPS_QEMU_MIPS]: Declare GRUB_MACHINE_PCI_IO_BASE. --- ChangeLog | 17 ++++++++++++++ grub-core/Makefile.core.def | 5 +++- grub-core/kern/mips/qemu_mips/init.c | 5 ++++ .../kern/{i386/qemu/init.c => vga_init.c} | 23 +++++++++++++++---- grub-core/term/i386/pc/vga_text.c | 6 ++++- include/grub/mips/qemu_mips/kernel.h | 1 + include/grub/vga.h | 5 ++++ 7 files changed, 56 insertions(+), 6 deletions(-) rename grub-core/kern/{i386/qemu/init.c => vga_init.c} (90%) diff --git a/ChangeLog b/ChangeLog index 3772dc028..c2d386032 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-07-05 Vladimir Serbinenko + + VGA text support in qemu-mips + + * grub-core/Makefile.core.def (kernel): Add term/i386/pc/vga_text.c, + term/i386/vga_common.c and kern/vga_init.c on qemu-mips. + * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Init vga + text. + * grub-core/kern/i386/qemu/init.c: Renamed to ... + * grub-core/kern/vga_init.c: ... this. + * grub-core/kern/vga_init.c (VGA_ADDR) [__mips__]: Adjust. + (grub_qemu_init_cirrus) [__mips__]: Skip PCI and adjust the I/O base. + * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN) [__mips__]: + Adjust. + * include/grub/vga.h [GRUB_MACHINE_MIPS_QEMU_MIPS]: Declare + GRUB_MACHINE_PCI_IO_BASE. + 2011-07-05 Vladimir Serbinenko MIPS qemu flash support. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 328f7186f..807f5b357 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -143,7 +143,7 @@ kernel = { i386_pc = term/i386/pc/console.c; i386_qemu = bus/pci.c; - i386_qemu = kern/i386/qemu/init.c; + i386_qemu = kern/vga_init.c; i386_qemu = kern/i386/qemu/mmap.c; i386_qemu = kern/i386/tsc.c; @@ -164,6 +164,9 @@ kernel = { mips_qemu_mips = term/serial.c; mips_qemu_mips = term/at_keyboard.c; mips_qemu_mips = commands/keylayouts.c; + mips_qemu_mips = term/i386/pc/vga_text.c; + mips_qemu_mips = term/i386/vga_common.c; + mips_qemu_mips = kern/vga_init.c; mips_arc = kern/mips/arc/init.c; mips_arc = term/arc/console.c; diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index 0c3113fe2..db9cc796a 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,7 @@ extern void grub_serial_init (void); extern void grub_terminfo_init (void); extern void grub_keylayouts_init (void); extern void grub_boot_init (void); +extern void grub_vga_text_init (void); static inline int probe_mem (grub_addr_t addr) @@ -69,6 +71,9 @@ grub_machine_init (void) grub_keylayouts_init (); grub_at_keyboard_init (); + grub_qemu_init_cirrus (); + grub_vga_text_init (); + grub_terminfo_init (); grub_serial_init (); diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/vga_init.c similarity index 90% rename from grub-core/kern/i386/qemu/init.c rename to grub-core/kern/vga_init.c index 054dfa86b..889d0128e 100644 --- a/grub-core/kern/i386/qemu/init.c +++ b/grub-core/kern/vga_init.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2010,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 @@ -16,7 +16,9 @@ * along with GRUB. If not, see . */ +#ifndef __mips__ #include +#endif #include #include #include @@ -43,7 +45,17 @@ static struct {grub_uint8_t r, g, b, a; } colors[] = {0xFE, 0xFE, 0xFE, 0xFF} // 15 = white }; +#ifdef __mips__ +extern unsigned char ascii_bitmaps[]; +#else #include +#endif + +#ifdef __mips__ +#define VGA_ADDR 0xb00a0000 +#else +#define VGA_ADDR 0xa0000 +#endif static void load_font (void) @@ -61,7 +73,7 @@ load_font (void) grub_vga_gr_write (0xff, GRUB_VGA_GR_BITMASK); for (i = 0; i < 128; i++) - grub_memcpy ((void *) (0xa0000 + 32 * i), ascii_bitmaps + 16 * i, 16); + grub_memcpy ((void *) (VGA_ADDR + 32 * i), ascii_bitmaps + 16 * i, 16); } static void @@ -78,6 +90,7 @@ load_palette (void) void grub_qemu_init_cirrus (void) { +#ifndef __mips__ auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) { @@ -106,8 +119,10 @@ grub_qemu_init_cirrus (void) } grub_pci_iterate (find_card); +#endif - grub_outb (GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE); + grub_outb (GRUB_VGA_IO_MISC_COLOR, + GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_MISC_WRITE); load_font (); @@ -143,5 +158,5 @@ grub_qemu_init_cirrus (void) grub_vga_cr_write (14, GRUB_VGA_CR_CURSOR_START); grub_vga_cr_write (15, GRUB_VGA_CR_CURSOR_END); - grub_outb (0x20, 0x3c0); + grub_outb (0x20, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); } diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c index 1816bfae2..9abffcc0a 100644 --- a/grub-core/term/i386/pc/vga_text.c +++ b/grub-core/term/i386/pc/vga_text.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -29,7 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); static int grub_curr_x, grub_curr_y; +#ifdef __mips__ +#define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb00b8000) +#else #define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb8000) +#endif static void screen_write_char (int x, int y, short c) diff --git a/include/grub/mips/qemu_mips/kernel.h b/include/grub/mips/qemu_mips/kernel.h index c08405e83..66add4b2e 100644 --- a/include/grub/mips/qemu_mips/kernel.h +++ b/include/grub/mips/qemu_mips/kernel.h @@ -25,6 +25,7 @@ void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); +void grub_qemu_init_cirrus (void); #endif diff --git a/include/grub/vga.h b/include/grub/vga.h index bf4439599..58ec3ba15 100644 --- a/include/grub/vga.h +++ b/include/grub/vga.h @@ -19,7 +19,12 @@ #ifndef GRUB_VGA_HEADER #define GRUB_VGA_HEADER 1 +#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS #include +#else +#include +#define GRUB_MACHINE_PCI_IO_BASE 0xb4000000 +#endif enum { From 72b9ad936abf84dbcd4a55b31fe64d316d1bd62a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 02:49:04 +0200 Subject: [PATCH 1146/1414] fix declarations in pxe --- grub-core/net/drivers/i386/pc/pxe.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index aa10cbbfa..cd598ea72 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -260,15 +260,13 @@ grub_pxe_send (const struct grub_net_card *dev __attribute__ ((unused)), return 0; } -static grub_err_t +static void grub_pxe_close (const struct grub_net_card *dev __attribute__ ((unused))) { if (pxe_rm_entry) grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, pxe_rm_entry); - - return GRUB_ERR_NONE; } static grub_err_t @@ -322,7 +320,6 @@ grub_pc_net_config_real (char **device, char **path) GRUB_MOD_INIT(pxe) { struct grub_pxe_bangpxe *pxenv; - struct grub_pxe_undi_open *ou; struct grub_pxe_undi_info *ui; unsigned i; From cf1337aa029a66e8936fa799dbf48d4feabf1f8f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 02:50:35 +0200 Subject: [PATCH 1147/1414] * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_init): Use new grub_read_cmos prototype. --- ChangeLog | 5 +++++ grub-core/kern/i386/qemu/mmap.c | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2d386032..06b71a246 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-05 Vladimir Serbinenko + + * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_init): Use new + grub_read_cmos prototype. + 2011-07-05 Vladimir Serbinenko VGA text support in qemu-mips diff --git a/grub-core/kern/i386/qemu/mmap.c b/grub-core/kern/i386/qemu/mmap.c index 208f36b7e..2b0c7f6a7 100644 --- a/grub-core/kern/i386/qemu/mmap.c +++ b/grub-core/kern/i386/qemu/mmap.c @@ -41,8 +41,11 @@ static grub_uint64_t mem_size, above_4g; void grub_machine_mmap_init () { - mem_size = ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH)) << 24 - | ((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW)) << 16; + grub_uint8_t high, low, b, c, d; + grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH, &high); + grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW, &low); + mem_size = ((grub_uint64_t) high) << 24 + | ((grub_uint64_t) low) << 16; if (mem_size > 0) { /* Don't ask... */ @@ -50,15 +53,19 @@ grub_machine_mmap_init () } else { + grub_cmos_read (QEMU_CMOS_MEMSIZE2_HIGH, &high); + grub_cmos_read (QEMU_CMOS_MEMSIZE2_LOW, &low); mem_size - = ((((grub_uint64_t) grub_cmos_read (QEMU_CMOS_MEMSIZE2_HIGH)) << 18) - | ((grub_uint64_t) (grub_cmos_read (QEMU_CMOS_MEMSIZE2_LOW)) << 10)) + = ((((grub_uint64_t) high) << 18) | (((grub_uint64_t) low) << 10)) + 1024 * 1024; } - above_4g = (((grub_uint64_t) grub_cmos_read (0x5b)) << 16) - | (((grub_uint64_t) grub_cmos_read (0x5c)) << 24) - | (((grub_uint64_t) grub_cmos_read (0x5d)) << 32); + grub_cmos_read (0x5b, &b); + grub_cmos_read (0x5c, &c); + grub_cmos_read (0x5d, &d); + above_4g = (((grub_uint64_t) b) << 16) + | (((grub_uint64_t) c) << 24) + | (((grub_uint64_t) d) << 32); } grub_err_t From b975df6348fdf7bb02d107dd4fff92965e5f9182 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 12:53:37 +0200 Subject: [PATCH 1148/1414] Send TFTP_ERROR on tftp premature close. Several cleanups --- grub-core/net/ethernet.c | 40 ++++++++++++ grub-core/net/ip.c | 46 +++++++++++++- grub-core/net/net.c | 1 + grub-core/net/tftp.c | 118 +++++++++++++++++++++++++++++++++++- include/grub/net.h | 34 +++-------- include/grub/net/device.h | 0 include/grub/net/ethernet.h | 41 ++++++------- include/grub/net/ip.h | 63 ++++++++++--------- include/grub/net/tftp.h | 68 --------------------- include/grub/net/udp.h | 4 +- 10 files changed, 262 insertions(+), 153 deletions(-) delete mode 100644 include/grub/net/device.h delete mode 100644 include/grub/net/tftp.h diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c index 3006c9d93..acd33bcf6 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 @@ -8,6 +26,28 @@ #include #include +#define LLCADDRMASK 0x7f + +struct etherhdr +{ + grub_uint8_t dst[6]; + grub_uint8_t src[6]; + grub_uint16_t type; +} __attribute__ ((packed)); + +struct llchdr +{ + grub_uint8_t dsap; + grub_uint8_t ssap; + grub_uint8_t ctrl; +} __attribute__ ((packed)); + +struct snaphdr +{ + grub_uint8_t oui[3]; + grub_uint16_t type; +} __attribute__ ((packed)); + grub_err_t send_ethernet_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index 8b06f7d11..642a67f18 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 @@ -7,8 +25,32 @@ #include #include +struct iphdr { + grub_uint8_t verhdrlen; + grub_uint8_t service; + grub_uint16_t len; + grub_uint16_t ident; + grub_uint16_t frags; + grub_uint8_t ttl; + grub_uint8_t protocol; + grub_uint16_t chksum; + grub_uint32_t src; + grub_uint32_t dest; +} __attribute__ ((packed)) ; + +struct ip6hdr +{ + grub_uint8_t version:4, priority:4; + grub_uint8_t flow_lbl[3]; + grub_uint16_t payload_len; + grub_uint8_t nexthdr; + grub_uint8_t hop_limit; + grub_uint8_t saddr[16]; + grub_uint8_t daddr[16]; +} __attribute__ ((packed)); + grub_uint16_t -ipchksum (void *ipv, int len) +grub_net_ip_chksum (void *ipv, int len) { grub_uint16_t *ip = (grub_uint16_t *) ipv; grub_uint32_t sum = 0; @@ -48,7 +90,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface * inf, iph->dest = target->ipv4; iph->chksum = 0; - iph->chksum = ipchksum ((void *) nb->data, sizeof (*iph)); + iph->chksum = grub_net_ip_chksum ((void *) nb->data, sizeof (*iph)); /* Determine link layer target address via ARP. */ err = grub_net_arp_resolve (inf, target, &ll_target_addr); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index a3b76cae0..0d664d9b5 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 6ffe27669..be1534021 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -1,5 +1,22 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 @@ -11,6 +28,74 @@ GRUB_MOD_LICENSE ("GPLv3+"); +/* IP port for the MTFTP server used for Intel's PXE */ +enum + { + MTFTP_SERVER_PORT = 75, + MTFTP_CLIENT_PORT = 76, + /* IP port for the TFTP server */ + TFTP_SERVER_PORT = 69 + }; + +enum + { + TFTP_DEFAULTSIZE_PACKET = 512, + TFTP_MAX_PACKET = 1432 + }; + +enum + { + TFTP_CODE_EOF = 1, + TFTP_CODE_MORE = 2, + TFTP_CODE_ERROR = 3, + TFTP_CODE_BOOT = 4, + TFTP_CODE_CFG = 5 + }; + +enum + { + TFTP_RRQ = 1, + TFTP_WRQ = 2, + TFTP_DATA = 3, + TFTP_ACK = 4, + TFTP_ERROR = 5, + TFTP_OACK = 6 + }; + +enum + { + TFTP_EUNDEF = 0, /* not defined */ + TFTP_ENOTFOUND = 1, /* file not found */ + TFTP_EACCESS = 2, /* access violation */ + TFTP_ENOSPACE = 3, /* disk full or allocation exceeded */ + TFTP_EBADOP = 4, /* illegal TFTP operation */ + TFTP_EBADID = 5, /* unknown transfer ID */ + TFTP_EEXISTS = 6, /* file already exists */ + TFTP_ENOUSER = 7 /* no such user */ + }; + +struct tftphdr { + grub_uint16_t opcode; + union { + grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; + struct { + grub_uint16_t block; + grub_int8_t download[TFTP_MAX_PACKET]; + } data; + struct { + grub_uint16_t block; + } ack; + struct { + grub_uint16_t errcode; + grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; + } err; + struct { + grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; + } oack; + } u; +} __attribute__ ((packed)) ; + + typedef struct tftp_data { grub_uint64_t file_size; @@ -40,7 +125,7 @@ tftp_receive (grub_net_socket_t sock __attribute__ ((unused)), switch (grub_be_to_cpu16 (tftph->opcode)) { case TFTP_OACK: - data->block_size = 512; + data->block_size = TFTP_DEFAULTSIZE_PACKET; data->have_oack = 1; for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) { @@ -224,8 +309,35 @@ static grub_err_t tftp_close (struct grub_file *file) { tftp_data_t data = file->data; + if (data->sock) - grub_net_udp_close (data->sock); + { + char nbdata[512]; + grub_err_t err; + struct grub_net_buff nb_err; + struct tftphdr *tftph; + + nb_err.head = nbdata; + nb_err.end = nbdata + sizeof (nbdata); + + grub_netbuff_clear (&nb_err); + grub_netbuff_reserve (&nb_err, 512); + err = grub_netbuff_push (&nb_err, sizeof (tftph->opcode) + + sizeof (tftph->u.err.errcode) + + sizeof ("closed")); + if (!err) + { + tftph = (struct tftphdr *) nb_err.data; + tftph->opcode = grub_cpu_to_be16 (TFTP_ERROR); + tftph->u.err.errcode = grub_cpu_to_be16 (TFTP_EUNDEF); + grub_memcpy (tftph->u.err.errmsg, "closed", sizeof ("closed")); + + err = grub_net_send_udp_packet (data->sock, &nb_err); + } + if (err) + grub_print_error (); + grub_net_udp_close (data->sock); + } grub_free (data); return GRUB_ERR_NONE; } diff --git a/include/grub/net.h b/include/grub/net.h index 85fdef365..0ac0838cf 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2010,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 @@ -82,6 +82,10 @@ typedef struct grub_net_packets grub_net_packet_t *last; } grub_net_packets_t; +#ifdef GRUB_MACHINE_EFI +#include +#endif + struct grub_net_card { struct grub_net_card *next; @@ -93,11 +97,13 @@ struct grub_net_card int opened; union { +#ifdef GRUB_MACHINE_EFI struct { struct grub_efi_simple_network *efi_net; - void *efi_handle; + grub_efi_handle_t efi_handle; }; +#endif void *data; int data_num; }; @@ -420,30 +426,6 @@ extern struct grub_net_network_level_interface *grub_net_network_level_interface #define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = var->next; var; var = next, next = var->next) -grub_err_t grub_net_send_link_layer (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb, - grub_net_link_level_address_t *target); - -typedef int -(*grub_net_packet_handler_t) (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf); - -grub_err_t grub_net_recv_link_layer (struct grub_net_network_level_interface *inf, - grub_net_packet_handler_t handler); - - -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb, - const struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddress); - -grub_err_t -grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - struct grub_net_buff *nb); - -#define FOR_NET_NL_PACKETS(inf, var) FOR_PACKETS(inf->nl_pending, var) - void grub_net_poll_cards (unsigned time); diff --git a/include/grub/net/device.h b/include/grub/net/device.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index a841dc12c..a68aafd96 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -1,30 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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_NET_ETHERNET_HEADER #define GRUB_NET_ETHERNET_HEADER 1 #include #include -#define LLCADDRMASK 0x7f - -struct etherhdr -{ - grub_uint8_t dst[6]; - grub_uint8_t src[6]; - grub_uint16_t type; -} __attribute__ ((packed)); - -struct llchdr -{ - grub_uint8_t dsap; - grub_uint8_t ssap; - grub_uint8_t ctrl; -} __attribute__ ((packed)); - -struct snaphdr -{ - grub_uint8_t oui[3]; - grub_uint16_t type; -} __attribute__ ((packed)); - /* IANA Ethertype */ enum { @@ -32,7 +28,6 @@ enum GRUB_NET_ETHERTYPE_ARP = 0x0806 }; - grub_err_t send_ethernet_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index cb8481a7d..9bed1e19c 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -1,35 +1,42 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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_NET_IP_HEADER #define GRUB_NET_IP_HEADER 1 #include +#include -struct iphdr { - grub_uint8_t verhdrlen; - grub_uint8_t service; - grub_uint16_t len; - grub_uint16_t ident; - grub_uint16_t frags; - grub_uint8_t ttl; - grub_uint8_t protocol; - grub_uint16_t chksum; - grub_uint32_t src; - grub_uint32_t dest; -} __attribute__ ((packed)) ; - -struct ip6hdr -{ - grub_uint8_t version:4, priority:4; - grub_uint8_t flow_lbl[3]; - grub_uint16_t payload_len; - grub_uint8_t nexthdr; - grub_uint8_t hop_limit; - grub_uint8_t saddr[16]; - grub_uint8_t daddr[16]; -} __attribute__ ((packed)); - -#define IP_UDP 0x11 /* UDP protocol */ +enum + { + IP_UDP = 0x11 /* UDP protocol */ + }; #define IP_BROADCAST 0xFFFFFFFF -grub_uint16_t ipchksum(void *ipv, int len); -void ipv4_ini(void); -void ipv4_fini(void); +grub_uint16_t grub_net_ip_chksum(void *ipv, int len); + +grub_err_t +grub_net_recv_ip_packets (struct grub_net_buff *nb, + const struct grub_net_card *card, + const grub_net_link_level_address_t *hwaddress); + +grub_err_t +grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, + const grub_net_network_level_address_t *target, + struct grub_net_buff *nb); + #endif diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h deleted file mode 100644 index 0d8cbd1de..000000000 --- a/include/grub/net/tftp.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef GRUB_NET_TFTP_HEADER -#define GRUB_NET_TFTP_HEADER 1 - -#include -#include -#include - -/* IP port for the MTFTP server used for Intel's PXE */ -#define MTFTP_SERVER_PORT 75 -#define MTFTP_CLIENT_PORT 76 - -#define TFTP_DEFAULTSIZE_PACKET 512 -#define TFTP_MAX_PACKET 1432 - -/* IP port for the TFTP server */ -#define TFTP_SERVER_PORT 69 - - -/* We define these based on what's in arpa/tftp.h. We just like our - * names better, cause they're clearer */ -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 -#define TFTP_OACK 6 - -#define TFTP_CODE_EOF 1 -#define TFTP_CODE_MORE 2 -#define TFTP_CODE_ERROR 3 -#define TFTP_CODE_BOOT 4 -#define TFTP_CODE_CFG 5 - -#define TFTP_EUNDEF 0 /* not defined */ -#define TFTP_ENOTFOUND 1 /* file not found */ -#define TFTP_EACCESS 2 /* access violation */ -#define TFTP_ENOSPACE 3 /* disk full or allocation exceeded */ -#define TFTP_EBADOP 4 /* illegal TFTP operation */ -#define TFTP_EBADID 5 /* unknown transfer ID */ -#define TFTP_EEXISTS 6 /* file already exists */ -#define TFTP_ENOUSER 7 /* no such user */ - - /* * own here because this is cleaner, and maps to the same data layout. - * */ - - -struct tftphdr { - grub_uint16_t opcode; - union { - grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; - struct { - grub_uint16_t block; - grub_int8_t download[TFTP_MAX_PACKET]; - } data; - struct { - grub_uint16_t block; - } ack; - struct { - grub_uint16_t errcode; - grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; - } err; - struct { - grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; - } oack; - } u; -} __attribute__ ((packed)) ; - -#endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index 272612299..5aacf8abb 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -28,13 +28,11 @@ grub_net_udp_close (grub_net_socket_t sock) } grub_err_t -grub_net_send_udp_packet (const grub_net_socket_t socket , struct grub_net_buff *nb); +grub_net_send_udp_packet (const grub_net_socket_t socket, struct grub_net_buff *nb); grub_err_t grub_net_recv_udp_packet (struct grub_net_buff *nb, struct grub_net_network_level_interface *inf); -#define FOR_NET_UDP_PACKETS(inf, var) FOR_PACKETS(inf->udp_pending, var) - #endif From 1c3fcdee151a95730444352b2fb5774bfdd75ce6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 13:13:45 +0200 Subject: [PATCH 1149/1414] buffer network files. Fix incorrect net_fini_hw and unregister calls --- grub-core/net/net.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 0d664d9b5..1f2e2b7d4 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -32,6 +32,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -709,15 +710,36 @@ grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)) } static grub_err_t -grub_net_fs_open (struct grub_file *file, const char *name) +grub_net_fs_open (struct grub_file *file_out, const char *name) { + grub_err_t err; + struct grub_file *file, *bufio; + + file = grub_malloc (sizeof (*file)); + if (!file) + return grub_errno; + + grub_memcpy (file, file_out, sizeof (struct grub_file)); file->device->net->packs.first = NULL; file->device->net->packs.last = NULL; file->device->net->name = grub_strdup (name); if (!file->device->net->name) return grub_errno; - return file->device->net->protocol->open (file, name); + err = file->device->net->protocol->open (file, name); + if (err) + return err; + bufio = grub_bufio_open (file, 32768); + if (! bufio) + { + file->device->net->protocol->close (file); + grub_free (file->device->net->name); + grub_free (file); + return grub_errno; + } + + grub_memcpy (file_out, bufio, sizeof (struct grub_file)); + return GRUB_ERR_NONE; } static grub_err_t @@ -1430,8 +1452,6 @@ GRUB_MOD_INIT(net) fini_hnd = grub_loader_register_preboot_hook (grub_net_fini_hw, grub_net_restore_hw, GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); - grub_net_fini_hw (0); - grub_loader_unregister_preboot_hook (fini_hnd); } GRUB_MOD_FINI(net) @@ -1446,5 +1466,6 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; + grub_net_fini_hw (0); grub_loader_unregister_preboot_hook (fini_hnd); } From 228ccedb5e7870931b628da5f1f758be65dac623 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 13:37:33 +0200 Subject: [PATCH 1150/1414] poll cards when idle --- grub-core/kern/term.c | 4 ++++ grub-core/net/net.c | 11 +++++++++++ include/grub/kernel.h | 3 +++ 3 files changed, 18 insertions(+) diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c index 7b3593161..d7c65dd82 100644 --- a/grub-core/kern/term.c +++ b/grub-core/kern/term.c @@ -29,6 +29,7 @@ struct grub_term_output *grub_term_outputs; struct grub_term_input *grub_term_inputs; void (*grub_term_poll_usb) (void) = NULL; +void (*grub_net_poll_cards_idle) (void) = NULL; /* Put a Unicode character. */ static void @@ -91,6 +92,9 @@ grub_checkkey (void) if (grub_term_poll_usb) grub_term_poll_usb (); + if (grub_net_poll_cards_idle) + grub_net_poll_cards_idle (); + FOR_ACTIVE_TERM_INPUTS(term) { pending_key = term->getkey (term); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 1f2e2b7d4..bee4f8321 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -33,6 +33,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -809,6 +810,14 @@ grub_net_poll_cards (unsigned time) } } +static void +grub_net_poll_cards_idle_real (void) +{ + struct grub_net_card *card; + FOR_NET_CARDS (card) + receive_packets (card); +} + /* Read from the packets list*/ static grub_ssize_t grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) @@ -1452,6 +1461,7 @@ GRUB_MOD_INIT(net) fini_hnd = grub_loader_register_preboot_hook (grub_net_fini_hw, grub_net_restore_hw, GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); + grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; } GRUB_MOD_FINI(net) @@ -1468,4 +1478,5 @@ GRUB_MOD_FINI(net) grub_net_open = NULL; grub_net_fini_hw (0); grub_loader_unregister_preboot_hook (fini_hnd); + grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; } diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 6a5f91c3d..aef585668 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -90,6 +90,9 @@ grub_machine_get_bootlocation (char **device, char **path); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); +extern void (*EXPORT_VAR(grub_net_poll_cards_idle)) (void); + + #if ! defined (ASM_FILE) extern char grub_prefix[]; #endif From 138eeb3625b22b9b5b286813088d8edca09ff2af Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 13:52:35 +0200 Subject: [PATCH 1151/1414] Move bootp into a separate file --- grub-core/Makefile.core.def | 1 + grub-core/net/net.c | 514 +----------------------------------- include/grub/net.h | 16 ++ 3 files changed, 24 insertions(+), 507 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index d1e1d30e4..7bceaa98f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1579,6 +1579,7 @@ module = { module = { name = net; common = net/net.c; + common = net/bootp.c; common = net/ip.c; common = net/udp.c; common = net/ethernet.c; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index bee4f8321..bc16fbde5 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -16,10 +16,8 @@ * along with GRUB. If not, see . */ -#include #include #include -#include #include #include #include @@ -28,16 +26,14 @@ #include #include #include -#include #include -#include #include #include #include GRUB_MOD_LICENSE ("GPLv3+"); -static char *default_server; +char *grub_net_default_server; struct grub_net_route { @@ -59,17 +55,6 @@ struct grub_net_card *grub_net_cards = NULL; struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; static struct grub_fs grub_net_fs; -static inline void -grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) -{ - inter->card->num_ifaces--; - *inter->prev = inter->next; - if (inter->next) - inter->next->prev = inter->prev; - inter->next = 0; - inter->prev = 0; -} - void grub_net_card_unregister (struct grub_net_card *card) { @@ -644,7 +629,7 @@ grub_net_open_real (const char *name) { protname = "tftp"; protnamelen = sizeof ("tftp") - 1; - server = default_server; + server = grub_net_default_server; } else { @@ -659,7 +644,7 @@ grub_net_open_real (const char *name) else { protnamelen = grub_strlen (name); - server = default_server; + server = grub_net_default_server; protname = name; } } @@ -911,483 +896,6 @@ grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) return grub_net_fs_read_real (file, buf, len); } -static char * -grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - return NULL; -} - -static void -set_env_limn_ro (const char *intername, const char *suffix, - char *value, grub_size_t len) -{ - char c; - char varname[sizeof ("net_") + grub_strlen (intername) + sizeof ("_") - + grub_strlen (suffix)]; - grub_snprintf (varname, sizeof (varname), "net_%s_%s", intername, suffix); - c = value[len]; - value[len] = 0; - grub_env_set (varname, value); - value[len] = c; - grub_register_variable_hook (varname, 0, grub_env_write_readonly); -} - -static void -parse_dhcp_vendor (const char *name, void *vend, int limit) -{ - grub_uint8_t *ptr, *ptr0; - - ptr = ptr0 = vend; - - if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 - || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 - || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 - || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) - return; - ptr = ptr + sizeof (grub_uint32_t); - while (ptr - ptr0 < limit) - { - grub_uint8_t tagtype; - grub_uint8_t taglength; - - tagtype = *ptr++; - - /* Pad tag. */ - if (tagtype == 0) - continue; - - /* End tag. */ - if (tagtype == 0xff) - return; - - taglength = *ptr++; - - switch (tagtype) - { - case 12: - set_env_limn_ro (name, "hostname", (char *) ptr, taglength); - break; - - case 15: - set_env_limn_ro (name, "domain", (char *) ptr, taglength); - break; - - case 17: - set_env_limn_ro (name, "rootpath", (char *) ptr, taglength); - break; - - case 18: - set_env_limn_ro (name, "extensionspath", (char *) ptr, taglength); - break; - - /* If you need any other options please contact GRUB - developpement team. */ - } - - ptr += taglength; - } -} - -#define OFFSET_OF(x, y) ((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)) - -struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, - struct grub_net_card *card, - grub_net_interface_flags_t flags, - const struct grub_net_bootp_packet *bp, - grub_size_t size, - int is_def, char **device, char **path) -{ - grub_net_network_level_address_t addr; - grub_net_link_level_address_t hwaddr; - struct grub_net_network_level_interface *inter; - - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = bp->your_ip; - - if (device) - *device = 0; - if (path) - *path = 0; - - grub_memcpy (hwaddr.mac, bp->mac_addr, - bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len - : sizeof (hwaddr.mac)); - hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - inter = grub_net_add_addr (name, card, addr, hwaddr, flags); - { - grub_net_network_level_netaddress_t target; - grub_net_network_level_address_t gw; - char rname[grub_strlen (name) + sizeof ("_gw")]; - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = bp->server_ip; - target.ipv4.masksize = 32; - gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - gw.ipv4 = bp->gateway_ip; - grub_snprintf (rname, sizeof (rname), "%s_gw", name); - grub_net_add_route_gw (rname, target, gw); - } - { - grub_net_network_level_netaddress_t target; - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = bp->gateway_ip; - target.ipv4.masksize = 32; - grub_net_add_route (name, target, inter); - } - - if (size > OFFSET_OF (boot_file, bp)) - set_env_limn_ro (name, "boot_file", (char *) bp->boot_file, - sizeof (bp->boot_file)); - if (is_def) - default_server = 0; - if (size > OFFSET_OF (server_name, bp) - && bp->server_name[0]) - { - set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, - sizeof (bp->server_name)); - if (is_def && !default_server) - { - default_server = grub_strdup (bp->server_name); - grub_print_error (); - } - if (device && !*device) - { - *device = grub_xasprintf ("tftp,%s", bp->server_name); - grub_print_error (); - } - } - if (is_def && !default_server) - { - default_server = grub_xasprintf ("%d.%d.%d.%d", - ((grub_uint8_t *) &bp->server_ip)[0], - ((grub_uint8_t *) &bp->server_ip)[1], - ((grub_uint8_t *) &bp->server_ip)[2], - ((grub_uint8_t *) &bp->server_ip)[3]); - grub_print_error (); - } - - if (device && !*device) - { - *device = grub_xasprintf ("tftp,%d.%d.%d.%d", - ((grub_uint8_t *) &bp->server_ip)[0], - ((grub_uint8_t *) &bp->server_ip)[1], - ((grub_uint8_t *) &bp->server_ip)[2], - ((grub_uint8_t *) &bp->server_ip)[3]); - grub_print_error (); - } - if (size > OFFSET_OF (boot_file, bp) && path) - { - *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); - grub_print_error (); - if (*path) - { - char *slash; - slash = grub_strrchr (*path, '/'); - if (slash) - *slash = 0; - else - **path = 0; - } - } - if (size > OFFSET_OF (vendor, bp)) - parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp)); - - inter->dhcp_ack = grub_malloc (size); - if (inter->dhcp_ack) - { - grub_memcpy (inter->dhcp_ack, bp, size); - inter->dhcp_acklen = size; - } - else - grub_errno = GRUB_ERR_NONE; - - return inter; -} - -void -grub_net_process_dhcp (struct grub_net_buff *nb, - struct grub_net_card *card) -{ - char *name; - struct grub_net_network_level_interface *inf; - - name = grub_xasprintf ("%s:dhcp", card->name); - if (!name) - { - grub_print_error (); - return; - } - grub_net_configure_by_dhcp_ack (name, card, - 0, (const struct grub_net_bootp_packet *) nb->data, - (nb->tail - nb->data), 0, 0, 0); - grub_free (name); - if (grub_errno) - grub_print_error (); - else - { - FOR_NET_NETWORK_LEVEL_INTERFACES(inf) - if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0 - && grub_memcmp (inf->name + grub_strlen (card->name), - ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0) - { - grub_net_network_level_interface_unregister (inf); - break; - } - } -} - -static char -hexdigit (grub_uint8_t val) -{ - if (val < 10) - return val + '0'; - return val + 'a' - 10; -} - -static grub_err_t -grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_network_level_interface *inter; - int num; - grub_uint8_t *ptr; - grub_uint8_t taglength; - - if (argc < 4) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "4 arguments expected"); - - FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[1]) == 0) - break; - - if (!inter) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unrecognised interface %s"), args[1]); - - if (!inter->dhcp_ack) - return grub_error (GRUB_ERR_IO, N_("no DHCP info found")); - - if (inter->dhcp_acklen <= OFFSET_OF (vendor, inter->dhcp_ack)) - return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); - - num = grub_strtoul (args[2], 0, 0); - if (grub_errno) - return grub_errno; - - ptr = inter->dhcp_ack->vendor; - - if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 - || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 - || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 - || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) - return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); - ptr = ptr + sizeof (grub_uint32_t); - while (1) - { - grub_uint8_t tagtype; - - if (ptr >= ((grub_uint8_t *) inter->dhcp_ack) + inter->dhcp_acklen) - return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); - - tagtype = *ptr++; - - /* Pad tag. */ - if (tagtype == 0) - continue; - - /* End tag. */ - if (tagtype == 0xff) - return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); - - taglength = *ptr++; - - if (tagtype == num) - break; - ptr += taglength; - } - - if (grub_strcmp (args[3], "string") == 0) - { - char *val = grub_malloc (taglength + 1); - if (!val) - return grub_errno; - grub_memcpy (val, ptr, taglength); - val[taglength] = 0; - if (args[0][0] == '-' && args[0][1] == 0) - grub_printf ("%s\n", val); - else - return grub_env_set (args[0], val); - return GRUB_ERR_NONE; - } - - if (grub_strcmp (args[3], "number") == 0) - { - grub_uint64_t val = 0; - int i; - for (i = 0; i < taglength; i++) - val = (val << 8) | ptr[i]; - if (args[0][0] == '-' && args[0][1] == 0) - grub_printf ("%llu\n", (unsigned long long) val); - else - { - char valn[64]; - grub_printf (valn, sizeof (valn), "%lld\n", (unsigned long long) val); - return grub_env_set (args[0], valn); - } - return GRUB_ERR_NONE; - } - - if (grub_strcmp (args[3], "hex") == 0) - { - char *val = grub_malloc (2 * taglength + 1); - int i; - if (!val) - return grub_errno; - for (i = 0; i < taglength; i++) - { - val[2 * i] = hexdigit (ptr[i] >> 4); - val[2 * i + 1] = hexdigit (ptr[i] & 0xf); - } - val[2 * taglength] = 0; - if (args[0][0] == '-' && args[0][1] == 0) - grub_printf ("%s\n", val); - else - return grub_env_set (args[0], val); - return GRUB_ERR_NONE; - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "unrecognised format specification %s", args[3]); -} - -static grub_err_t -grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_card *card; - struct grub_net_network_level_interface *ifaces; - grub_size_t ncards = 0; - unsigned j = 0; - int interval; - grub_err_t err; - - FOR_NET_CARDS (card) - { - if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) - continue; - ncards++; - } - - ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); - if (!ifaces) - return grub_errno; - - j = 0; - FOR_NET_CARDS (card) - { - if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) - continue; - ifaces[j].card = card; - ifaces[j].next = &ifaces[j+1]; - if (j) - ifaces[j].prev = &ifaces[j-1].next; - ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); - card->num_ifaces++; - if (!ifaces[j].name) - { - unsigned i; - for (i = 0; i < j; i++) - grub_free (ifaces[i].name); - grub_free (ifaces); - return grub_errno; - } - ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV; - grub_memcpy (&ifaces[j].hwaddress, &card->default_address, - sizeof (ifaces[j].hwaddress)); - j++; - } - ifaces[ncards - 1].next = grub_net_network_level_interfaces; - if (grub_net_network_level_interfaces) - grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next; - grub_net_network_level_interfaces = &ifaces[0]; - ifaces[0].prev = &grub_net_network_level_interfaces; - for (interval = 200; interval < 10000; interval *= 2) - { - int done = 0; - for (j = 0; j < ncards; j++) - { - struct grub_net_bootp_packet *pack; - struct grub_datetime date; - grub_int32_t t; - struct grub_net_buff *nb; - struct udphdr *udph; - grub_net_network_level_address_t target; - - if (!ifaces[j].prev) - continue; - nb = grub_netbuff_alloc (sizeof (*pack)); - if (!nb) - return grub_errno; - err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128); - if (err) - return err; - err = grub_netbuff_push (nb, sizeof (*pack) + 64); - if (err) - return err; - pack = (void *) nb->data; - done = 1; - grub_memset (pack, 0, sizeof (*pack) + 64); - pack->opcode = 1; - pack->hw_type = 1; - pack->hw_len = 6; - err = grub_get_datetime (&date); - if (err || !grub_datetime2unixtime (&date, &t)) - { - grub_errno = GRUB_ERR_NONE; - t = 0; - } - pack->ident = grub_cpu_to_be32 (t); - pack->seconds = 0;//grub_cpu_to_be16 (t); - - grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6); - - grub_netbuff_push (nb, sizeof (*udph)); - - udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16 (68); - udph->dst = grub_cpu_to_be16 (67); - udph->chksum = 0; - udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4 = 0xffffffff; - - err = grub_net_send_ip_packet (&ifaces[j], &target, nb); - if (err) - return err; - } - if (!done) - break; - grub_net_poll_cards (interval); - } - - err = GRUB_ERR_NONE; - for (j = 0; j < ncards; j++) - { - if (!ifaces[j].prev) - continue; - grub_error_push (); - grub_net_network_level_interface_unregister (&ifaces[j]); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't configure %s", - ifaces[j].card->name); - } - - return err; -} - static struct grub_fs grub_net_fs = { .name = "netfs", @@ -1423,8 +931,8 @@ grub_net_restore_hw (void) static void *fini_hnd; static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -static grub_command_t cmd_lsroutes, cmd_lscards, cmd_getdhcp, cmd_bootp; -static grub_command_t cmd_dhcp, cmd_lsaddr; +static grub_command_t cmd_lsroutes, cmd_lscards; +static grub_command_t cmd_lsaddr; GRUB_MOD_INIT(net) { @@ -1446,15 +954,7 @@ GRUB_MOD_INIT(net) "", N_("list network cards")); cmd_lsaddr = grub_register_command ("net_ls_addr", grub_cmd_listaddrs, "", N_("list network addresses")); - cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, - "[CARD]", - N_("perform a bootp autoconfiguration")); - cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, - "[CARD]", - N_("perform a bootp autoconfiguration")); - cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, - N_("VAR INTERFACE NUMBER DESCRIPTION"), - N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); + grub_bootp_init (); grub_fs_register (&grub_net_fs); grub_net_open = grub_net_open_real; @@ -1466,6 +966,7 @@ GRUB_MOD_INIT(net) GRUB_MOD_FINI(net) { + grub_bootp_fini (); grub_unregister_command (cmd_addaddr); grub_unregister_command (cmd_deladdr); grub_unregister_command (cmd_addroute); @@ -1473,7 +974,6 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_lsroutes); grub_unregister_command (cmd_lscards); grub_unregister_command (cmd_lsaddr); - grub_unregister_command (cmd_getdhcp); grub_fs_unregister (&grub_net_fs); grub_net_open = NULL; grub_net_fini_hw (0); diff --git a/include/grub/net.h b/include/grub/net.h index 0ac0838cf..92e637d89 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -429,4 +429,20 @@ extern struct grub_net_network_level_interface *grub_net_network_level_interface void grub_net_poll_cards (unsigned time); +void grub_bootp_init (void); +void grub_bootp_fini (void); + +static inline void +grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) +{ + inter->card->num_ifaces--; + *inter->prev = inter->next; + if (inter->next) + inter->next->prev = inter->prev; + inter->next = 0; + inter->prev = 0; +} + +extern char *grub_net_default_server; + #endif /* ! GRUB_NET_HEADER */ From 6cf88dfd7aa8091e7dfe48c5a1e6e722b48c8a37 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 15:02:19 +0200 Subject: [PATCH 1152/1414] add missing file --- grub-core/net/bootp.c | 527 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 527 insertions(+) create mode 100644 grub-core/net/bootp.c diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c new file mode 100644 index 000000000..a1aaf402f --- /dev/null +++ b/grub-core/net/bootp.c @@ -0,0 +1,527 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 + +static char * +grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), + const char *val __attribute__ ((unused))) +{ + return NULL; +} + +static void +set_env_limn_ro (const char *intername, const char *suffix, + char *value, grub_size_t len) +{ + char c; + char varname[sizeof ("net_") + grub_strlen (intername) + sizeof ("_") + + grub_strlen (suffix)]; + grub_snprintf (varname, sizeof (varname), "net_%s_%s", intername, suffix); + c = value[len]; + value[len] = 0; + grub_env_set (varname, value); + value[len] = c; + grub_register_variable_hook (varname, 0, grub_env_write_readonly); +} + +static void +parse_dhcp_vendor (const char *name, void *vend, int limit) +{ + grub_uint8_t *ptr, *ptr0; + + ptr = ptr0 = vend; + + if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 + || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 + || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 + || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) + return; + ptr = ptr + sizeof (grub_uint32_t); + while (ptr - ptr0 < limit) + { + grub_uint8_t tagtype; + grub_uint8_t taglength; + + tagtype = *ptr++; + + /* Pad tag. */ + if (tagtype == 0) + continue; + + /* End tag. */ + if (tagtype == 0xff) + return; + + taglength = *ptr++; + + switch (tagtype) + { + case 12: + set_env_limn_ro (name, "hostname", (char *) ptr, taglength); + break; + + case 15: + set_env_limn_ro (name, "domain", (char *) ptr, taglength); + break; + + case 17: + set_env_limn_ro (name, "rootpath", (char *) ptr, taglength); + break; + + case 18: + set_env_limn_ro (name, "extensionspath", (char *) ptr, taglength); + break; + + /* If you need any other options please contact GRUB + developpement team. */ + } + + ptr += taglength; + } +} + +#define OFFSET_OF(x, y) ((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y)) + +struct grub_net_network_level_interface * +grub_net_configure_by_dhcp_ack (const char *name, + struct grub_net_card *card, + grub_net_interface_flags_t flags, + const struct grub_net_bootp_packet *bp, + grub_size_t size, + int is_def, char **device, char **path) +{ + grub_net_network_level_address_t addr; + grub_net_link_level_address_t hwaddr; + struct grub_net_network_level_interface *inter; + + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + addr.ipv4 = bp->your_ip; + + if (device) + *device = 0; + if (path) + *path = 0; + + grub_memcpy (hwaddr.mac, bp->mac_addr, + bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len + : sizeof (hwaddr.mac)); + hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + + inter = grub_net_add_addr (name, card, addr, hwaddr, flags); + { + grub_net_network_level_netaddress_t target; + grub_net_network_level_address_t gw; + char rname[grub_strlen (name) + sizeof ("_gw")]; + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = bp->server_ip; + target.ipv4.masksize = 32; + gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + gw.ipv4 = bp->gateway_ip; + grub_snprintf (rname, sizeof (rname), "%s_gw", name); + grub_net_add_route_gw (rname, target, gw); + } + { + grub_net_network_level_netaddress_t target; + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = bp->gateway_ip; + target.ipv4.masksize = 32; + grub_net_add_route (name, target, inter); + } + + if (size > OFFSET_OF (boot_file, bp)) + set_env_limn_ro (name, "boot_file", (char *) bp->boot_file, + sizeof (bp->boot_file)); + if (is_def) + grub_net_default_server = 0; + if (size > OFFSET_OF (server_name, bp) + && bp->server_name[0]) + { + set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, + sizeof (bp->server_name)); + if (is_def && !grub_net_default_server) + { + grub_net_default_server = grub_strdup (bp->server_name); + grub_print_error (); + } + if (device && !*device) + { + *device = grub_xasprintf ("tftp,%s", bp->server_name); + grub_print_error (); + } + } + if (is_def && !grub_net_default_server) + { + grub_net_default_server = grub_xasprintf ("%d.%d.%d.%d", + ((grub_uint8_t *) &bp->server_ip)[0], + ((grub_uint8_t *) &bp->server_ip)[1], + ((grub_uint8_t *) &bp->server_ip)[2], + ((grub_uint8_t *) &bp->server_ip)[3]); + grub_print_error (); + } + + if (device && !*device) + { + *device = grub_xasprintf ("tftp,%d.%d.%d.%d", + ((grub_uint8_t *) &bp->server_ip)[0], + ((grub_uint8_t *) &bp->server_ip)[1], + ((grub_uint8_t *) &bp->server_ip)[2], + ((grub_uint8_t *) &bp->server_ip)[3]); + grub_print_error (); + } + if (size > OFFSET_OF (boot_file, bp) && path) + { + *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); + grub_print_error (); + if (*path) + { + char *slash; + slash = grub_strrchr (*path, '/'); + if (slash) + *slash = 0; + else + **path = 0; + } + } + if (size > OFFSET_OF (vendor, bp)) + parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp)); + + inter->dhcp_ack = grub_malloc (size); + if (inter->dhcp_ack) + { + grub_memcpy (inter->dhcp_ack, bp, size); + inter->dhcp_acklen = size; + } + else + grub_errno = GRUB_ERR_NONE; + + return inter; +} + +void +grub_net_process_dhcp (struct grub_net_buff *nb, + struct grub_net_card *card) +{ + char *name; + struct grub_net_network_level_interface *inf; + + name = grub_xasprintf ("%s:dhcp", card->name); + if (!name) + { + grub_print_error (); + return; + } + grub_net_configure_by_dhcp_ack (name, card, + 0, (const struct grub_net_bootp_packet *) nb->data, + (nb->tail - nb->data), 0, 0, 0); + grub_free (name); + if (grub_errno) + grub_print_error (); + else + { + FOR_NET_NETWORK_LEVEL_INTERFACES(inf) + if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0 + && grub_memcmp (inf->name + grub_strlen (card->name), + ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0) + { + grub_net_network_level_interface_unregister (inf); + break; + } + } +} + +static char +hexdigit (grub_uint8_t val) +{ + if (val < 10) + return val + '0'; + return val + 'a' - 10; +} + +static grub_err_t +grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_network_level_interface *inter; + int num; + grub_uint8_t *ptr; + grub_uint8_t taglength; + + if (argc < 4) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "4 arguments expected"); + + FOR_NET_NETWORK_LEVEL_INTERFACES (inter) + if (grub_strcmp (inter->name, args[1]) == 0) + break; + + if (!inter) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unrecognised interface %s"), args[1]); + + if (!inter->dhcp_ack) + return grub_error (GRUB_ERR_IO, N_("no DHCP info found")); + + if (inter->dhcp_acklen <= OFFSET_OF (vendor, inter->dhcp_ack)) + return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); + + num = grub_strtoul (args[2], 0, 0); + if (grub_errno) + return grub_errno; + + ptr = inter->dhcp_ack->vendor; + + if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 + || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 + || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 + || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) + return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); + ptr = ptr + sizeof (grub_uint32_t); + while (1) + { + grub_uint8_t tagtype; + + if (ptr >= ((grub_uint8_t *) inter->dhcp_ack) + inter->dhcp_acklen) + return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); + + tagtype = *ptr++; + + /* Pad tag. */ + if (tagtype == 0) + continue; + + /* End tag. */ + if (tagtype == 0xff) + return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); + + taglength = *ptr++; + + if (tagtype == num) + break; + ptr += taglength; + } + + if (grub_strcmp (args[3], "string") == 0) + { + char *val = grub_malloc (taglength + 1); + if (!val) + return grub_errno; + grub_memcpy (val, ptr, taglength); + val[taglength] = 0; + if (args[0][0] == '-' && args[0][1] == 0) + grub_printf ("%s\n", val); + else + return grub_env_set (args[0], val); + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[3], "number") == 0) + { + grub_uint64_t val = 0; + int i; + for (i = 0; i < taglength; i++) + val = (val << 8) | ptr[i]; + if (args[0][0] == '-' && args[0][1] == 0) + grub_printf ("%llu\n", (unsigned long long) val); + else + { + char valn[64]; + grub_printf (valn, sizeof (valn), "%lld\n", (unsigned long long) val); + return grub_env_set (args[0], valn); + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[3], "hex") == 0) + { + char *val = grub_malloc (2 * taglength + 1); + int i; + if (!val) + return grub_errno; + for (i = 0; i < taglength; i++) + { + val[2 * i] = hexdigit (ptr[i] >> 4); + val[2 * i + 1] = hexdigit (ptr[i] & 0xf); + } + val[2 * taglength] = 0; + if (args[0][0] == '-' && args[0][1] == 0) + grub_printf ("%s\n", val); + else + return grub_env_set (args[0], val); + return GRUB_ERR_NONE; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "unrecognised format specification %s", args[3]); +} + +static grub_err_t +grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_net_card *card; + struct grub_net_network_level_interface *ifaces; + grub_size_t ncards = 0; + unsigned j = 0; + int interval; + grub_err_t err; + + FOR_NET_CARDS (card) + { + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; + ncards++; + } + + ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); + if (!ifaces) + return grub_errno; + + j = 0; + FOR_NET_CARDS (card) + { + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; + ifaces[j].card = card; + ifaces[j].next = &ifaces[j+1]; + if (j) + ifaces[j].prev = &ifaces[j-1].next; + ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); + card->num_ifaces++; + if (!ifaces[j].name) + { + unsigned i; + for (i = 0; i < j; i++) + grub_free (ifaces[i].name); + grub_free (ifaces); + return grub_errno; + } + ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV; + grub_memcpy (&ifaces[j].hwaddress, &card->default_address, + sizeof (ifaces[j].hwaddress)); + j++; + } + ifaces[ncards - 1].next = grub_net_network_level_interfaces; + if (grub_net_network_level_interfaces) + grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next; + grub_net_network_level_interfaces = &ifaces[0]; + ifaces[0].prev = &grub_net_network_level_interfaces; + for (interval = 200; interval < 10000; interval *= 2) + { + int done = 0; + for (j = 0; j < ncards; j++) + { + struct grub_net_bootp_packet *pack; + struct grub_datetime date; + grub_int32_t t; + struct grub_net_buff *nb; + struct udphdr *udph; + grub_net_network_level_address_t target; + + if (!ifaces[j].prev) + continue; + nb = grub_netbuff_alloc (sizeof (*pack)); + if (!nb) + return grub_errno; + err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128); + if (err) + return err; + err = grub_netbuff_push (nb, sizeof (*pack) + 64); + if (err) + return err; + pack = (void *) nb->data; + done = 1; + grub_memset (pack, 0, sizeof (*pack) + 64); + pack->opcode = 1; + pack->hw_type = 1; + pack->hw_len = 6; + err = grub_get_datetime (&date); + if (err || !grub_datetime2unixtime (&date, &t)) + { + grub_errno = GRUB_ERR_NONE; + t = 0; + } + pack->ident = grub_cpu_to_be32 (t); + pack->seconds = 0;//grub_cpu_to_be16 (t); + + grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6); + + grub_netbuff_push (nb, sizeof (*udph)); + + udph = (struct udphdr *) nb->data; + udph->src = grub_cpu_to_be16 (68); + udph->dst = grub_cpu_to_be16 (67); + udph->chksum = 0; + udph->len = grub_cpu_to_be16 (nb->tail - nb->data); + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4 = 0xffffffff; + + err = grub_net_send_ip_packet (&ifaces[j], &target, nb); + if (err) + return err; + } + if (!done) + break; + grub_net_poll_cards (interval); + } + + err = GRUB_ERR_NONE; + for (j = 0; j < ncards; j++) + { + if (!ifaces[j].prev) + continue; + grub_error_push (); + grub_net_network_level_interface_unregister (&ifaces[j]); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "couldn't configure %s", + ifaces[j].card->name); + } + + return err; +} + +static grub_command_t cmd_dhcp, cmd_getdhcp, cmd_bootp; + +void +grub_bootp_init (void) +{ + cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, + "[CARD]", + N_("perform a bootp autoconfiguration")); + cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, + "[CARD]", + N_("perform a bootp autoconfiguration")); + cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, + N_("VAR INTERFACE NUMBER DESCRIPTION"), + N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); +} + +void +grub_bootp_fini (void) +{ + grub_unregister_command (cmd_getdhcp); + grub_unregister_command (cmd_dhcp); + grub_unregister_command (cmd_bootp); +} From c97dbbf2f28c7d3026e9109790167b646d76ac5e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 17:40:24 +0200 Subject: [PATCH 1153/1414] Fix a memory leak --- grub-core/disk/ieee1275/ofdisk.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 0a935d5c2..7868b14b1 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -243,14 +243,24 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) grub_dprintf ("disk", "Opening `%s'.\n", devpath); if (grub_ieee1275_finddevice (devpath, &dev)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties"); + { + grub_free (devpath); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "can't read device properties"); + } if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop), &actual)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type"); + { + grub_free (devpath); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type"); + } if (grub_strcmp (prop, "block")) - return grub_error (GRUB_ERR_BAD_DEVICE, "not a block device"); + { + grub_free (devpath); + return grub_error (GRUB_ERR_BAD_DEVICE, "not a block device"); + } /* XXX: There is no property to read the number of blocks. There should be a property `#blocks', but it is not there. Perhaps it From c2aa00f059ab09bd427703c874d8ff7936ba3d39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 17:40:36 +0200 Subject: [PATCH 1154/1414] Fix a memory leak --- grub-core/kern/dl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 5f214e378..1841bf1f5 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -688,11 +688,9 @@ grub_dl_load_file (const char *filename) grub_file_close (file); mod = grub_dl_load_core (core, size); + grub_free (core); if (! mod) - { - grub_free (core); - return 0; - } + return 0; mod->ref_count--; return mod; From f872d4744e66dde8cccbc9a189ac39e432851e92 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 17:40:56 +0200 Subject: [PATCH 1155/1414] Fix compilation error --- grub-core/kern/ieee1275/openfw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 2cecd8c7f..4e705a4d8 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -23,7 +23,6 @@ #include #include #include -#include enum grub_ieee1275_parse_type { From e1a0e1b42841f02481f8051cccf9669aa5a231a4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 17:41:19 +0200 Subject: [PATCH 1156/1414] Fix the usage of unsupported %zx --- grub-core/kern/mm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index d54f3f240..ee4d58d81 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -515,7 +515,7 @@ grub_debug_malloc (const char *file, int line, grub_size_t size) void *ptr; if (grub_mm_debug) - grub_printf ("%s:%d: malloc (0x%zx) = ", file, line, size); + grub_printf ("%s:%d: malloc (0x%" PRIxGRUB_SIZE ") = ", file, line, size); ptr = grub_malloc (size); if (grub_mm_debug) grub_printf ("%p\n", ptr); @@ -528,7 +528,7 @@ grub_debug_zalloc (const char *file, int line, grub_size_t size) void *ptr; if (grub_mm_debug) - grub_printf ("%s:%d: zalloc (0x%zx) = ", file, line, size); + grub_printf ("%s:%d: zalloc (0x%" PRIxGRUB_SIZE ") = ", file, line, size); ptr = grub_zalloc (size); if (grub_mm_debug) grub_printf ("%p\n", ptr); @@ -547,7 +547,7 @@ void * grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size) { if (grub_mm_debug) - grub_printf ("%s:%d: realloc (%p, 0x%zx) = ", file, line, ptr, size); + grub_printf ("%s:%d: realloc (%p, 0x%" PRIxGRUB_SIZE ") = ", file, line, ptr, size); ptr = grub_realloc (ptr, size); if (grub_mm_debug) grub_printf ("%p\n", ptr); @@ -561,8 +561,8 @@ grub_debug_memalign (const char *file, int line, grub_size_t align, void *ptr; if (grub_mm_debug) - grub_printf ("%s:%d: memalign (0x%zx, 0x%zx) = ", - file, line, align, size); + grub_printf ("%s:%d: memalign (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE + ") = ", file, line, align, size); ptr = grub_memalign (align, size); if (grub_mm_debug) grub_printf ("%p\n", ptr); From c3bf5267b016238d09455c843d425e7a9ce30e83 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 17:41:49 +0200 Subject: [PATCH 1157/1414] Fix a memory leak --- grub-core/net/bootp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index a1aaf402f..84bdc04d7 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -444,13 +444,22 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), continue; nb = grub_netbuff_alloc (sizeof (*pack)); if (!nb) - return grub_errno; + { + grub_netbuff_free (nb); + return grub_errno; + } err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128); if (err) - return err; + { + grub_netbuff_free (nb); + return err; + } err = grub_netbuff_push (nb, sizeof (*pack) + 64); if (err) - return err; + { + grub_netbuff_free (nb); + return err; + } pack = (void *) nb->data; done = 1; grub_memset (pack, 0, sizeof (*pack) + 64); @@ -480,6 +489,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), target.ipv4 = 0xffffffff; err = grub_net_send_ip_packet (&ifaces[j], &target, nb); + grub_netbuff_free (nb); if (err) return err; } @@ -491,6 +501,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), err = GRUB_ERR_NONE; for (j = 0; j < ncards; j++) { + grub_free (ifaces[j].name); if (!ifaces[j].prev) continue; grub_error_push (); @@ -499,6 +510,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), ifaces[j].card->name); } + grub_free (ifaces); return err; } From d1831ca48a8ee052599f129c36e346336fae6b17 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 18:21:07 +0200 Subject: [PATCH 1158/1414] Limit idle polling frequency --- grub-core/net/drivers/ieee1275/ofnet.c | 1 + grub-core/net/net.c | 10 +++++++++- include/grub/net.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index cc29d0987..20d45ee3d 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -253,6 +253,7 @@ grub_ofnet_findcards (void) card->flags = 0; shortname = find_alias (alias->path); card->name = grub_xasprintf ("ofnet_%s", shortname ? : alias->path); + card->idle_poll_delay_ms = 1; grub_free (shortname); card->driver = &ofdriver; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index bc16fbde5..641aebd64 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -768,6 +768,7 @@ receive_packets (struct grub_net_card *card) if (!nb) { grub_print_error (); + card->last_poll = grub_get_time_ms (); return; } @@ -775,6 +776,7 @@ receive_packets (struct grub_net_card *card) if (actual < 0) { grub_netbuff_free (nb); + card->last_poll = grub_get_time_ms (); break; } grub_net_recv_ethernet_packet (nb, card); @@ -800,7 +802,13 @@ grub_net_poll_cards_idle_real (void) { struct grub_net_card *card; FOR_NET_CARDS (card) - receive_packets (card); + { + grub_uint64_t ctime = grub_get_time_ms (); + + if (ctime < card->last_poll + || ctime >= card->last_poll + card->idle_poll_delay_ms) + receive_packets (card); + } } /* Read from the packets list*/ diff --git a/include/grub/net.h b/include/grub/net.h index 92e637d89..45d08f3f5 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -95,6 +95,8 @@ struct grub_net_card grub_net_card_flags_t flags; int num_ifaces; int opened; + unsigned idle_poll_delay_ms; + grub_uint64_t last_poll; union { #ifdef GRUB_MACHINE_EFI From 697ffdc55b6fcb150e19ad5f746142edbcf5e372 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 18:21:24 +0200 Subject: [PATCH 1159/1414] Fix a memory leak --- grub-core/net/net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 641aebd64..0f8a60413 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -725,6 +725,7 @@ grub_net_fs_open (struct grub_file *file_out, const char *name) } grub_memcpy (file_out, bufio, sizeof (struct grub_file)); + grub_free (bufio); return GRUB_ERR_NONE; } From 1c358e5948c43ac7684c2067c9aa035dd3493778 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jul 2011 22:15:58 +0200 Subject: [PATCH 1160/1414] * po/POTFILES.in: Regenerate. --- ChangeLog | 4 + po/POTFILES.in | 342 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 328 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 110a980f0..e6aace254 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-06 Vladimir Serbinenko + + * po/POTFILES.in: Regenerate. + 2011-07-06 Vladimir Serbinenko Unify sparc init with other ieee1275. diff --git a/po/POTFILES.in b/po/POTFILES.in index 8329fdf0a..2bf4aa10c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,5 +1,22 @@ -# List of files which contain translatable strings. +grub-core/boot/decompressor/minilib.c +grub-core/boot/decompressor/none.c +grub-core/boot/decompressor/xz.c +grub-core/bus/bonito.c +grub-core/bus/cs5536.c +grub-core/bus/emu/pci.c +grub-core/bus/pci.c +grub-core/bus/usb/emu/usb.c +grub-core/bus/usb/ohci.c +grub-core/bus/usb/serial/common.c +grub-core/bus/usb/serial/ftdi.c +grub-core/bus/usb/serial/pl2303.c +grub-core/bus/usb/uhci.c +grub-core/bus/usb/usb.c +grub-core/bus/usb/usbhub.c +grub-core/bus/usb/usbtrans.c grub-core/commands/acpi.c +grub-core/commands/acpihalt.c +grub-core/commands/arc/lsdev.c grub-core/commands/blocklist.c grub-core/commands/boot.c grub-core/commands/cat.c @@ -7,33 +24,41 @@ grub-core/commands/cmp.c grub-core/commands/configfile.c grub-core/commands/date.c grub-core/commands/echo.c +grub-core/commands/efi/acpi.c grub-core/commands/efi/fixvideo.c grub-core/commands/efi/loadbios.c +grub-core/commands/efi/lsefimmap.c +grub-core/commands/efi/lsefisystab.c +grub-core/commands/efi/lssal.c +grub-core/commands/extcmd.c grub-core/commands/gptsync.c grub-core/commands/halt.c grub-core/commands/hashsum.c grub-core/commands/hdparm.c grub-core/commands/help.c grub-core/commands/hexdump.c +grub-core/commands/i386/cmostest.c grub-core/commands/i386/cpuid.c +grub-core/commands/i386/pc/acpi.c grub-core/commands/i386/pc/drivemap.c grub-core/commands/i386/pc/halt.c grub-core/commands/i386/pc/lsapm.c grub-core/commands/i386/pc/play.c -grub-core/commands/i386/pc/pxecmd.c +grub-core/commands/i386/pc/sendkey.c grub-core/commands/ieee1275/suspend.c grub-core/commands/iorw.c grub-core/commands/keylayouts.c grub-core/commands/keystatus.c grub-core/commands/legacycfg.c grub-core/commands/loadenv.c -grub-core/commands/ls.c grub-core/commands/lsacpi.c +grub-core/commands/ls.c grub-core/commands/lsmmap.c grub-core/commands/lspci.c grub-core/commands/memrw.c grub-core/commands/menuentry.c grub-core/commands/minicmd.c +grub-core/commands/mips/loongson/lsspd.c grub-core/commands/parttool.c grub-core/commands/password.c grub-core/commands/password_pbkdf2.c @@ -51,67 +76,348 @@ grub-core/commands/sleep.c grub-core/commands/terminal.c grub-core/commands/test.c grub-core/commands/testload.c +grub-core/commands/time.c grub-core/commands/true.c grub-core/commands/usbtest.c grub-core/commands/videoinfo.c grub-core/commands/videotest.c +grub-core/commands/wildcard.c grub-core/commands/xnu_uuid.c - +grub-core/disk/ahci.c +grub-core/disk/arc/arcdisk.c +grub-core/disk/ata.c +grub-core/disk/dmraid_nvidia.c +grub-core/disk/efi/efidisk.c +grub-core/disk/host.c +grub-core/disk/i386/pc/biosdisk.c +grub-core/disk/ieee1275/nand.c +grub-core/disk/ieee1275/ofdisk.c grub-core/disk/loopback.c - +grub-core/disk/lvm.c +grub-core/disk/mdraid1x_linux.c +grub-core/disk/mdraid_linux.c +grub-core/disk/memdisk.c +grub-core/disk/pata.c +grub-core/disk/raid5_recover.c +grub-core/disk/raid6_recover.c +grub-core/disk/raid.c +grub-core/disk/scsi.c +grub-core/disk/usbms.c +grub-core/efiemu/i386/coredetect.c +grub-core/efiemu/i386/loadcore32.c +grub-core/efiemu/i386/loadcore64.c +grub-core/efiemu/i386/nocfgtables.c +grub-core/efiemu/i386/pc/cfgtables.c +grub-core/efiemu/loadcore32.c +grub-core/efiemu/loadcore64.c +grub-core/efiemu/loadcore.c +grub-core/efiemu/loadcore_common.c grub-core/efiemu/main.c - +grub-core/efiemu/mm.c +grub-core/efiemu/pnvram.c +grub-core/efiemu/prepare32.c +grub-core/efiemu/prepare64.c +grub-core/efiemu/prepare.c +grub-core/efiemu/runtime/efiemu.c +grub-core/efiemu/symbols.c +grub-core/font/font.c grub-core/font/font_cmd.c - +grub-core/fs/affs.c +grub-core/fs/afs_be.c +grub-core/fs/afs.c +grub-core/fs/befs_be.c +grub-core/fs/befs.c +grub-core/fs/btrfs.c +grub-core/fs/cpio.c +grub-core/fs/ext2.c +grub-core/fs/fat.c +grub-core/fs/fshelp.c +grub-core/fs/hfs.c +grub-core/fs/hfsplus.c +grub-core/fs/iso9660.c +grub-core/fs/jfs.c +grub-core/fs/minix2.c +grub-core/fs/minix3.c +grub-core/fs/minix.c +grub-core/fs/nilfs2.c +grub-core/fs/ntfs.c +grub-core/fs/ntfscomp.c +grub-core/fs/reiserfs.c +grub-core/fs/romfs.c +grub-core/fs/sfs.c +grub-core/fs/squash4.c +grub-core/fs/tar.c +grub-core/fs/udf.c +grub-core/fs/ufs2.c +grub-core/fs/ufs.c +grub-core/fs/xfs.c +grub-core/fs/zfs/zfs.c +grub-core/fs/zfs/zfs_fletcher.c +grub-core/fs/zfs/zfsinfo.c +grub-core/fs/zfs/zfs_lzjb.c +grub-core/fs/zfs/zfs_sha256.c +grub-core/gentrigtables.c grub-core/gettext/gettext.c - +grub-core/gfxmenu/font.c +grub-core/gfxmenu/gfxmenu.c +grub-core/gfxmenu/gui_box.c +grub-core/gfxmenu/gui_canvas.c +grub-core/gfxmenu/gui_circular_progress.c +grub-core/gfxmenu/gui_image.c +grub-core/gfxmenu/gui_label.c +grub-core/gfxmenu/gui_list.c grub-core/gfxmenu/gui_progress_bar.c - +grub-core/gfxmenu/gui_string_util.c +grub-core/gfxmenu/gui_util.c +grub-core/gfxmenu/icon_manager.c +grub-core/gfxmenu/model.c +grub-core/gfxmenu/theme_loader.c +grub-core/gfxmenu/view.c +grub-core/gfxmenu/widget-box.c grub-core/hello/hello.c - +grub-core/hook/datehook.c +grub-core/io/bufio.c +grub-core/io/gzio.c +grub-core/io/xzio.c +grub-core/kern/command.c grub-core/kern/corecmd.c +grub-core/kern/device.c +grub-core/kern/disk.c +grub-core/kern/dl.c +grub-core/kern/efi/efi.c +grub-core/kern/efi/init.c +grub-core/kern/efi/mm.c +grub-core/kern/elf.c +grub-core/kern/emu/cache.c +grub-core/kern/emu/console.c +grub-core/kern/emu/full.c +grub-core/kern/emu/getroot.c grub-core/kern/emu/hostdisk.c +grub-core/kern/emu/hostfs.c +grub-core/kern/emu/lite.c +grub-core/kern/emu/main.c grub-core/kern/emu/misc.c +grub-core/kern/emu/mm.c +grub-core/kern/emu/time.c +grub-core/kern/env.c grub-core/kern/err.c - +grub-core/kern/file.c +grub-core/kern/fs.c +grub-core/kern/generic/millisleep.c +grub-core/kern/generic/rtc_get_time_ms.c +grub-core/kern/i386/coreboot/init.c +grub-core/kern/i386/coreboot/mmap.c +grub-core/kern/i386/dl.c +grub-core/kern/i386/efi/init.c +grub-core/kern/i386/multiboot_mmap.c +grub-core/kern/i386/pc/init.c +grub-core/kern/i386/pc/mmap.c +grub-core/kern/i386/pit.c +grub-core/kern/i386/qemu/mmap.c +grub-core/kern/i386/tsc.c +grub-core/kern/ia64/dl.c +grub-core/kern/ia64/dl_helper.c +grub-core/kern/ia64/efi/init.c +grub-core/kern/ieee1275/cmain.c +grub-core/kern/ieee1275/ieee1275.c +grub-core/kern/ieee1275/init.c +grub-core/kern/ieee1275/mmap.c +grub-core/kern/ieee1275/openfw.c +grub-core/kern/list.c +grub-core/kern/main.c +grub-core/kern/mips/arc/init.c +grub-core/kern/mips/dl.c +grub-core/kern/mips/init.c +grub-core/kern/mips/loongson/init.c +grub-core/kern/mips/qemu_mips/init.c +grub-core/kern/misc.c +grub-core/kern/mm.c +grub-core/kern/parser.c +grub-core/kern/partition.c +grub-core/kern/powerpc/dl.c +grub-core/kern/rescue_parser.c +grub-core/kern/rescue_reader.c +grub-core/kern/sparc64/dl.c +grub-core/kern/sparc64/ieee1275/ieee1275.c +grub-core/kern/term.c +grub-core/kern/time.c +grub-core/kern/vga_init.c +grub-core/kern/x86_64/dl.c +grub-core/lib/arc/datetime.c grub-core/lib/arg.c - +grub-core/lib/cmdline.c +grub-core/lib/cmos_datetime.c +grub-core/lib/crc.c +grub-core/lib/crypto.c +grub-core/lib/efi/datetime.c +grub-core/lib/efi/halt.c +grub-core/lib/efi/relocator.c +grub-core/lib/emu/halt.c +grub-core/lib/envblk.c +grub-core/lib/hexdump.c +grub-core/lib/i386/halt.c +grub-core/lib/i386/pc/biosnum.c +grub-core/lib/i386/pc/vesa_modes_table.c +grub-core/lib/i386/relocator.c +grub-core/lib/ieee1275/cmos.c +grub-core/lib/ieee1275/datetime.c +grub-core/lib/ieee1275/halt.c +grub-core/lib/ieee1275/relocator.c +grub-core/lib/legacy_parse.c +grub-core/lib/LzFind.c +grub-core/lib/LzmaDec.c +grub-core/lib/LzmaEnc.c +grub-core/lib/mips/relocator.c +grub-core/lib/pbkdf2.c +grub-core/lib/powerpc/relocator.c +grub-core/lib/reed_solomon.c +grub-core/lib/relocator.c +grub-core/lib/xzembed/xz_dec_bcj.c +grub-core/lib/xzembed/xz_dec_lzma2.c +grub-core/lib/xzembed/xz_dec_stream.c +grub-core/loader/aout.c grub-core/loader/efi/appleloader.c grub-core/loader/efi/chainloader.c +grub-core/loader/i386/bsd32.c +grub-core/loader/i386/bsd64.c grub-core/loader/i386/bsd.c +grub-core/loader/i386/bsd_pagetable.c +grub-core/loader/i386/bsdXX.c +grub-core/loader/i386/coreboot/chainloader.c grub-core/loader/i386/linux.c +grub-core/loader/i386/multiboot_mbi.c grub-core/loader/i386/pc/chainloader.c +grub-core/loader/i386/pc/freedos.c grub-core/loader/i386/pc/linux.c grub-core/loader/i386/pc/ntldr.c grub-core/loader/i386/xnu.c +grub-core/loader/ia64/efi/linux.c +grub-core/loader/macho32.c +grub-core/loader/macho64.c +grub-core/loader/macho.c +grub-core/loader/machoXX.c grub-core/loader/mips/linux.c grub-core/loader/multiboot.c +grub-core/loader/multiboot_elfxx.c +grub-core/loader/multiboot_mbi2.c grub-core/loader/powerpc/ieee1275/linux.c grub-core/loader/sparc64/ieee1275/linux.c grub-core/loader/xnu.c - +grub-core/loader/xnu_resume.c +grub-core/mmap/efi/mmap.c +grub-core/mmap/i386/mmap.c +grub-core/mmap/i386/pc/mmap.c +grub-core/mmap/i386/uppermem.c +grub-core/mmap/mips/uppermem.c grub-core/mmap/mmap.c - +grub-core/net/arp.c +grub-core/net/bootp.c +grub-core/net/drivers/efi/efinet.c +grub-core/net/drivers/emu/emunet.c +grub-core/net/drivers/i386/pc/pxe.c +grub-core/net/drivers/ieee1275/ofnet.c +grub-core/net/ethernet.c +grub-core/net/ip.c +grub-core/net/netbuff.c +grub-core/net/net.c +grub-core/net/tftp.c +grub-core/net/udp.c grub-core/normal/auth.c +grub-core/normal/autofs.c +grub-core/normal/charset.c grub-core/normal/cmdline.c grub-core/normal/color.c +grub-core/normal/completion.c grub-core/normal/context.c +grub-core/normal/crypto.c +grub-core/normal/datetime.c grub-core/normal/dyncmd.c grub-core/normal/main.c grub-core/normal/menu.c grub-core/normal/menu_entry.c grub-core/normal/menu_text.c grub-core/normal/misc.c - +grub-core/normal/term.c +grub-core/partmap/acorn.c +grub-core/partmap/amiga.c +grub-core/partmap/apple.c +grub-core/partmap/bsdlabel.c +grub-core/partmap/dvh.c +grub-core/partmap/gpt.c +grub-core/partmap/msdos.c +grub-core/partmap/sun.c +grub-core/partmap/sunpc.c +grub-core/parttool/msdospart.c +grub-core/script/argv.c +grub-core/script/execute.c +grub-core/script/function.c +grub-core/script/lexer.c grub-core/script/main.c - +grub-core/script/script.c +grub-core/term/arc/console.c +grub-core/term/at_keyboard.c +grub-core/term/efi/console.c grub-core/term/gfxterm.c +grub-core/term/i386/pc/console.c +grub-core/term/i386/pc/vga_text.c +grub-core/term/i386/vga_common.c +grub-core/term/ieee1275/ofconsole.c +grub-core/term/ns8250.c grub-core/term/serial.c grub-core/term/terminfo.c - +grub-core/term/tparm.c +grub-core/term/usb_keyboard.c +grub-core/tests/example_functional_test.c +grub-core/tests/lib/functional_test.c +grub-core/tests/lib/test.c grub-core/tests/test_blockarg.c - +grub-core/video/bitmap.c +grub-core/video/bitmap_scale.c +grub-core/video/bochs.c +grub-core/video/cirrus.c +grub-core/video/colors.c +grub-core/video/efi_gop.c +grub-core/video/efi_uga.c +grub-core/video/emu/sdl.c +grub-core/video/fb/fbblit.c +grub-core/video/fb/fbfill.c +grub-core/video/fb/fbutil.c +grub-core/video/fb/video_fb.c +grub-core/video/i386/pc/vbe.c +grub-core/video/i386/pc/vga.c +grub-core/video/ieee1275.c +grub-core/video/readers/jpeg.c +grub-core/video/readers/png.c +grub-core/video/readers/tga.c +grub-core/video/sis315_init.c +grub-core/video/sis315pro.c +grub-core/video/sm712.c +grub-core/video/sm712_init.c +grub-core/video/video.c +tests/example_unit_test.c +tests/lib/unit_test.c +util/bin2h.c +util/deviceiter.c +util/devicemap.c util/grub-editenv.c util/grub-fstest.c +util/grub-macho2img.c +util/grub-menulst2cfg.c +util/grub-mkdevicemap.c +util/grub-mkfont.c util/grub-mkimage.c +util/grub-mkimagexx.c +util/grub-mklayout.c +util/grub-mkpasswd-pbkdf2.c +util/grub-mkrelpath.c +util/grub-pe2elf.c +util/grub-probe.c +util/grub-script-check.c util/grub-setup.c +util/ieee1275/devicemap.c +util/ieee1275/grub-ofpathname.c +util/ieee1275/ofpath.c +util/lvm.c +util/misc.c +util/raid.c +util/resolve.c From 0044d1db2e43943112aac3f3482e97d66584e645 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 7 Jul 2011 21:46:25 +0200 Subject: [PATCH 1161/1414] Simplify disk opening --- grub-core/disk/arc/arcdisk.c | 6 +++++- grub-core/disk/ata.c | 3 +-- grub-core/disk/efi/efidisk.c | 3 +-- grub-core/disk/host.c | 3 +-- grub-core/disk/i386/pc/biosdisk.c | 3 +-- grub-core/disk/ieee1275/nand.c | 3 +-- grub-core/disk/ieee1275/ofdisk.c | 3 +-- grub-core/disk/loopback.c | 3 +-- grub-core/disk/lvm.c | 6 ++---- grub-core/disk/memdisk.c | 3 +-- grub-core/disk/raid.c | 4 ++-- grub-core/disk/scsi.c | 3 +-- grub-core/kern/disk.c | 28 +++++++++------------------- grub-core/kern/emu/hostdisk.c | 3 +-- include/grub/disk.h | 4 +--- 15 files changed, 29 insertions(+), 49 deletions(-) diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c index 7dff30931..170bf521d 100644 --- a/grub-core/disk/arc/arcdisk.c +++ b/grub-core/disk/arc/arcdisk.c @@ -79,7 +79,8 @@ arcdisk_hash_add (char *devpath) static int -grub_arcdisk_iterate (int (*hook_in) (const char *name)) +grub_arcdisk_iterate (int (*hook_in) (const char *name), + grub_disk_pull_t pull) { auto int hook (const char *name, const struct grub_arc_component *comp); int hook (const char *name, const struct grub_arc_component *comp) @@ -90,6 +91,9 @@ grub_arcdisk_iterate (int (*hook_in) (const char *name)) return 0; return hook_in (name); } + if (pull != GRUB_DISK_PULL_NONE) + return 0; + return grub_arc_iterate_devs (hook, 1); } diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 9a09ee158..8add7f4de 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -412,8 +412,7 @@ grub_ata_iterate (int (*hook_in) (const char *name), } static grub_err_t -grub_ata_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_ata_open (const char *name, grub_disk_t disk) { unsigned id, bus; struct grub_ata *ata; diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 4ae1d7bb9..85969cc1d 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -454,8 +454,7 @@ get_device (struct grub_efidisk_data *devices, int num) } static grub_err_t -grub_efidisk_open (const char *name, struct grub_disk *disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_efidisk_open (const char *name, struct grub_disk *disk) { int num; struct grub_efidisk_data *d = 0; diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c index 5376cc6ce..5ee0d2e56 100644 --- a/grub-core/disk/host.c +++ b/grub-core/disk/host.c @@ -39,8 +39,7 @@ grub_host_iterate (int (*hook) (const char *name), } static grub_err_t -grub_host_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_host_open (const char *name, grub_disk_t disk) { if (grub_strcmp (name, "host")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk"); diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 1198d4305..e152b9d89 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -328,8 +328,7 @@ grub_biosdisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_biosdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_biosdisk_open (const char *name, grub_disk_t disk) { grub_uint64_t total_sectors = 0; int drive; diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c index 4be5b5641..94d62bc4f 100644 --- a/grub-core/disk/ieee1275/nand.c +++ b/grub-core/disk/ieee1275/nand.c @@ -58,8 +58,7 @@ grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf); static grub_err_t -grub_nand_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_nand_open (const char *name, grub_disk_t disk) { grub_ieee1275_ihandle_t dev_ihandle = 0; struct grub_nand_data *data = 0; diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 7b7db3a08..2cd43d80a 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -233,8 +233,7 @@ compute_dev_path (const char *name) } static grub_err_t -grub_ofdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_ofdisk_open (const char *name, grub_disk_t disk) { grub_ieee1275_phandle_t dev; char *devpath; diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index 21345af57..dca83b7c6 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -148,8 +148,7 @@ grub_loopback_iterate (int (*hook) (const char *name), } static grub_err_t -grub_loopback_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_loopback_open (const char *name, grub_disk_t disk) { struct grub_loopback *dev; diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 9e304c001..06e9f6d6a 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -181,8 +181,7 @@ find_lv (const char *name) static const char *scan_for = NULL; static grub_err_t -grub_lvm_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull) +grub_lvm_open (const char *name, grub_disk_t disk) { struct grub_lvm_lv *lv = NULL; int explicit = 0; @@ -192,8 +191,7 @@ grub_lvm_open (const char *name, grub_disk_t disk, lv = find_lv (name); - if (! lv && !scan_depth && - pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) + if (! lv && !scan_depth && explicit) { scan_for = name; scan_depth++; diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index 775234055..ed570c6a0 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -40,8 +40,7 @@ grub_memdisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_memdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_memdisk_open (const char *name, grub_disk_t disk) { if (grub_strcmp (name, "memdisk")) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk"); diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index a7d36bfb2..5d8326daf 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -257,7 +257,7 @@ find_array (const char *name) } static grub_err_t -grub_raid_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull) +grub_raid_open (const char *name, grub_disk_t disk) { struct grub_raid_array *array; unsigned n; @@ -268,7 +268,7 @@ grub_raid_open (const char *name, grub_disk_t disk, grub_disk_pull_t pull) array = find_array (name); - if (! array && pull == GRUB_DISK_PULL_RESCAN) + if (! array) { scan_devices (name); if (grub_errno) diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 5ab5177e9..610cc4dc5 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -371,8 +371,7 @@ grub_scsi_iterate (int (*hook) (const char *name), } static grub_err_t -grub_scsi_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_scsi_open (const char *name, grub_disk_t disk) { grub_scsi_dev_t p; grub_scsi_t scsi; diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index 022157434..5584030bd 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -206,13 +206,9 @@ grub_disk_dev_iterate (int (*hook) (const char *name)) grub_disk_pull_t pull; for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) - { - if (pull == GRUB_DISK_PULL_RESCAN_UNTYPED) - continue; - for (p = grub_disk_dev_list; p; p = p->next) - if (p->iterate && (p->iterate) (hook, pull)) - return 1; - } + for (p = grub_disk_dev_list; p; p = p->next) + if (p->iterate && (p->iterate) (hook, pull)) + return 1; return 0; } @@ -243,7 +239,6 @@ grub_disk_open (const char *name) grub_disk_dev_t dev; char *raw = (char *) name; grub_uint64_t current_time; - grub_disk_pull_t pull; grub_dprintf ("disk", "Opening `%s'...\n", name); @@ -270,19 +265,14 @@ grub_disk_open (const char *name) if (! disk->name) goto fail; - for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + for (dev = grub_disk_dev_list; dev; dev = dev->next) { - for (dev = grub_disk_dev_list; dev; dev = dev->next) - { - if ((dev->open) (raw, disk, pull) == GRUB_ERR_NONE) - break; - else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - grub_errno = GRUB_ERR_NONE; - else - goto fail; - } - if (dev) + if ((dev->open) (raw, disk) == GRUB_ERR_NONE) break; + else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + grub_errno = GRUB_ERR_NONE; + else + goto fail; } if (! dev) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index a2f9ce084..59d7a4a2c 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -227,8 +227,7 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_util_biosdisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_util_biosdisk_open (const char *name, grub_disk_t disk) { int drive; struct stat st; diff --git a/include/grub/disk.h b/include/grub/disk.h index efa27a4d2..2b6d02972 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -56,7 +56,6 @@ typedef enum GRUB_DISK_PULL_NONE, GRUB_DISK_PULL_REMOVABLE, GRUB_DISK_PULL_RESCAN, - GRUB_DISK_PULL_RESCAN_UNTYPED, GRUB_DISK_PULL_MAX } grub_disk_pull_t; @@ -74,8 +73,7 @@ struct grub_disk_dev grub_disk_pull_t pull); /* Open the device named NAME, and set up DISK. */ - grub_err_t (*open) (const char *name, struct grub_disk *disk, - grub_disk_pull_t pull); + grub_err_t (*open) (const char *name, struct grub_disk *disk); /* Close the disk DISK. */ void (*close) (struct grub_disk *disk); From cd8fe79a594a644773493ac339a4a1ebf73dd527 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Jul 2011 03:59:05 +0200 Subject: [PATCH 1162/1414] Fix compilation on GNU/Linux. * grub-core/kern/emu/getroot.c (grub_util_pull_device) [!FreeBSD]: Disable geli. (grub_util_get_grub_dev) [!FreeBSD]: Likewise. (grub_util_pull_device) [HAVE_DEVICE_MAPPER]: Fix const and func name. * grub-core/disk/cryptodisk.c (grub_cryptodisk_open): Fix proto. --- ChangeLog | 10 ++++++++++ grub-core/disk/cryptodisk.c | 3 +-- grub-core/kern/emu/getroot.c | 9 ++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b587dae2a..4bef20b13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-07-07 Vladimir Serbinenko + + Fix compilation on GNU/Linux. + + * grub-core/kern/emu/getroot.c (grub_util_pull_device) [!FreeBSD]: + Disable geli. + (grub_util_get_grub_dev) [!FreeBSD]: Likewise. + (grub_util_pull_device) [HAVE_DEVICE_MAPPER]: Fix const and func name. + * grub-core/disk/cryptodisk.c (grub_cryptodisk_open): Fix proto. + 2011-07-07 Vladimir Serbinenko 2011-07-07 Michael Gorven 2011-07-07 Clemens Fruhwirth diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 1a5e8164b..2852b65c4 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -413,8 +413,7 @@ grub_cryptodisk_iterate (int (*hook) (const char *name), } static grub_err_t -grub_cryptodisk_open (const char *name, grub_disk_t disk, - grub_disk_pull_t pull __attribute__ ((unused))) +grub_cryptodisk_open (const char *name, grub_disk_t disk) { grub_cryptodisk_t dev; diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index 380c5a7d1..9986fc5fc 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -975,6 +975,7 @@ grub_util_pull_device (const char *os_dev) switch (ab) { case GRUB_DEV_ABSTRACTION_GELI: +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) { char *whole; struct gmesh mesh; @@ -1035,8 +1036,8 @@ grub_util_pull_device (const char *os_dev) grub_free (grdev); } - } +#endif break; case GRUB_DEV_ABSTRACTION_LVM: @@ -1065,14 +1066,14 @@ grub_util_pull_device (const char *os_dev) grub_util_pull_device (subdev); } } - if (ab == GRUB_DEV_ABSTRACTION_CRYPTO && lastsubdev) + if (ab == GRUB_DEV_ABSTRACTION_LUKS && lastsubdev) { char *grdev = grub_util_get_grub_dev (lastsubdev); dm_tree_free (tree); if (grdev) { grub_err_t err; - err = grub_luks_cheat_mount (grdev, os_dev); + err = grub_cryptodisk_cheat_mount (grdev, os_dev); if (err) grub_util_error ("Can't mount crypto: %s", grub_errmsg); } @@ -1141,6 +1142,7 @@ grub_util_get_grub_dev (const char *os_dev) break; case GRUB_DEV_ABSTRACTION_GELI: +#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) { char *whole; struct gmesh mesh; @@ -1187,6 +1189,7 @@ grub_util_get_grub_dev (const char *os_dev) } } } +#endif break; case GRUB_DEV_ABSTRACTION_RAID: From def9832af6b454f077c01100155c6a787b0b5f4d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Jul 2011 04:06:02 +0200 Subject: [PATCH 1163/1414] * po/POTFILES.in: Regenerate. --- ChangeLog | 4 ++ po/POTFILES.in | 117 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4bef20b13..e86b3a4f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-08 Vladimir Serbinenko + + * po/POTFILES.in: Regenerate. + 2011-07-07 Vladimir Serbinenko Fix compilation on GNU/Linux. diff --git a/po/POTFILES.in b/po/POTFILES.in index 2bf4aa10c..83cb48b2c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -83,16 +83,20 @@ grub-core/commands/videoinfo.c grub-core/commands/videotest.c grub-core/commands/wildcard.c grub-core/commands/xnu_uuid.c +grub-core/disk/AFSplitter.c grub-core/disk/ahci.c grub-core/disk/arc/arcdisk.c grub-core/disk/ata.c +grub-core/disk/cryptodisk.c grub-core/disk/dmraid_nvidia.c grub-core/disk/efi/efidisk.c +grub-core/disk/geli.c grub-core/disk/host.c grub-core/disk/i386/pc/biosdisk.c grub-core/disk/ieee1275/nand.c grub-core/disk/ieee1275/ofdisk.c grub-core/disk/loopback.c +grub-core/disk/luks.c grub-core/disk/lvm.c grub-core/disk/mdraid1x_linux.c grub-core/disk/mdraid_linux.c @@ -174,6 +178,59 @@ grub-core/gfxmenu/model.c grub-core/gfxmenu/theme_loader.c grub-core/gfxmenu/view.c grub-core/gfxmenu/widget-box.c +grub-core/gnulib/alloca.c +grub-core/gnulib/argp-ba.c +grub-core/gnulib/argp-eexst.c +grub-core/gnulib/argp-fmtstream.c +grub-core/gnulib/argp-fs-xinl.c +grub-core/gnulib/argp-help.c +grub-core/gnulib/argp-parse.c +grub-core/gnulib/argp-pin.c +grub-core/gnulib/argp-pv.c +grub-core/gnulib/argp-pvh.c +grub-core/gnulib/argp-xinl.c +grub-core/gnulib/asnprintf.c +grub-core/gnulib/basename-lgpl.c +grub-core/gnulib/btowc.c +grub-core/gnulib/dirname-lgpl.c +grub-core/gnulib/error.c +grub-core/gnulib/fnmatch.c +grub-core/gnulib/fnmatch_loop.c +grub-core/gnulib/getdelim.c +grub-core/gnulib/getline.c +grub-core/gnulib/getopt1.c +grub-core/gnulib/getopt.c +grub-core/gnulib/localcharset.c +grub-core/gnulib/malloc.c +grub-core/gnulib/mbrtowc.c +grub-core/gnulib/mbsinit.c +grub-core/gnulib/mbsrtowcs.c +grub-core/gnulib/mbsrtowcs-state.c +grub-core/gnulib/memchr.c +grub-core/gnulib/mempcpy.c +grub-core/gnulib/nl_langinfo.c +grub-core/gnulib/printf-args.c +grub-core/gnulib/printf-parse.c +grub-core/gnulib/progname.c +grub-core/gnulib/rawmemchr.c +grub-core/gnulib/realloc.c +grub-core/gnulib/regcomp.c +grub-core/gnulib/regex.c +grub-core/gnulib/regexec.c +grub-core/gnulib/regex_internal.c +grub-core/gnulib/sleep.c +grub-core/gnulib/stdio-write.c +grub-core/gnulib/strcasecmp.c +grub-core/gnulib/strchrnul.c +grub-core/gnulib/strerror.c +grub-core/gnulib/stripslash.c +grub-core/gnulib/strncasecmp.c +grub-core/gnulib/strndup.c +grub-core/gnulib/strnlen1.c +grub-core/gnulib/strnlen.c +grub-core/gnulib/vasnprintf.c +grub-core/gnulib/vsnprintf.c +grub-core/gnulib/wcrtomb.c grub-core/hello/hello.c grub-core/hook/datehook.c grub-core/io/bufio.c @@ -198,6 +255,7 @@ grub-core/kern/emu/lite.c grub-core/kern/emu/main.c grub-core/kern/emu/misc.c grub-core/kern/emu/mm.c +grub-core/kern/emu/raid.c grub-core/kern/emu/time.c grub-core/kern/env.c grub-core/kern/err.c @@ -264,6 +322,63 @@ grub-core/lib/ieee1275/datetime.c grub-core/lib/ieee1275/halt.c grub-core/lib/ieee1275/relocator.c grub-core/lib/legacy_parse.c +grub-core/lib/libgcrypt/cipher/ac.c +grub-core/lib/libgcrypt/cipher/arcfour.c +grub-core/lib/libgcrypt/cipher/blowfish.c +grub-core/lib/libgcrypt/cipher/camellia.c +grub-core/lib/libgcrypt/cipher/camellia-glue.c +grub-core/lib/libgcrypt/cipher/cast5.c +grub-core/lib/libgcrypt/cipher/cipher.c +grub-core/lib/libgcrypt/cipher/crc.c +grub-core/lib/libgcrypt/cipher/des.c +grub-core/lib/libgcrypt/cipher/dsa.c +grub-core/lib/libgcrypt/cipher/ecc.c +grub-core/lib/libgcrypt/cipher/elgamal.c +grub-core/lib/libgcrypt/cipher/hash-common.c +grub-core/lib/libgcrypt/cipher/hmac-tests.c +grub-core/lib/libgcrypt/cipher/md4.c +grub-core/lib/libgcrypt/cipher/md5.c +grub-core/lib/libgcrypt/cipher/md.c +grub-core/lib/libgcrypt/cipher/primegen.c +grub-core/lib/libgcrypt/cipher/pubkey.c +grub-core/lib/libgcrypt/cipher/rfc2268.c +grub-core/lib/libgcrypt/cipher/rijndael.c +grub-core/lib/libgcrypt/cipher/rmd160.c +grub-core/lib/libgcrypt/cipher/rsa.c +grub-core/lib/libgcrypt/cipher/seed.c +grub-core/lib/libgcrypt/cipher/serpent.c +grub-core/lib/libgcrypt/cipher/sha1.c +grub-core/lib/libgcrypt/cipher/sha256.c +grub-core/lib/libgcrypt/cipher/sha512.c +grub-core/lib/libgcrypt/cipher/tiger.c +grub-core/lib/libgcrypt/cipher/twofish.c +grub-core/lib/libgcrypt/cipher/whirlpool.c +grub-core/lib/libgcrypt-grub/cipher/arcfour.c +grub-core/lib/libgcrypt-grub/cipher/blowfish.c +grub-core/lib/libgcrypt-grub/cipher/camellia.c +grub-core/lib/libgcrypt-grub/cipher/camellia-glue.c +grub-core/lib/libgcrypt-grub/cipher/cast5.c +grub-core/lib/libgcrypt-grub/cipher/crc.c +grub-core/lib/libgcrypt-grub/cipher/des.c +grub-core/lib/libgcrypt-grub/cipher/dsa.c +grub-core/lib/libgcrypt-grub/cipher/ecc.c +grub-core/lib/libgcrypt-grub/cipher/elgamal.c +grub-core/lib/libgcrypt-grub/cipher/init.c +grub-core/lib/libgcrypt-grub/cipher/md4.c +grub-core/lib/libgcrypt-grub/cipher/md5.c +grub-core/lib/libgcrypt-grub/cipher/primegen.c +grub-core/lib/libgcrypt-grub/cipher/rfc2268.c +grub-core/lib/libgcrypt-grub/cipher/rijndael.c +grub-core/lib/libgcrypt-grub/cipher/rmd160.c +grub-core/lib/libgcrypt-grub/cipher/rsa.c +grub-core/lib/libgcrypt-grub/cipher/seed.c +grub-core/lib/libgcrypt-grub/cipher/serpent.c +grub-core/lib/libgcrypt-grub/cipher/sha1.c +grub-core/lib/libgcrypt-grub/cipher/sha256.c +grub-core/lib/libgcrypt-grub/cipher/sha512.c +grub-core/lib/libgcrypt-grub/cipher/tiger.c +grub-core/lib/libgcrypt-grub/cipher/twofish.c +grub-core/lib/libgcrypt-grub/cipher/whirlpool.c grub-core/lib/LzFind.c grub-core/lib/LzmaDec.c grub-core/lib/LzmaEnc.c @@ -371,6 +486,7 @@ grub-core/tests/example_functional_test.c grub-core/tests/lib/functional_test.c grub-core/tests/lib/test.c grub-core/tests/test_blockarg.c +grub-core/unidata.c grub-core/video/bitmap.c grub-core/video/bitmap_scale.c grub-core/video/bochs.c @@ -419,5 +535,4 @@ util/ieee1275/grub-ofpathname.c util/ieee1275/ofpath.c util/lvm.c util/misc.c -util/raid.c util/resolve.c From 2e418de6460421240d5109b115b937694e6ba96e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Jul 2011 13:33:12 +0200 Subject: [PATCH 1164/1414] Remove getroot.c from core on emu platform. * grub-core/Makefile.core.def (kernel): Remove kern/emu/getroot.c and kern/emu/raid.c. * grub-core/kern/emu/main.c (main): Don't try to guess root device. It's useless. * grub-core/kern/emu/misc.c (get_win32_path): Moved from here... * util/getroot.c (get_win32_path): ... here. * grub-core/kern/emu/misc.c (fini_libzfs): Moved from here... * util/getroot.c (fini_libzfs): ... here. * grub-core/kern/emu/misc.c (grub_get_libzfs_handle): Moved from here... * util/getroot.c (grub_get_libzfs_handle): ... here. * grub-core/kern/emu/misc.c (grub_find_zpool_from_dir): Moved from here... * util/getroot.c (grub_find_zpool_from_dir): ... here. * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Moved from here... * util/getroot.c (grub_make_system_path_relative_to_its_root): ... here. * grub-core/kern/emu/getroot.c: Moved from here ... * util/getroot.c: ... here. All users updated. * grub-core/kern/emu/raid.c: Moved from here ... * util/raid.c: ... here. All users updated. --- ChangeLog | 25 +++ Makefile.util.def | 4 +- grub-core/Makefile.core.def | 2 - grub-core/kern/emu/main.c | 21 +- grub-core/kern/emu/misc.c | 267 ------------------------- {grub-core/kern/emu => util}/getroot.c | 259 ++++++++++++++++++++++++ {grub-core/kern/emu => util}/raid.c | 0 7 files changed, 289 insertions(+), 289 deletions(-) rename {grub-core/kern/emu => util}/getroot.c (84%) rename {grub-core/kern/emu => util}/raid.c (100%) diff --git a/ChangeLog b/ChangeLog index e86b3a4f1..33c5b0b92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2011-07-08 Vladimir Serbinenko + + Remove getroot.c from core on emu platform. + + * grub-core/Makefile.core.def (kernel): Remove kern/emu/getroot.c and + kern/emu/raid.c. + * grub-core/kern/emu/main.c (main): Don't try to guess root device. It's + useless. + * grub-core/kern/emu/misc.c (get_win32_path): Moved from here... + * util/getroot.c (get_win32_path): ... here. + * grub-core/kern/emu/misc.c (fini_libzfs): Moved from here... + * util/getroot.c (fini_libzfs): ... here. + * grub-core/kern/emu/misc.c (grub_get_libzfs_handle): Moved from here... + * util/getroot.c (grub_get_libzfs_handle): ... here. + * grub-core/kern/emu/misc.c (grub_find_zpool_from_dir): + Moved from here... + * util/getroot.c (grub_find_zpool_from_dir): ... here. + * grub-core/kern/emu/misc.c + (grub_make_system_path_relative_to_its_root): Moved from here... + * util/getroot.c (grub_make_system_path_relative_to_its_root): ... here. + * grub-core/kern/emu/getroot.c: Moved from here ... + * util/getroot.c: ... here. All users updated. + * grub-core/kern/emu/raid.c: Moved from here ... + * util/raid.c: ... here. All users updated. + 2011-07-08 Vladimir Serbinenko * po/POTFILES.in: Regenerate. diff --git a/Makefile.util.def b/Makefile.util.def index 18dd2fef8..c87020493 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -9,8 +9,8 @@ library = { common = grub-core/kern/command.c; common = grub-core/kern/device.c; common = grub-core/kern/disk.c; - common = grub-core/kern/emu/getroot.c; - common = grub-core/kern/emu/raid.c; + common = util/getroot.c; + common = util/raid.c; common = grub-core/kern/emu/hostdisk.c; common = grub-core/kern/emu/misc.c; common = grub-core/kern/emu/mm.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7200bd3e9..0924602f3 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -195,8 +195,6 @@ kernel = { emu = gnulib/error.c; emu = kern/emu/cache_s.S; emu = kern/emu/console.c; - emu = kern/emu/getroot.c; - emu = kern/emu/raid.c; emu = kern/emu/hostdisk.c; emu = kern/emu/hostfs.c; emu = kern/emu/main.c; diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 2092d03cb..9a58acd9e 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -111,7 +111,7 @@ usage (int status) "\n" "GRUB emulator.\n" "\n" - " -r, --root-device=DEV use DEV as the root device [default=guessed]\n" + " -r, --root-device=DEV use DEV as the root device [default=host]\n" " -m, --device-map=FILE use FILE as the device map [default=%s]\n" " -d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n" " -v, --verbose print verbose messages\n" @@ -204,24 +204,9 @@ main (int argc, char *argv[]) /* Make sure that there is a root device. */ if (! root_dev) - { - char *device_name = grub_guess_root_device (dir); - if (! device_name) - grub_util_error ("cannot find a device for %s", dir); + root_dev = grub_strdup ("host"); - root_dev = grub_util_get_grub_dev (device_name); - if (! root_dev) - { - grub_util_info ("guessing the root device failed, because of `%s'", - grub_errmsg); - grub_util_error ("cannot guess the root device. Specify the option `--root-device'"); - } - } - - if (strcmp (root_dev, "host") == 0) - dir = xstrdup (dir); - else - dir = grub_make_system_path_relative_to_its_root (dir); + dir = xstrdup (dir); /* Start GRUB! */ if (setjmp (main_env) == 0) diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 44c40b010..737f5f1a9 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -46,14 +46,6 @@ # include #endif -#ifdef HAVE_LIBZFS -# include -#endif - -#ifdef HAVE_LIBNVPAIR -# include -#endif - #ifdef HAVE_SYS_PARAM_H # include #endif @@ -242,265 +234,6 @@ canonicalize_file_name (const char *path) return ret; } -#ifdef __CYGWIN__ -/* Convert POSIX path to Win32 path, - remove drive letter, replace backslashes. */ -static char * -get_win32_path (const char *path) -{ - char winpath[PATH_MAX]; - if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) - grub_util_error ("cygwin_conv_path() failed"); - - int len = strlen (winpath); - int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); - - int i; - for (i = offs; i < len; i++) - if (winpath[i] == '\\') - winpath[i] = '/'; - return xstrdup (winpath + offs); -} -#endif - -#ifdef HAVE_LIBZFS -static libzfs_handle_t *__libzfs_handle; - -static void -fini_libzfs (void) -{ - libzfs_fini (__libzfs_handle); -} - -libzfs_handle_t * -grub_get_libzfs_handle (void) -{ - if (! __libzfs_handle) - { - __libzfs_handle = libzfs_init (); - - if (__libzfs_handle) - atexit (fini_libzfs); - } - - return __libzfs_handle; -} -#endif /* HAVE_LIBZFS */ - -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) -/* ZFS has similar problems to those of btrfs (see above). */ -void -grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) -{ - char *slash; - - *poolname = *poolfs = NULL; - -#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && defined(HAVE_STRUCT_STATFS_F_MNTFROMNAME) - /* FreeBSD and GNU/kFreeBSD. */ - { - struct statfs mnt; - - if (statfs (dir, &mnt) != 0) - return; - - if (strcmp (mnt.f_fstypename, "zfs") != 0) - return; - - *poolname = xstrdup (mnt.f_mntfromname); - } -#elif defined(HAVE_GETEXTMNTENT) - /* Solaris. */ - { - struct stat st; - struct extmnttab mnt; - - if (stat (dir, &st) != 0) - return; - - FILE *mnttab = fopen ("/etc/mnttab", "r"); - if (! mnttab) - return; - - while (getextmntent (mnttab, &mnt, sizeof (mnt)) == 0) - { - if (makedev (mnt.mnt_major, mnt.mnt_minor) == st.st_dev - && !strcmp (mnt.mnt_fstype, "zfs")) - { - *poolname = xstrdup (mnt.mnt_special); - break; - } - } - - fclose (mnttab); - } -#endif - - if (! *poolname) - return; - - slash = strchr (*poolname, '/'); - if (slash) - { - *slash = '\0'; - *poolfs = xstrdup (slash + 1); - } - else - *poolfs = xstrdup (""); -} -#endif - -/* This function never prints trailing slashes (so that its output - can be appended a slash unconditionally). */ -char * -grub_make_system_path_relative_to_its_root (const char *path) -{ - struct stat st; - char *p, *buf, *buf2, *buf3, *ret; - uintptr_t offset = 0; - dev_t num; - size_t len; - -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - char *poolfs = NULL; -#endif - - /* canonicalize. */ - p = canonicalize_file_name (path); - if (p == NULL) - grub_util_error ("failed to get canonical path of %s", path); - -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ - { - char *dummy; - grub_find_zpool_from_dir (p, &dummy, &poolfs); - } -#endif - - len = strlen (p) + 1; - buf = xstrdup (p); - free (p); - - if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); - - buf2 = xstrdup (buf); - num = st.st_dev; - - /* This loop sets offset to the number of chars of the root - directory we're inspecting. */ - while (1) - { - p = strrchr (buf, '/'); - if (p == NULL) - /* This should never happen. */ - grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)"); - if (p != buf) - *p = 0; - else - *++p = 0; - - if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); - - /* buf is another filesystem; we found it. */ - if (st.st_dev != num) - { - /* offset == 0 means path given is the mount point. - This works around special-casing of "/" in Un*x. This function never - prints trailing slashes (so that its output can be appended a slash - unconditionally). Each slash in is considered a preceding slash, and - therefore the root directory is an empty string. */ - if (offset == 0) - { - free (buf); -#ifdef __linux__ - { - char *bind; - grub_free (grub_find_root_device_from_mountinfo (buf2, &bind)); - if (bind && bind[0] && bind[1]) - { - buf3 = bind; - goto parsedir; - } - grub_free (bind); - } -#endif - free (buf2); -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - if (poolfs) - return xasprintf ("/%s/@", poolfs); -#endif - return xstrdup (""); - } - else - break; - } - - offset = p - buf; - /* offset == 1 means root directory. */ - if (offset == 1) - { - /* Include leading slash. */ - offset = 0; - break; - } - } - free (buf); - buf3 = xstrdup (buf2 + offset); - buf2[offset] = 0; -#ifdef __linux__ - { - char *bind; - grub_free (grub_find_root_device_from_mountinfo (buf2, &bind)); - if (bind && bind[0] && bind[1]) - { - char *temp = buf3; - buf3 = grub_xasprintf ("%s%s%s", bind, buf3[0] == '/' ?"":"/", buf3); - grub_free (temp); - } - grub_free (bind); - } -#endif - - free (buf2); - -#ifdef __CYGWIN__ - if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) - { - /* Reached some mount point not below /cygdrive. - GRUB does not know Cygwin's emulated mounts, - convert to Win32 path. */ - grub_util_info ("Cygwin path = %s\n", buf3); - char * temp = get_win32_path (buf3); - free (buf3); - buf3 = temp; - } -#endif - - parsedir: - /* Remove trailing slashes, return empty string if root directory. */ - len = strlen (buf3); - while (len > 0 && buf3[len - 1] == '/') - { - buf3[len - 1] = '\0'; - len--; - } - -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) - if (poolfs) - { - ret = xasprintf ("/%s/@%s", poolfs, buf3); - free (buf3); - } - else -#endif - ret = buf3; - - return ret; -} - #ifdef HAVE_DEVICE_MAPPER static void device_mapper_null_log (int level __attribute__ ((unused)), const char *file __attribute__ ((unused)), diff --git a/grub-core/kern/emu/getroot.c b/util/getroot.c similarity index 84% rename from grub-core/kern/emu/getroot.c rename to util/getroot.c index 9986fc5fc..71064583f 100644 --- a/grub-core/kern/emu/getroot.c +++ b/util/getroot.c @@ -1330,3 +1330,262 @@ grub_util_check_char_device (const char *blk_dev) else return 0; } + +#ifdef __CYGWIN__ +/* Convert POSIX path to Win32 path, + remove drive letter, replace backslashes. */ +static char * +get_win32_path (const char *path) +{ + char winpath[PATH_MAX]; + if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) + grub_util_error ("cygwin_conv_path() failed"); + + int len = strlen (winpath); + int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); + + int i; + for (i = offs; i < len; i++) + if (winpath[i] == '\\') + winpath[i] = '/'; + return xstrdup (winpath + offs); +} +#endif + +#ifdef HAVE_LIBZFS +static libzfs_handle_t *__libzfs_handle; + +static void +fini_libzfs (void) +{ + libzfs_fini (__libzfs_handle); +} + +libzfs_handle_t * +grub_get_libzfs_handle (void) +{ + if (! __libzfs_handle) + { + __libzfs_handle = libzfs_init (); + + if (__libzfs_handle) + atexit (fini_libzfs); + } + + return __libzfs_handle; +} +#endif /* HAVE_LIBZFS */ + +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +/* ZFS has similar problems to those of btrfs (see above). */ +void +grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) +{ + char *slash; + + *poolname = *poolfs = NULL; + +#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && defined(HAVE_STRUCT_STATFS_F_MNTFROMNAME) + /* FreeBSD and GNU/kFreeBSD. */ + { + struct statfs mnt; + + if (statfs (dir, &mnt) != 0) + return; + + if (strcmp (mnt.f_fstypename, "zfs") != 0) + return; + + *poolname = xstrdup (mnt.f_mntfromname); + } +#elif defined(HAVE_GETEXTMNTENT) + /* Solaris. */ + { + struct stat st; + struct extmnttab mnt; + + if (stat (dir, &st) != 0) + return; + + FILE *mnttab = fopen ("/etc/mnttab", "r"); + if (! mnttab) + return; + + while (getextmntent (mnttab, &mnt, sizeof (mnt)) == 0) + { + if (makedev (mnt.mnt_major, mnt.mnt_minor) == st.st_dev + && !strcmp (mnt.mnt_fstype, "zfs")) + { + *poolname = xstrdup (mnt.mnt_special); + break; + } + } + + fclose (mnttab); + } +#endif + + if (! *poolname) + return; + + slash = strchr (*poolname, '/'); + if (slash) + { + *slash = '\0'; + *poolfs = xstrdup (slash + 1); + } + else + *poolfs = xstrdup (""); +} +#endif + +/* This function never prints trailing slashes (so that its output + can be appended a slash unconditionally). */ +char * +grub_make_system_path_relative_to_its_root (const char *path) +{ + struct stat st; + char *p, *buf, *buf2, *buf3, *ret; + uintptr_t offset = 0; + dev_t num; + size_t len; + +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + char *poolfs = NULL; +#endif + + /* canonicalize. */ + p = canonicalize_file_name (path); + if (p == NULL) + grub_util_error ("failed to get canonical path of %s", path); + +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ + { + char *dummy; + grub_find_zpool_from_dir (p, &dummy, &poolfs); + } +#endif + + len = strlen (p) + 1; + buf = xstrdup (p); + free (p); + + if (stat (buf, &st) < 0) + grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + + buf2 = xstrdup (buf); + num = st.st_dev; + + /* This loop sets offset to the number of chars of the root + directory we're inspecting. */ + while (1) + { + p = strrchr (buf, '/'); + if (p == NULL) + /* This should never happen. */ + grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)"); + if (p != buf) + *p = 0; + else + *++p = 0; + + if (stat (buf, &st) < 0) + grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + + /* buf is another filesystem; we found it. */ + if (st.st_dev != num) + { + /* offset == 0 means path given is the mount point. + This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in is considered a preceding slash, and + therefore the root directory is an empty string. */ + if (offset == 0) + { + free (buf); +#ifdef __linux__ + { + char *bind; + grub_free (grub_find_root_device_from_mountinfo (buf2, &bind)); + if (bind && bind[0] && bind[1]) + { + buf3 = bind; + goto parsedir; + } + grub_free (bind); + } +#endif + free (buf2); +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + if (poolfs) + return xasprintf ("/%s/@", poolfs); +#endif + return xstrdup (""); + } + else + break; + } + + offset = p - buf; + /* offset == 1 means root directory. */ + if (offset == 1) + { + /* Include leading slash. */ + offset = 0; + break; + } + } + free (buf); + buf3 = xstrdup (buf2 + offset); + buf2[offset] = 0; +#ifdef __linux__ + { + char *bind; + grub_free (grub_find_root_device_from_mountinfo (buf2, &bind)); + if (bind && bind[0] && bind[1]) + { + char *temp = buf3; + buf3 = grub_xasprintf ("%s%s%s", bind, buf3[0] == '/' ?"":"/", buf3); + grub_free (temp); + } + grub_free (bind); + } +#endif + + free (buf2); + +#ifdef __CYGWIN__ + if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) + { + /* Reached some mount point not below /cygdrive. + GRUB does not know Cygwin's emulated mounts, + convert to Win32 path. */ + grub_util_info ("Cygwin path = %s\n", buf3); + char * temp = get_win32_path (buf3); + free (buf3); + buf3 = temp; + } +#endif + + parsedir: + /* Remove trailing slashes, return empty string if root directory. */ + len = strlen (buf3); + while (len > 0 && buf3[len - 1] == '/') + { + buf3[len - 1] = '\0'; + len--; + } + +#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) + if (poolfs) + { + ret = xasprintf ("/%s/@%s", poolfs, buf3); + free (buf3); + } + else +#endif + ret = buf3; + + return ret; +} diff --git a/grub-core/kern/emu/raid.c b/util/raid.c similarity index 100% rename from grub-core/kern/emu/raid.c rename to util/raid.c From 16a2bab03c78d1f727ab48fe9af47abe6bea7b22 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Jul 2011 15:32:43 +0200 Subject: [PATCH 1165/1414] * util/grub-install.in: Source grub-mkconfig_lib. --- ChangeLog | 4 ++++ util/grub-install.in | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 33c5b0b92..96b48f2fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-10 Vladimir Serbinenko + + * util/grub-install.in: Source grub-mkconfig_lib. + 2011-07-08 Vladimir Serbinenko Remove getroot.c from core on emu platform. diff --git a/util/grub-install.in b/util/grub-install.in index 09894d0d0..711c9c7e2 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -59,6 +59,8 @@ update_nvram=yes removable=no efi_quiet= +. ${libdir}/@PACKAGE@/grub-mkconfig_lib + # Get GRUB_DISTRIBUTOR. if test -f "${sysconfdir}/default/grub" ; then . "${sysconfdir}/default/grub" From c4edd548324dd0c1bfdd5d8cc4566de25074fdb6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Jul 2011 15:33:57 +0200 Subject: [PATCH 1166/1414] * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix incorrect memory usage. --- ChangeLog | 5 +++++ grub-core/disk/efi/efidisk.c | 9 +++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96b48f2fe..cf2354f6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-10 Vladimir Serbinenko + + * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix + incorrect memory usage. + 2011-07-10 Vladimir Serbinenko * util/grub-install.in: Source grub-mkconfig_lib. diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 85969cc1d..0baeb8e4b 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -709,7 +709,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) { - grub_partition_t tpart = NULL; + char *partition_name = NULL; char *device_name; grub_efi_device_path_t *dup_dp, *dup_ldp; grub_efi_hard_drive_device_path_t hd; @@ -722,7 +722,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) if (grub_partition_get_start (part) == hd.partition_start && grub_partition_get_len (part) == hd.partition_size) { - tpart = part; + partition_name = grub_partition_get_name (part); return 1; } @@ -760,17 +760,14 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) } else { - char *partition_name; - grub_partition_iterate (parent, find_partition); - if (! tpart) + if (! partition_name) { grub_disk_close (parent); return 0; } - partition_name = grub_partition_get_name (tpart); device_name = grub_xasprintf ("%s,%s", parent->name, partition_name); grub_free (partition_name); } From e4bcf6258cd128aa81257ca8dd217596f9cd5771 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Jul 2011 15:56:56 +0200 Subject: [PATCH 1167/1414] * po/POTFILES.in: Regenerate. --- ChangeLog | 4 + po/POTFILES.in | 1076 ++++++++++++++++++++++++------------------------ 2 files changed, 542 insertions(+), 538 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf2354f6d..84167f226 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-10 Vladimir Serbinenko + + * po/POTFILES.in: Regenerate. + 2011-07-10 Vladimir Serbinenko * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix diff --git a/po/POTFILES.in b/po/POTFILES.in index 83cb48b2c..ebb0aadaa 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,538 +1,538 @@ -grub-core/boot/decompressor/minilib.c -grub-core/boot/decompressor/none.c -grub-core/boot/decompressor/xz.c -grub-core/bus/bonito.c -grub-core/bus/cs5536.c -grub-core/bus/emu/pci.c -grub-core/bus/pci.c -grub-core/bus/usb/emu/usb.c -grub-core/bus/usb/ohci.c -grub-core/bus/usb/serial/common.c -grub-core/bus/usb/serial/ftdi.c -grub-core/bus/usb/serial/pl2303.c -grub-core/bus/usb/uhci.c -grub-core/bus/usb/usb.c -grub-core/bus/usb/usbhub.c -grub-core/bus/usb/usbtrans.c -grub-core/commands/acpi.c -grub-core/commands/acpihalt.c -grub-core/commands/arc/lsdev.c -grub-core/commands/blocklist.c -grub-core/commands/boot.c -grub-core/commands/cat.c -grub-core/commands/cmp.c -grub-core/commands/configfile.c -grub-core/commands/date.c -grub-core/commands/echo.c -grub-core/commands/efi/acpi.c -grub-core/commands/efi/fixvideo.c -grub-core/commands/efi/loadbios.c -grub-core/commands/efi/lsefimmap.c -grub-core/commands/efi/lsefisystab.c -grub-core/commands/efi/lssal.c -grub-core/commands/extcmd.c -grub-core/commands/gptsync.c -grub-core/commands/halt.c -grub-core/commands/hashsum.c -grub-core/commands/hdparm.c -grub-core/commands/help.c -grub-core/commands/hexdump.c -grub-core/commands/i386/cmostest.c -grub-core/commands/i386/cpuid.c -grub-core/commands/i386/pc/acpi.c -grub-core/commands/i386/pc/drivemap.c -grub-core/commands/i386/pc/halt.c -grub-core/commands/i386/pc/lsapm.c -grub-core/commands/i386/pc/play.c -grub-core/commands/i386/pc/sendkey.c -grub-core/commands/ieee1275/suspend.c -grub-core/commands/iorw.c -grub-core/commands/keylayouts.c -grub-core/commands/keystatus.c -grub-core/commands/legacycfg.c -grub-core/commands/loadenv.c -grub-core/commands/lsacpi.c -grub-core/commands/ls.c -grub-core/commands/lsmmap.c -grub-core/commands/lspci.c -grub-core/commands/memrw.c -grub-core/commands/menuentry.c -grub-core/commands/minicmd.c -grub-core/commands/mips/loongson/lsspd.c -grub-core/commands/parttool.c -grub-core/commands/password.c -grub-core/commands/password_pbkdf2.c -grub-core/commands/probe.c -grub-core/commands/read.c -grub-core/commands/reboot.c -grub-core/commands/regexp.c -grub-core/commands/search.c -grub-core/commands/search_file.c -grub-core/commands/search_label.c -grub-core/commands/search_uuid.c -grub-core/commands/search_wrap.c -grub-core/commands/setpci.c -grub-core/commands/sleep.c -grub-core/commands/terminal.c -grub-core/commands/test.c -grub-core/commands/testload.c -grub-core/commands/time.c -grub-core/commands/true.c -grub-core/commands/usbtest.c -grub-core/commands/videoinfo.c -grub-core/commands/videotest.c -grub-core/commands/wildcard.c -grub-core/commands/xnu_uuid.c -grub-core/disk/AFSplitter.c -grub-core/disk/ahci.c -grub-core/disk/arc/arcdisk.c -grub-core/disk/ata.c -grub-core/disk/cryptodisk.c -grub-core/disk/dmraid_nvidia.c -grub-core/disk/efi/efidisk.c -grub-core/disk/geli.c -grub-core/disk/host.c -grub-core/disk/i386/pc/biosdisk.c -grub-core/disk/ieee1275/nand.c -grub-core/disk/ieee1275/ofdisk.c -grub-core/disk/loopback.c -grub-core/disk/luks.c -grub-core/disk/lvm.c -grub-core/disk/mdraid1x_linux.c -grub-core/disk/mdraid_linux.c -grub-core/disk/memdisk.c -grub-core/disk/pata.c -grub-core/disk/raid5_recover.c -grub-core/disk/raid6_recover.c -grub-core/disk/raid.c -grub-core/disk/scsi.c -grub-core/disk/usbms.c -grub-core/efiemu/i386/coredetect.c -grub-core/efiemu/i386/loadcore32.c -grub-core/efiemu/i386/loadcore64.c -grub-core/efiemu/i386/nocfgtables.c -grub-core/efiemu/i386/pc/cfgtables.c -grub-core/efiemu/loadcore32.c -grub-core/efiemu/loadcore64.c -grub-core/efiemu/loadcore.c -grub-core/efiemu/loadcore_common.c -grub-core/efiemu/main.c -grub-core/efiemu/mm.c -grub-core/efiemu/pnvram.c -grub-core/efiemu/prepare32.c -grub-core/efiemu/prepare64.c -grub-core/efiemu/prepare.c -grub-core/efiemu/runtime/efiemu.c -grub-core/efiemu/symbols.c -grub-core/font/font.c -grub-core/font/font_cmd.c -grub-core/fs/affs.c -grub-core/fs/afs_be.c -grub-core/fs/afs.c -grub-core/fs/befs_be.c -grub-core/fs/befs.c -grub-core/fs/btrfs.c -grub-core/fs/cpio.c -grub-core/fs/ext2.c -grub-core/fs/fat.c -grub-core/fs/fshelp.c -grub-core/fs/hfs.c -grub-core/fs/hfsplus.c -grub-core/fs/iso9660.c -grub-core/fs/jfs.c -grub-core/fs/minix2.c -grub-core/fs/minix3.c -grub-core/fs/minix.c -grub-core/fs/nilfs2.c -grub-core/fs/ntfs.c -grub-core/fs/ntfscomp.c -grub-core/fs/reiserfs.c -grub-core/fs/romfs.c -grub-core/fs/sfs.c -grub-core/fs/squash4.c -grub-core/fs/tar.c -grub-core/fs/udf.c -grub-core/fs/ufs2.c -grub-core/fs/ufs.c -grub-core/fs/xfs.c -grub-core/fs/zfs/zfs.c -grub-core/fs/zfs/zfs_fletcher.c -grub-core/fs/zfs/zfsinfo.c -grub-core/fs/zfs/zfs_lzjb.c -grub-core/fs/zfs/zfs_sha256.c -grub-core/gentrigtables.c -grub-core/gettext/gettext.c -grub-core/gfxmenu/font.c -grub-core/gfxmenu/gfxmenu.c -grub-core/gfxmenu/gui_box.c -grub-core/gfxmenu/gui_canvas.c -grub-core/gfxmenu/gui_circular_progress.c -grub-core/gfxmenu/gui_image.c -grub-core/gfxmenu/gui_label.c -grub-core/gfxmenu/gui_list.c -grub-core/gfxmenu/gui_progress_bar.c -grub-core/gfxmenu/gui_string_util.c -grub-core/gfxmenu/gui_util.c -grub-core/gfxmenu/icon_manager.c -grub-core/gfxmenu/model.c -grub-core/gfxmenu/theme_loader.c -grub-core/gfxmenu/view.c -grub-core/gfxmenu/widget-box.c -grub-core/gnulib/alloca.c -grub-core/gnulib/argp-ba.c -grub-core/gnulib/argp-eexst.c -grub-core/gnulib/argp-fmtstream.c -grub-core/gnulib/argp-fs-xinl.c -grub-core/gnulib/argp-help.c -grub-core/gnulib/argp-parse.c -grub-core/gnulib/argp-pin.c -grub-core/gnulib/argp-pv.c -grub-core/gnulib/argp-pvh.c -grub-core/gnulib/argp-xinl.c -grub-core/gnulib/asnprintf.c -grub-core/gnulib/basename-lgpl.c -grub-core/gnulib/btowc.c -grub-core/gnulib/dirname-lgpl.c -grub-core/gnulib/error.c -grub-core/gnulib/fnmatch.c -grub-core/gnulib/fnmatch_loop.c -grub-core/gnulib/getdelim.c -grub-core/gnulib/getline.c -grub-core/gnulib/getopt1.c -grub-core/gnulib/getopt.c -grub-core/gnulib/localcharset.c -grub-core/gnulib/malloc.c -grub-core/gnulib/mbrtowc.c -grub-core/gnulib/mbsinit.c -grub-core/gnulib/mbsrtowcs.c -grub-core/gnulib/mbsrtowcs-state.c -grub-core/gnulib/memchr.c -grub-core/gnulib/mempcpy.c -grub-core/gnulib/nl_langinfo.c -grub-core/gnulib/printf-args.c -grub-core/gnulib/printf-parse.c -grub-core/gnulib/progname.c -grub-core/gnulib/rawmemchr.c -grub-core/gnulib/realloc.c -grub-core/gnulib/regcomp.c -grub-core/gnulib/regex.c -grub-core/gnulib/regexec.c -grub-core/gnulib/regex_internal.c -grub-core/gnulib/sleep.c -grub-core/gnulib/stdio-write.c -grub-core/gnulib/strcasecmp.c -grub-core/gnulib/strchrnul.c -grub-core/gnulib/strerror.c -grub-core/gnulib/stripslash.c -grub-core/gnulib/strncasecmp.c -grub-core/gnulib/strndup.c -grub-core/gnulib/strnlen1.c -grub-core/gnulib/strnlen.c -grub-core/gnulib/vasnprintf.c -grub-core/gnulib/vsnprintf.c -grub-core/gnulib/wcrtomb.c -grub-core/hello/hello.c -grub-core/hook/datehook.c -grub-core/io/bufio.c -grub-core/io/gzio.c -grub-core/io/xzio.c -grub-core/kern/command.c -grub-core/kern/corecmd.c -grub-core/kern/device.c -grub-core/kern/disk.c -grub-core/kern/dl.c -grub-core/kern/efi/efi.c -grub-core/kern/efi/init.c -grub-core/kern/efi/mm.c -grub-core/kern/elf.c -grub-core/kern/emu/cache.c -grub-core/kern/emu/console.c -grub-core/kern/emu/full.c -grub-core/kern/emu/getroot.c -grub-core/kern/emu/hostdisk.c -grub-core/kern/emu/hostfs.c -grub-core/kern/emu/lite.c -grub-core/kern/emu/main.c -grub-core/kern/emu/misc.c -grub-core/kern/emu/mm.c -grub-core/kern/emu/raid.c -grub-core/kern/emu/time.c -grub-core/kern/env.c -grub-core/kern/err.c -grub-core/kern/file.c -grub-core/kern/fs.c -grub-core/kern/generic/millisleep.c -grub-core/kern/generic/rtc_get_time_ms.c -grub-core/kern/i386/coreboot/init.c -grub-core/kern/i386/coreboot/mmap.c -grub-core/kern/i386/dl.c -grub-core/kern/i386/efi/init.c -grub-core/kern/i386/multiboot_mmap.c -grub-core/kern/i386/pc/init.c -grub-core/kern/i386/pc/mmap.c -grub-core/kern/i386/pit.c -grub-core/kern/i386/qemu/mmap.c -grub-core/kern/i386/tsc.c -grub-core/kern/ia64/dl.c -grub-core/kern/ia64/dl_helper.c -grub-core/kern/ia64/efi/init.c -grub-core/kern/ieee1275/cmain.c -grub-core/kern/ieee1275/ieee1275.c -grub-core/kern/ieee1275/init.c -grub-core/kern/ieee1275/mmap.c -grub-core/kern/ieee1275/openfw.c -grub-core/kern/list.c -grub-core/kern/main.c -grub-core/kern/mips/arc/init.c -grub-core/kern/mips/dl.c -grub-core/kern/mips/init.c -grub-core/kern/mips/loongson/init.c -grub-core/kern/mips/qemu_mips/init.c -grub-core/kern/misc.c -grub-core/kern/mm.c -grub-core/kern/parser.c -grub-core/kern/partition.c -grub-core/kern/powerpc/dl.c -grub-core/kern/rescue_parser.c -grub-core/kern/rescue_reader.c -grub-core/kern/sparc64/dl.c -grub-core/kern/sparc64/ieee1275/ieee1275.c -grub-core/kern/term.c -grub-core/kern/time.c -grub-core/kern/vga_init.c -grub-core/kern/x86_64/dl.c -grub-core/lib/arc/datetime.c -grub-core/lib/arg.c -grub-core/lib/cmdline.c -grub-core/lib/cmos_datetime.c -grub-core/lib/crc.c -grub-core/lib/crypto.c -grub-core/lib/efi/datetime.c -grub-core/lib/efi/halt.c -grub-core/lib/efi/relocator.c -grub-core/lib/emu/halt.c -grub-core/lib/envblk.c -grub-core/lib/hexdump.c -grub-core/lib/i386/halt.c -grub-core/lib/i386/pc/biosnum.c -grub-core/lib/i386/pc/vesa_modes_table.c -grub-core/lib/i386/relocator.c -grub-core/lib/ieee1275/cmos.c -grub-core/lib/ieee1275/datetime.c -grub-core/lib/ieee1275/halt.c -grub-core/lib/ieee1275/relocator.c -grub-core/lib/legacy_parse.c -grub-core/lib/libgcrypt/cipher/ac.c -grub-core/lib/libgcrypt/cipher/arcfour.c -grub-core/lib/libgcrypt/cipher/blowfish.c -grub-core/lib/libgcrypt/cipher/camellia.c -grub-core/lib/libgcrypt/cipher/camellia-glue.c -grub-core/lib/libgcrypt/cipher/cast5.c -grub-core/lib/libgcrypt/cipher/cipher.c -grub-core/lib/libgcrypt/cipher/crc.c -grub-core/lib/libgcrypt/cipher/des.c -grub-core/lib/libgcrypt/cipher/dsa.c -grub-core/lib/libgcrypt/cipher/ecc.c -grub-core/lib/libgcrypt/cipher/elgamal.c -grub-core/lib/libgcrypt/cipher/hash-common.c -grub-core/lib/libgcrypt/cipher/hmac-tests.c -grub-core/lib/libgcrypt/cipher/md4.c -grub-core/lib/libgcrypt/cipher/md5.c -grub-core/lib/libgcrypt/cipher/md.c -grub-core/lib/libgcrypt/cipher/primegen.c -grub-core/lib/libgcrypt/cipher/pubkey.c -grub-core/lib/libgcrypt/cipher/rfc2268.c -grub-core/lib/libgcrypt/cipher/rijndael.c -grub-core/lib/libgcrypt/cipher/rmd160.c -grub-core/lib/libgcrypt/cipher/rsa.c -grub-core/lib/libgcrypt/cipher/seed.c -grub-core/lib/libgcrypt/cipher/serpent.c -grub-core/lib/libgcrypt/cipher/sha1.c -grub-core/lib/libgcrypt/cipher/sha256.c -grub-core/lib/libgcrypt/cipher/sha512.c -grub-core/lib/libgcrypt/cipher/tiger.c -grub-core/lib/libgcrypt/cipher/twofish.c -grub-core/lib/libgcrypt/cipher/whirlpool.c -grub-core/lib/libgcrypt-grub/cipher/arcfour.c -grub-core/lib/libgcrypt-grub/cipher/blowfish.c -grub-core/lib/libgcrypt-grub/cipher/camellia.c -grub-core/lib/libgcrypt-grub/cipher/camellia-glue.c -grub-core/lib/libgcrypt-grub/cipher/cast5.c -grub-core/lib/libgcrypt-grub/cipher/crc.c -grub-core/lib/libgcrypt-grub/cipher/des.c -grub-core/lib/libgcrypt-grub/cipher/dsa.c -grub-core/lib/libgcrypt-grub/cipher/ecc.c -grub-core/lib/libgcrypt-grub/cipher/elgamal.c -grub-core/lib/libgcrypt-grub/cipher/init.c -grub-core/lib/libgcrypt-grub/cipher/md4.c -grub-core/lib/libgcrypt-grub/cipher/md5.c -grub-core/lib/libgcrypt-grub/cipher/primegen.c -grub-core/lib/libgcrypt-grub/cipher/rfc2268.c -grub-core/lib/libgcrypt-grub/cipher/rijndael.c -grub-core/lib/libgcrypt-grub/cipher/rmd160.c -grub-core/lib/libgcrypt-grub/cipher/rsa.c -grub-core/lib/libgcrypt-grub/cipher/seed.c -grub-core/lib/libgcrypt-grub/cipher/serpent.c -grub-core/lib/libgcrypt-grub/cipher/sha1.c -grub-core/lib/libgcrypt-grub/cipher/sha256.c -grub-core/lib/libgcrypt-grub/cipher/sha512.c -grub-core/lib/libgcrypt-grub/cipher/tiger.c -grub-core/lib/libgcrypt-grub/cipher/twofish.c -grub-core/lib/libgcrypt-grub/cipher/whirlpool.c -grub-core/lib/LzFind.c -grub-core/lib/LzmaDec.c -grub-core/lib/LzmaEnc.c -grub-core/lib/mips/relocator.c -grub-core/lib/pbkdf2.c -grub-core/lib/powerpc/relocator.c -grub-core/lib/reed_solomon.c -grub-core/lib/relocator.c -grub-core/lib/xzembed/xz_dec_bcj.c -grub-core/lib/xzembed/xz_dec_lzma2.c -grub-core/lib/xzembed/xz_dec_stream.c -grub-core/loader/aout.c -grub-core/loader/efi/appleloader.c -grub-core/loader/efi/chainloader.c -grub-core/loader/i386/bsd32.c -grub-core/loader/i386/bsd64.c -grub-core/loader/i386/bsd.c -grub-core/loader/i386/bsd_pagetable.c -grub-core/loader/i386/bsdXX.c -grub-core/loader/i386/coreboot/chainloader.c -grub-core/loader/i386/linux.c -grub-core/loader/i386/multiboot_mbi.c -grub-core/loader/i386/pc/chainloader.c -grub-core/loader/i386/pc/freedos.c -grub-core/loader/i386/pc/linux.c -grub-core/loader/i386/pc/ntldr.c -grub-core/loader/i386/xnu.c -grub-core/loader/ia64/efi/linux.c -grub-core/loader/macho32.c -grub-core/loader/macho64.c -grub-core/loader/macho.c -grub-core/loader/machoXX.c -grub-core/loader/mips/linux.c -grub-core/loader/multiboot.c -grub-core/loader/multiboot_elfxx.c -grub-core/loader/multiboot_mbi2.c -grub-core/loader/powerpc/ieee1275/linux.c -grub-core/loader/sparc64/ieee1275/linux.c -grub-core/loader/xnu.c -grub-core/loader/xnu_resume.c -grub-core/mmap/efi/mmap.c -grub-core/mmap/i386/mmap.c -grub-core/mmap/i386/pc/mmap.c -grub-core/mmap/i386/uppermem.c -grub-core/mmap/mips/uppermem.c -grub-core/mmap/mmap.c -grub-core/net/arp.c -grub-core/net/bootp.c -grub-core/net/drivers/efi/efinet.c -grub-core/net/drivers/emu/emunet.c -grub-core/net/drivers/i386/pc/pxe.c -grub-core/net/drivers/ieee1275/ofnet.c -grub-core/net/ethernet.c -grub-core/net/ip.c -grub-core/net/netbuff.c -grub-core/net/net.c -grub-core/net/tftp.c -grub-core/net/udp.c -grub-core/normal/auth.c -grub-core/normal/autofs.c -grub-core/normal/charset.c -grub-core/normal/cmdline.c -grub-core/normal/color.c -grub-core/normal/completion.c -grub-core/normal/context.c -grub-core/normal/crypto.c -grub-core/normal/datetime.c -grub-core/normal/dyncmd.c -grub-core/normal/main.c -grub-core/normal/menu.c -grub-core/normal/menu_entry.c -grub-core/normal/menu_text.c -grub-core/normal/misc.c -grub-core/normal/term.c -grub-core/partmap/acorn.c -grub-core/partmap/amiga.c -grub-core/partmap/apple.c -grub-core/partmap/bsdlabel.c -grub-core/partmap/dvh.c -grub-core/partmap/gpt.c -grub-core/partmap/msdos.c -grub-core/partmap/sun.c -grub-core/partmap/sunpc.c -grub-core/parttool/msdospart.c -grub-core/script/argv.c -grub-core/script/execute.c -grub-core/script/function.c -grub-core/script/lexer.c -grub-core/script/main.c -grub-core/script/script.c -grub-core/term/arc/console.c -grub-core/term/at_keyboard.c -grub-core/term/efi/console.c -grub-core/term/gfxterm.c -grub-core/term/i386/pc/console.c -grub-core/term/i386/pc/vga_text.c -grub-core/term/i386/vga_common.c -grub-core/term/ieee1275/ofconsole.c -grub-core/term/ns8250.c -grub-core/term/serial.c -grub-core/term/terminfo.c -grub-core/term/tparm.c -grub-core/term/usb_keyboard.c -grub-core/tests/example_functional_test.c -grub-core/tests/lib/functional_test.c -grub-core/tests/lib/test.c -grub-core/tests/test_blockarg.c -grub-core/unidata.c -grub-core/video/bitmap.c -grub-core/video/bitmap_scale.c -grub-core/video/bochs.c -grub-core/video/cirrus.c -grub-core/video/colors.c -grub-core/video/efi_gop.c -grub-core/video/efi_uga.c -grub-core/video/emu/sdl.c -grub-core/video/fb/fbblit.c -grub-core/video/fb/fbfill.c -grub-core/video/fb/fbutil.c -grub-core/video/fb/video_fb.c -grub-core/video/i386/pc/vbe.c -grub-core/video/i386/pc/vga.c -grub-core/video/ieee1275.c -grub-core/video/readers/jpeg.c -grub-core/video/readers/png.c -grub-core/video/readers/tga.c -grub-core/video/sis315_init.c -grub-core/video/sis315pro.c -grub-core/video/sm712.c -grub-core/video/sm712_init.c -grub-core/video/video.c -tests/example_unit_test.c -tests/lib/unit_test.c -util/bin2h.c -util/deviceiter.c -util/devicemap.c -util/grub-editenv.c -util/grub-fstest.c -util/grub-macho2img.c -util/grub-menulst2cfg.c -util/grub-mkdevicemap.c -util/grub-mkfont.c -util/grub-mkimage.c -util/grub-mkimagexx.c -util/grub-mklayout.c -util/grub-mkpasswd-pbkdf2.c -util/grub-mkrelpath.c -util/grub-pe2elf.c -util/grub-probe.c -util/grub-script-check.c -util/grub-setup.c -util/ieee1275/devicemap.c -util/ieee1275/grub-ofpathname.c -util/ieee1275/ofpath.c -util/lvm.c -util/misc.c -util/resolve.c +./grub-core/boot/decompressor/minilib.c +./grub-core/boot/decompressor/none.c +./grub-core/boot/decompressor/xz.c +./grub-core/bus/bonito.c +./grub-core/bus/cs5536.c +./grub-core/bus/emu/pci.c +./grub-core/bus/pci.c +./grub-core/bus/usb/emu/usb.c +./grub-core/bus/usb/ohci.c +./grub-core/bus/usb/serial/common.c +./grub-core/bus/usb/serial/ftdi.c +./grub-core/bus/usb/serial/pl2303.c +./grub-core/bus/usb/uhci.c +./grub-core/bus/usb/usb.c +./grub-core/bus/usb/usbhub.c +./grub-core/bus/usb/usbtrans.c +./grub-core/commands/acpi.c +./grub-core/commands/acpihalt.c +./grub-core/commands/arc/lsdev.c +./grub-core/commands/blocklist.c +./grub-core/commands/boot.c +./grub-core/commands/cat.c +./grub-core/commands/cmp.c +./grub-core/commands/configfile.c +./grub-core/commands/date.c +./grub-core/commands/echo.c +./grub-core/commands/efi/acpi.c +./grub-core/commands/efi/fixvideo.c +./grub-core/commands/efi/loadbios.c +./grub-core/commands/efi/lsefimmap.c +./grub-core/commands/efi/lsefisystab.c +./grub-core/commands/efi/lssal.c +./grub-core/commands/extcmd.c +./grub-core/commands/gptsync.c +./grub-core/commands/halt.c +./grub-core/commands/hashsum.c +./grub-core/commands/hdparm.c +./grub-core/commands/help.c +./grub-core/commands/hexdump.c +./grub-core/commands/i386/cmostest.c +./grub-core/commands/i386/cpuid.c +./grub-core/commands/i386/pc/acpi.c +./grub-core/commands/i386/pc/drivemap.c +./grub-core/commands/i386/pc/halt.c +./grub-core/commands/i386/pc/lsapm.c +./grub-core/commands/i386/pc/play.c +./grub-core/commands/i386/pc/sendkey.c +./grub-core/commands/ieee1275/suspend.c +./grub-core/commands/iorw.c +./grub-core/commands/keylayouts.c +./grub-core/commands/keystatus.c +./grub-core/commands/legacycfg.c +./grub-core/commands/loadenv.c +./grub-core/commands/lsacpi.c +./grub-core/commands/ls.c +./grub-core/commands/lsmmap.c +./grub-core/commands/lspci.c +./grub-core/commands/memrw.c +./grub-core/commands/menuentry.c +./grub-core/commands/minicmd.c +./grub-core/commands/mips/loongson/lsspd.c +./grub-core/commands/parttool.c +./grub-core/commands/password.c +./grub-core/commands/password_pbkdf2.c +./grub-core/commands/probe.c +./grub-core/commands/read.c +./grub-core/commands/reboot.c +./grub-core/commands/regexp.c +./grub-core/commands/search.c +./grub-core/commands/search_file.c +./grub-core/commands/search_label.c +./grub-core/commands/search_uuid.c +./grub-core/commands/search_wrap.c +./grub-core/commands/setpci.c +./grub-core/commands/sleep.c +./grub-core/commands/terminal.c +./grub-core/commands/test.c +./grub-core/commands/testload.c +./grub-core/commands/time.c +./grub-core/commands/true.c +./grub-core/commands/usbtest.c +./grub-core/commands/videoinfo.c +./grub-core/commands/videotest.c +./grub-core/commands/wildcard.c +./grub-core/commands/xnu_uuid.c +./grub-core/disk/AFSplitter.c +./grub-core/disk/ahci.c +./grub-core/disk/arc/arcdisk.c +./grub-core/disk/ata.c +./grub-core/disk/cryptodisk.c +./grub-core/disk/dmraid_nvidia.c +./grub-core/disk/efi/efidisk.c +./grub-core/disk/geli.c +./grub-core/disk/host.c +./grub-core/disk/i386/pc/biosdisk.c +./grub-core/disk/ieee1275/nand.c +./grub-core/disk/ieee1275/ofdisk.c +./grub-core/disk/loopback.c +./grub-core/disk/luks.c +./grub-core/disk/lvm.c +./grub-core/disk/mdraid1x_linux.c +./grub-core/disk/mdraid_linux.c +./grub-core/disk/memdisk.c +./grub-core/disk/pata.c +./grub-core/disk/raid5_recover.c +./grub-core/disk/raid6_recover.c +./grub-core/disk/raid.c +./grub-core/disk/scsi.c +./grub-core/disk/usbms.c +./grub-core/efiemu/i386/coredetect.c +./grub-core/efiemu/i386/loadcore32.c +./grub-core/efiemu/i386/loadcore64.c +./grub-core/efiemu/i386/nocfgtables.c +./grub-core/efiemu/i386/pc/cfgtables.c +./grub-core/efiemu/loadcore32.c +./grub-core/efiemu/loadcore64.c +./grub-core/efiemu/loadcore.c +./grub-core/efiemu/loadcore_common.c +./grub-core/efiemu/main.c +./grub-core/efiemu/mm.c +./grub-core/efiemu/pnvram.c +./grub-core/efiemu/prepare32.c +./grub-core/efiemu/prepare64.c +./grub-core/efiemu/prepare.c +./grub-core/efiemu/runtime/efiemu.c +./grub-core/efiemu/symbols.c +./grub-core/font/font.c +./grub-core/font/font_cmd.c +./grub-core/fs/affs.c +./grub-core/fs/afs_be.c +./grub-core/fs/afs.c +./grub-core/fs/befs_be.c +./grub-core/fs/befs.c +./grub-core/fs/btrfs.c +./grub-core/fs/cpio.c +./grub-core/fs/ext2.c +./grub-core/fs/fat.c +./grub-core/fs/fshelp.c +./grub-core/fs/hfs.c +./grub-core/fs/hfsplus.c +./grub-core/fs/iso9660.c +./grub-core/fs/jfs.c +./grub-core/fs/minix2.c +./grub-core/fs/minix3.c +./grub-core/fs/minix.c +./grub-core/fs/nilfs2.c +./grub-core/fs/ntfs.c +./grub-core/fs/ntfscomp.c +./grub-core/fs/reiserfs.c +./grub-core/fs/romfs.c +./grub-core/fs/sfs.c +./grub-core/fs/squash4.c +./grub-core/fs/tar.c +./grub-core/fs/udf.c +./grub-core/fs/ufs2.c +./grub-core/fs/ufs.c +./grub-core/fs/xfs.c +./grub-core/fs/zfs/zfs.c +./grub-core/fs/zfs/zfs_fletcher.c +./grub-core/fs/zfs/zfsinfo.c +./grub-core/fs/zfs/zfs_lzjb.c +./grub-core/fs/zfs/zfs_sha256.c +./grub-core/gentrigtables.c +./grub-core/gettext/gettext.c +./grub-core/gfxmenu/font.c +./grub-core/gfxmenu/gfxmenu.c +./grub-core/gfxmenu/gui_box.c +./grub-core/gfxmenu/gui_canvas.c +./grub-core/gfxmenu/gui_circular_progress.c +./grub-core/gfxmenu/gui_image.c +./grub-core/gfxmenu/gui_label.c +./grub-core/gfxmenu/gui_list.c +./grub-core/gfxmenu/gui_progress_bar.c +./grub-core/gfxmenu/gui_string_util.c +./grub-core/gfxmenu/gui_util.c +./grub-core/gfxmenu/icon_manager.c +./grub-core/gfxmenu/model.c +./grub-core/gfxmenu/theme_loader.c +./grub-core/gfxmenu/view.c +./grub-core/gfxmenu/widget-box.c +./grub-core/gnulib/alloca.c +./grub-core/gnulib/argp-ba.c +./grub-core/gnulib/argp-eexst.c +./grub-core/gnulib/argp-fmtstream.c +./grub-core/gnulib/argp-fs-xinl.c +./grub-core/gnulib/argp-help.c +./grub-core/gnulib/argp-parse.c +./grub-core/gnulib/argp-pin.c +./grub-core/gnulib/argp-pv.c +./grub-core/gnulib/argp-pvh.c +./grub-core/gnulib/argp-xinl.c +./grub-core/gnulib/asnprintf.c +./grub-core/gnulib/basename-lgpl.c +./grub-core/gnulib/btowc.c +./grub-core/gnulib/dirname-lgpl.c +./grub-core/gnulib/error.c +./grub-core/gnulib/fnmatch.c +./grub-core/gnulib/fnmatch_loop.c +./grub-core/gnulib/getdelim.c +./grub-core/gnulib/getline.c +./grub-core/gnulib/getopt1.c +./grub-core/gnulib/getopt.c +./grub-core/gnulib/localcharset.c +./grub-core/gnulib/malloc.c +./grub-core/gnulib/mbrtowc.c +./grub-core/gnulib/mbsinit.c +./grub-core/gnulib/mbsrtowcs.c +./grub-core/gnulib/mbsrtowcs-state.c +./grub-core/gnulib/memchr.c +./grub-core/gnulib/mempcpy.c +./grub-core/gnulib/nl_langinfo.c +./grub-core/gnulib/printf-args.c +./grub-core/gnulib/printf-parse.c +./grub-core/gnulib/progname.c +./grub-core/gnulib/rawmemchr.c +./grub-core/gnulib/realloc.c +./grub-core/gnulib/regcomp.c +./grub-core/gnulib/regex.c +./grub-core/gnulib/regexec.c +./grub-core/gnulib/regex_internal.c +./grub-core/gnulib/sleep.c +./grub-core/gnulib/stdio-write.c +./grub-core/gnulib/strcasecmp.c +./grub-core/gnulib/strchrnul.c +./grub-core/gnulib/strerror.c +./grub-core/gnulib/stripslash.c +./grub-core/gnulib/strncasecmp.c +./grub-core/gnulib/strndup.c +./grub-core/gnulib/strnlen1.c +./grub-core/gnulib/strnlen.c +./grub-core/gnulib/vasnprintf.c +./grub-core/gnulib/vsnprintf.c +./grub-core/gnulib/wcrtomb.c +./grub-core/hello/hello.c +./grub-core/hook/datehook.c +./grub-core/io/bufio.c +./grub-core/io/gzio.c +./grub-core/io/xzio.c +./grub-core/kern/command.c +./grub-core/kern/corecmd.c +./grub-core/kern/device.c +./grub-core/kern/disk.c +./grub-core/kern/dl.c +./grub-core/kern/efi/efi.c +./grub-core/kern/efi/init.c +./grub-core/kern/efi/mm.c +./grub-core/kern/elf.c +./grub-core/kern/emu/cache.c +./grub-core/kern/emu/console.c +./grub-core/kern/emu/full.c +./grub-core/kern/emu/hostdisk.c +./grub-core/kern/emu/hostfs.c +./grub-core/kern/emu/lite.c +./grub-core/kern/emu/main.c +./grub-core/kern/emu/misc.c +./grub-core/kern/emu/mm.c +./grub-core/kern/emu/time.c +./grub-core/kern/env.c +./grub-core/kern/err.c +./grub-core/kern/file.c +./grub-core/kern/fs.c +./grub-core/kern/generic/millisleep.c +./grub-core/kern/generic/rtc_get_time_ms.c +./grub-core/kern/i386/coreboot/init.c +./grub-core/kern/i386/coreboot/mmap.c +./grub-core/kern/i386/dl.c +./grub-core/kern/i386/efi/init.c +./grub-core/kern/i386/multiboot_mmap.c +./grub-core/kern/i386/pc/init.c +./grub-core/kern/i386/pc/mmap.c +./grub-core/kern/i386/pit.c +./grub-core/kern/i386/qemu/mmap.c +./grub-core/kern/i386/tsc.c +./grub-core/kern/ia64/dl.c +./grub-core/kern/ia64/dl_helper.c +./grub-core/kern/ia64/efi/init.c +./grub-core/kern/ieee1275/cmain.c +./grub-core/kern/ieee1275/ieee1275.c +./grub-core/kern/ieee1275/init.c +./grub-core/kern/ieee1275/mmap.c +./grub-core/kern/ieee1275/openfw.c +./grub-core/kern/list.c +./grub-core/kern/main.c +./grub-core/kern/mips/arc/init.c +./grub-core/kern/mips/dl.c +./grub-core/kern/mips/init.c +./grub-core/kern/mips/loongson/init.c +./grub-core/kern/mips/qemu_mips/init.c +./grub-core/kern/misc.c +./grub-core/kern/mm.c +./grub-core/kern/parser.c +./grub-core/kern/partition.c +./grub-core/kern/powerpc/dl.c +./grub-core/kern/rescue_parser.c +./grub-core/kern/rescue_reader.c +./grub-core/kern/sparc64/dl.c +./grub-core/kern/sparc64/ieee1275/ieee1275.c +./grub-core/kern/term.c +./grub-core/kern/time.c +./grub-core/kern/vga_init.c +./grub-core/kern/x86_64/dl.c +./grub-core/lib/arc/datetime.c +./grub-core/lib/arg.c +./grub-core/lib/cmdline.c +./grub-core/lib/cmos_datetime.c +./grub-core/lib/crc.c +./grub-core/lib/crypto.c +./grub-core/lib/efi/datetime.c +./grub-core/lib/efi/halt.c +./grub-core/lib/efi/relocator.c +./grub-core/lib/emu/halt.c +./grub-core/lib/envblk.c +./grub-core/lib/hexdump.c +./grub-core/lib/i386/halt.c +./grub-core/lib/i386/pc/biosnum.c +./grub-core/lib/i386/pc/vesa_modes_table.c +./grub-core/lib/i386/relocator.c +./grub-core/lib/ieee1275/cmos.c +./grub-core/lib/ieee1275/datetime.c +./grub-core/lib/ieee1275/halt.c +./grub-core/lib/ieee1275/relocator.c +./grub-core/lib/legacy_parse.c +./grub-core/lib/libgcrypt/cipher/ac.c +./grub-core/lib/libgcrypt/cipher/arcfour.c +./grub-core/lib/libgcrypt/cipher/blowfish.c +./grub-core/lib/libgcrypt/cipher/camellia.c +./grub-core/lib/libgcrypt/cipher/camellia-glue.c +./grub-core/lib/libgcrypt/cipher/cast5.c +./grub-core/lib/libgcrypt/cipher/cipher.c +./grub-core/lib/libgcrypt/cipher/crc.c +./grub-core/lib/libgcrypt/cipher/des.c +./grub-core/lib/libgcrypt/cipher/dsa.c +./grub-core/lib/libgcrypt/cipher/ecc.c +./grub-core/lib/libgcrypt/cipher/elgamal.c +./grub-core/lib/libgcrypt/cipher/hash-common.c +./grub-core/lib/libgcrypt/cipher/hmac-tests.c +./grub-core/lib/libgcrypt/cipher/md4.c +./grub-core/lib/libgcrypt/cipher/md5.c +./grub-core/lib/libgcrypt/cipher/md.c +./grub-core/lib/libgcrypt/cipher/primegen.c +./grub-core/lib/libgcrypt/cipher/pubkey.c +./grub-core/lib/libgcrypt/cipher/rfc2268.c +./grub-core/lib/libgcrypt/cipher/rijndael.c +./grub-core/lib/libgcrypt/cipher/rmd160.c +./grub-core/lib/libgcrypt/cipher/rsa.c +./grub-core/lib/libgcrypt/cipher/seed.c +./grub-core/lib/libgcrypt/cipher/serpent.c +./grub-core/lib/libgcrypt/cipher/sha1.c +./grub-core/lib/libgcrypt/cipher/sha256.c +./grub-core/lib/libgcrypt/cipher/sha512.c +./grub-core/lib/libgcrypt/cipher/tiger.c +./grub-core/lib/libgcrypt/cipher/twofish.c +./grub-core/lib/libgcrypt/cipher/whirlpool.c +./grub-core/lib/libgcrypt-grub/cipher/arcfour.c +./grub-core/lib/libgcrypt-grub/cipher/blowfish.c +./grub-core/lib/libgcrypt-grub/cipher/camellia.c +./grub-core/lib/libgcrypt-grub/cipher/camellia-glue.c +./grub-core/lib/libgcrypt-grub/cipher/cast5.c +./grub-core/lib/libgcrypt-grub/cipher/crc.c +./grub-core/lib/libgcrypt-grub/cipher/des.c +./grub-core/lib/libgcrypt-grub/cipher/dsa.c +./grub-core/lib/libgcrypt-grub/cipher/ecc.c +./grub-core/lib/libgcrypt-grub/cipher/elgamal.c +./grub-core/lib/libgcrypt-grub/cipher/init.c +./grub-core/lib/libgcrypt-grub/cipher/md4.c +./grub-core/lib/libgcrypt-grub/cipher/md5.c +./grub-core/lib/libgcrypt-grub/cipher/primegen.c +./grub-core/lib/libgcrypt-grub/cipher/rfc2268.c +./grub-core/lib/libgcrypt-grub/cipher/rijndael.c +./grub-core/lib/libgcrypt-grub/cipher/rmd160.c +./grub-core/lib/libgcrypt-grub/cipher/rsa.c +./grub-core/lib/libgcrypt-grub/cipher/seed.c +./grub-core/lib/libgcrypt-grub/cipher/serpent.c +./grub-core/lib/libgcrypt-grub/cipher/sha1.c +./grub-core/lib/libgcrypt-grub/cipher/sha256.c +./grub-core/lib/libgcrypt-grub/cipher/sha512.c +./grub-core/lib/libgcrypt-grub/cipher/tiger.c +./grub-core/lib/libgcrypt-grub/cipher/twofish.c +./grub-core/lib/libgcrypt-grub/cipher/whirlpool.c +./grub-core/lib/LzFind.c +./grub-core/lib/LzmaDec.c +./grub-core/lib/LzmaEnc.c +./grub-core/lib/mips/relocator.c +./grub-core/lib/pbkdf2.c +./grub-core/lib/powerpc/relocator.c +./grub-core/lib/reed_solomon.c +./grub-core/lib/relocator.c +./grub-core/lib/xzembed/xz_dec_bcj.c +./grub-core/lib/xzembed/xz_dec_lzma2.c +./grub-core/lib/xzembed/xz_dec_stream.c +./grub-core/loader/aout.c +./grub-core/loader/efi/appleloader.c +./grub-core/loader/efi/chainloader.c +./grub-core/loader/i386/bsd32.c +./grub-core/loader/i386/bsd64.c +./grub-core/loader/i386/bsd.c +./grub-core/loader/i386/bsd_pagetable.c +./grub-core/loader/i386/bsdXX.c +./grub-core/loader/i386/coreboot/chainloader.c +./grub-core/loader/i386/linux.c +./grub-core/loader/i386/multiboot_mbi.c +./grub-core/loader/i386/pc/chainloader.c +./grub-core/loader/i386/pc/freedos.c +./grub-core/loader/i386/pc/linux.c +./grub-core/loader/i386/pc/ntldr.c +./grub-core/loader/i386/xnu.c +./grub-core/loader/ia64/efi/linux.c +./grub-core/loader/macho32.c +./grub-core/loader/macho64.c +./grub-core/loader/macho.c +./grub-core/loader/machoXX.c +./grub-core/loader/mips/linux.c +./grub-core/loader/multiboot.c +./grub-core/loader/multiboot_elfxx.c +./grub-core/loader/multiboot_mbi2.c +./grub-core/loader/powerpc/ieee1275/linux.c +./grub-core/loader/sparc64/ieee1275/linux.c +./grub-core/loader/xnu.c +./grub-core/loader/xnu_resume.c +./grub-core/mmap/efi/mmap.c +./grub-core/mmap/i386/mmap.c +./grub-core/mmap/i386/pc/mmap.c +./grub-core/mmap/i386/uppermem.c +./grub-core/mmap/mips/uppermem.c +./grub-core/mmap/mmap.c +./grub-core/net/arp.c +./grub-core/net/bootp.c +./grub-core/net/drivers/efi/efinet.c +./grub-core/net/drivers/emu/emunet.c +./grub-core/net/drivers/i386/pc/pxe.c +./grub-core/net/drivers/ieee1275/ofnet.c +./grub-core/net/ethernet.c +./grub-core/net/ip.c +./grub-core/net/netbuff.c +./grub-core/net/net.c +./grub-core/net/tftp.c +./grub-core/net/udp.c +./grub-core/normal/auth.c +./grub-core/normal/autofs.c +./grub-core/normal/charset.c +./grub-core/normal/cmdline.c +./grub-core/normal/color.c +./grub-core/normal/completion.c +./grub-core/normal/context.c +./grub-core/normal/crypto.c +./grub-core/normal/datetime.c +./grub-core/normal/dyncmd.c +./grub-core/normal/main.c +./grub-core/normal/menu.c +./grub-core/normal/menu_entry.c +./grub-core/normal/menu_text.c +./grub-core/normal/misc.c +./grub-core/normal/term.c +./grub-core/partmap/acorn.c +./grub-core/partmap/amiga.c +./grub-core/partmap/apple.c +./grub-core/partmap/bsdlabel.c +./grub-core/partmap/dvh.c +./grub-core/partmap/gpt.c +./grub-core/partmap/msdos.c +./grub-core/partmap/sun.c +./grub-core/partmap/sunpc.c +./grub-core/parttool/msdospart.c +./grub-core/script/argv.c +./grub-core/script/execute.c +./grub-core/script/function.c +./grub-core/script/lexer.c +./grub-core/script/main.c +./grub-core/script/script.c +./grub-core/term/arc/console.c +./grub-core/term/at_keyboard.c +./grub-core/term/efi/console.c +./grub-core/term/gfxterm.c +./grub-core/term/i386/pc/console.c +./grub-core/term/i386/pc/vga_text.c +./grub-core/term/i386/vga_common.c +./grub-core/term/ieee1275/ofconsole.c +./grub-core/term/ns8250.c +./grub-core/term/serial.c +./grub-core/term/terminfo.c +./grub-core/term/tparm.c +./grub-core/term/usb_keyboard.c +./grub-core/tests/example_functional_test.c +./grub-core/tests/lib/functional_test.c +./grub-core/tests/lib/test.c +./grub-core/tests/test_blockarg.c +./grub-core/unidata.c +./grub-core/video/bitmap.c +./grub-core/video/bitmap_scale.c +./grub-core/video/bochs.c +./grub-core/video/cirrus.c +./grub-core/video/colors.c +./grub-core/video/efi_gop.c +./grub-core/video/efi_uga.c +./grub-core/video/emu/sdl.c +./grub-core/video/fb/fbblit.c +./grub-core/video/fb/fbfill.c +./grub-core/video/fb/fbutil.c +./grub-core/video/fb/video_fb.c +./grub-core/video/i386/pc/vbe.c +./grub-core/video/i386/pc/vga.c +./grub-core/video/ieee1275.c +./grub-core/video/readers/jpeg.c +./grub-core/video/readers/png.c +./grub-core/video/readers/tga.c +./grub-core/video/sis315_init.c +./grub-core/video/sis315pro.c +./grub-core/video/sm712.c +./grub-core/video/sm712_init.c +./grub-core/video/video.c +./tests/example_unit_test.c +./tests/lib/unit_test.c +./util/bin2h.c +./util/deviceiter.c +./util/devicemap.c +./util/getroot.c +./util/grub-editenv.c +./util/grub-fstest.c +./util/grub-macho2img.c +./util/grub-menulst2cfg.c +./util/grub-mkdevicemap.c +./util/grub-mkfont.c +./util/grub-mkimage.c +./util/grub-mkimagexx.c +./util/grub-mklayout.c +./util/grub-mkpasswd-pbkdf2.c +./util/grub-mkrelpath.c +./util/grub-pe2elf.c +./util/grub-probe.c +./util/grub-script-check.c +./util/grub-setup.c +./util/ieee1275/devicemap.c +./util/ieee1275/grub-ofpathname.c +./util/ieee1275/ofpath.c +./util/lvm.c +./util/misc.c +./util/raid.c +./util/resolve.c From ca5572a9ad872fd26712d0fbae1ab63adc64787b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 10 Jul 2011 16:06:31 +0200 Subject: [PATCH 1168/1414] * util/grub-install.in: Recognize ESP mounted at /boot/EFI. --- ChangeLog | 4 ++++ util/grub-install.in | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 84167f226..0b386157c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-10 Vladimir Serbinenko + + * util/grub-install.in: Recognize ESP mounted at /boot/EFI. + 2011-07-10 Vladimir Serbinenko * po/POTFILES.in: Regenerate. diff --git a/util/grub-install.in b/util/grub-install.in index 711c9c7e2..1e9e1a2fd 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -335,6 +335,12 @@ if [ x"$platform" = xefi ]; then if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then efidir="${bootdir}/efi" fi + elif test -d "${bootdir}/EFI"; then + install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}/EFI"`" + # Is it a mount point? + if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then + efidir="${bootdir}/EFI" + fi elif test -n "$rootdir" && test "x$rootdir" != "x/"; then # The EFI System Partition may have been given directly using # --root-directory. From bf66054fb3969fffed65b0fa6dea535ae368a0f8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Jul 2011 16:44:40 +0200 Subject: [PATCH 1169/1414] * grub-core/kern/mips/cache_flush.S [GRUB_MACHINE_MIPS_LOONGSON]: Flush all four ways. --- ChangeLog | 5 +++++ grub-core/kern/mips/cache_flush.S | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index e4ca1a6c3..55f097965 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-23 Vladimir Serbinenko + + * grub-core/kern/mips/cache_flush.S [GRUB_MACHINE_MIPS_LOONGSON]: Flush + all four ways. + 2011-07-21 Colin Watson Preferred resolution detection for VBE. diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S index a352fd8ba..c03c337b5 100644 --- a/grub-core/kern/mips/cache_flush.S +++ b/grub-core/kern/mips/cache_flush.S @@ -9,6 +9,13 @@ subu $t1, $t3, $t2 1: cache 1, 0($t0) + /* All four ways. */ +#ifdef GRUB_MACHINE_MIPS_LOONGSON + cache 1, 1($t0) + cache 1, 2($t0) + cache 1, 3($t0) +#endif + addiu $t1, $t1, -0x4 bne $t1, $zero, 1b addiu $t0, $t0, 0x4 From a1167439107cc51d864452c7249c994f6b5b2ce1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Jul 2011 17:14:38 +0200 Subject: [PATCH 1170/1414] * include/grub/mips/kernel.h: Fix define conflict. --- ChangeLog | 4 ++++ include/grub/mips/kernel.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 55f097965..15e7344f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-23 Vladimir Serbinenko + + * include/grub/mips/kernel.h: Fix define conflict. + 2011-07-23 Vladimir Serbinenko * grub-core/kern/mips/cache_flush.S [GRUB_MACHINE_MIPS_LOONGSON]: Flush diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index d82d0a97d..d351f17cb 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 #include From 6be1c01fd721bbea8353e0c0ad547a2c0056640c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Jul 2011 17:18:31 +0200 Subject: [PATCH 1171/1414] * include/grub/video.h: add missing EXPORT_FUND on grub_video_edid_checksum and grub_video_edid_preferred_mode. --- ChangeLog | 5 +++++ include/grub/video.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 15e7344f2..71c33569f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-23 Vladimir Serbinenko + + * include/grub/video.h: add missing EXPORT_FUND on + grub_video_edid_checksum and grub_video_edid_preferred_mode. + 2011-07-23 Vladimir Serbinenko * include/grub/mips/kernel.h: Fix define conflict. diff --git a/include/grub/video.h b/include/grub/video.h index b2adff11d..e30589a3d 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -486,8 +486,8 @@ grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_ grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); -grub_err_t grub_video_edid_checksum (struct grub_video_edid_info *edid_info); -grub_err_t grub_video_edid_preferred_mode (struct grub_video_edid_info *edid_info, +grub_err_t EXPORT_FUNC (grub_video_edid_checksum) (struct grub_video_edid_info *edid_info); +grub_err_t EXPORT_FUNC (grub_video_edid_preferred_mode) (struct grub_video_edid_info *edid_info, unsigned int *width, unsigned int *height); From 583168a216e477bfbf6039ddc331d5827833ec08 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Jul 2011 18:18:14 +0200 Subject: [PATCH 1172/1414] * grub-core/disk/pata.c (grub_pata_readwrite): Add missing wait. --- ChangeLog | 4 ++++ grub-core/disk/pata.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 71c33569f..2eb0c0fcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-23 Vladimir Serbinenko + + * grub-core/disk/pata.c (grub_pata_readwrite): Add missing wait. + 2011-07-23 Vladimir Serbinenko * include/grub/video.h: add missing EXPORT_FUND on diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index ff6f77366..c54fe91ab 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -177,6 +177,10 @@ grub_pata_readwrite (struct grub_ata *disk, /* Start command. */ grub_pata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile.cmd); + /* Wait for !BSY. */ + if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + /* Check status. */ grub_int8_t sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS); grub_dprintf ("pata", "status=0x%x\n", sts); From b70e4cb08d055181585c9b1d3e7a0366e90d17f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Jul 2011 07:48:19 +0200 Subject: [PATCH 1173/1414] * grub-core/normal/menu.c (grub_menu_execute_entry): Fix NULL dereference. --- ChangeLog | 5 +++++ grub-core/normal/menu.c | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2eb0c0fcd..5069e5651 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-23 Vladimir Serbinenko + + * grub-core/normal/menu.c (grub_menu_execute_entry): Fix NULL + dereference. + 2011-07-23 Vladimir Serbinenko * grub-core/disk/pata.c (grub_pata_readwrite): Add missing wait. diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 5844cb2f0..2c127794b 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -232,7 +232,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) grub_env_export ("chosen"); grub_free (buf); } - for (ptr = def; *ptr; ptr++) + + for (ptr = def; ptr && *ptr; ptr++) { if (ptr[0] == '>' && ptr[1] == '>') { @@ -242,10 +243,12 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) if (ptr[0] == '>') break; } - if (ptr[0] && ptr[1]) + + if (ptr && ptr[0] && ptr[1]) grub_env_set ("default", ptr + 1); else grub_env_unset ("default"); + grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args); if (errs_before != grub_err_printed_errors) From c77069f5ae4107323bf71c8c9d8505048acae740 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Jul 2011 07:57:29 +0200 Subject: [PATCH 1174/1414] * util/grub-mkrescue.in: Add missing quotes. --- ChangeLog | 6 +++++- util/grub-mkrescue.in | 14 +++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5069e5651..570de50e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2011-07-23 Vladimir Serbinenko +2011-07-25 Vladimir Serbinenko + + * util/grub-mkrescue.in: Add missing quotes. + +2011-07-25 Vladimir Serbinenko * grub-core/normal/menu.c (grub_menu_execute_entry): Fix NULL dereference. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index f054c43a9..4c96dd42b 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -31,15 +31,15 @@ pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst self=`basename $0` -multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot -coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot -qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu -pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc -efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi -efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi +multiboot_dir="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot" +coreboot_dir="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot" +qemu_dir="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu" +pc_dir="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc" +efi32_dir="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi" +efi64_dir="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi" rom_directory= override_dir= -grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` +grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" xorriso=xorriso From 922275976579ecd9ebaa88eba3fb5e8933e9c93f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Jul 2011 08:06:20 +0200 Subject: [PATCH 1175/1414] * util/grub-install.in: Don't use uhci outside of x86. --- ChangeLog | 4 ++++ util/grub-install.in | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 570de50e1..32dfada58 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-25 Vladimir Serbinenko + + * util/grub-install.in: Don't use uhci outside of x86. + 2011-07-25 Vladimir Serbinenko * util/grub-mkrescue.in: Add missing quotes. diff --git a/util/grub-install.in b/util/grub-install.in index 1e9e1a2fd..3d2420b91 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -504,7 +504,11 @@ if [ "x$disk_module" = xata ]; then fi if [ "x$disk_module" = xnative ]; then - disk_module="pata ahci ohci uhci usbms" + disk_module="pata ahci ohci" + if [ "x$target_cpu" = "xi386" ] || [ "x$target_cpu" = "xx86_64" ]; then + disk_module="$disk_module uhci" + fi + disk_module="$disk_module usbms" fi # The order in this list is critical. Be careful when modifying it. From 6795300e7f230ac552c984ef051f0ae79f318bcf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Jul 2011 08:14:34 +0200 Subject: [PATCH 1176/1414] Support ATA disks with 4K sectors. * include/grub/ata.h (grub_ata): New member log_sector_size. * grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. (grub_ata_identify): Read sector size. (grub_ata_readwrite): Use log_sector_size rather than hardcoded value. --- ChangeLog | 9 +++++++++ grub-core/disk/ata.c | 23 ++++++++++++++++++++--- include/grub/ata.h | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 32dfada58..5c4e20c28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-07-25 Vladimir Serbinenko + + Support ATA disks with non-4K sectors. + + * include/grub/ata.h (grub_ata): New member log_sector_size. + * grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. + (grub_ata_identify): Read sector size. + (grub_ata_readwrite): Use log_sector_size rather than hardcoded value. + 2011-07-25 Vladimir Serbinenko * util/grub-install.in: Don't use uhci outside of x86. diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 8add7f4de..330635f57 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -57,6 +57,7 @@ grub_ata_dumpinfo (struct grub_ata *dev, char *info) { grub_dprintf ("ata", "Addressing: %d\n", dev->addr); grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size); + grub_dprintf ("ata", "Sector size: %u\n", 1U << dev->log_sector_size); } } @@ -170,6 +171,21 @@ grub_ata_identify (struct grub_ata *dev) else dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100])); + if (info16[106] & (1 << 12)) + { + grub_uint32_t secsize; + secsize = grub_le_to_cpu32 (*((grub_uint32_t *) &info16[117])); + if (secsize & (secsize - 1) || !secsize + || secsize > 1048576) + secsize = 256; + for (dev->log_sector_size = 0; + (1U << dev->log_sector_size) < secsize; + dev->log_sector_size++); + dev->log_sector_size++; + } + else + dev->log_sector_size = 9; + /* Read CHS information. */ dev->cylinders = info16[1]; dev->heads = info16[3]; @@ -314,7 +330,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, grub_ata_setaddress (ata, &parms, sector, batch, addressing); parms.taskfile.cmd = (! rw ? cmd : cmd_write); parms.buffer = buf; - parms.size = batch * GRUB_DISK_SECTOR_SIZE; + parms.size = batch << ata->log_sector_size; parms.write = rw; if (ata->dma) parms.dma = 1; @@ -322,9 +338,9 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, err = ata->dev->readwrite (ata, &parms, 0); if (err) return err; - if (parms.size != batch * GRUB_DISK_SECTOR_SIZE) + if (parms.size != batch << ata->log_sector_size) return grub_error (GRUB_ERR_READ_ERROR, "incomplete read"); - buf += GRUB_DISK_SECTOR_SIZE * batch; + buf += batch << ata->log_sector_size; sector += batch; nsectors += batch; } @@ -433,6 +449,7 @@ grub_ata_open (const char *name, grub_disk_t disk) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); disk->total_sectors = ata->size; + disk->log_sector_size = ata->log_sector_size; disk->id = grub_make_scsi_id (id, bus, 0); diff --git a/include/grub/ata.h b/include/grub/ata.h index 6938b6a42..1a19f27aa 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -170,6 +170,7 @@ struct grub_ata /* Sector count. */ grub_uint64_t size; + grub_uint32_t log_sector_size; /* CHS maximums. */ grub_uint16_t cylinders; From 41aa28ea2a7c90c14016a122ae604c95aa4a8697 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 25 Jul 2011 08:19:30 +0200 Subject: [PATCH 1177/1414] New script grub-mkstandalone. * Makefile.util.def (grub-mkstandalone): New script. * docs/man/grub-mkstandalone.h2m: New file. * util/grub-mkstandalone.in: Likewise. --- ChangeLog | 10 +- Makefile.util.def | 6 ++ docs/man/grub-mkstandalone.h2m | 4 + util/grub-mkstandalone.in | 189 +++++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 docs/man/grub-mkstandalone.h2m create mode 100644 util/grub-mkstandalone.in diff --git a/ChangeLog b/ChangeLog index 5c4e20c28..2593d598b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ 2011-07-25 Vladimir Serbinenko - Support ATA disks with non-4K sectors. + New script grub-mkstandalone. + + * Makefile.util.def (grub-mkstandalone): New script. + * docs/man/grub-mkstandalone.h2m: New file. + * util/grub-mkstandalone.in: Likewise. + +2011-07-25 Vladimir Serbinenko + + Support ATA disks with 4K sectors. * include/grub/ata.h (grub_ata): New member log_sector_size. * grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. diff --git a/Makefile.util.def b/Makefile.util.def index c87020493..d86cb9761 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -412,6 +412,12 @@ script = { enable = powerpc_ieee1275; }; +script = { + mansection = 1; + name = grub-mkstandalone; + common = util/grub-mkstandalone.in; +}; + script = { mansection = 8; installdir = sbin; diff --git a/docs/man/grub-mkstandalone.h2m b/docs/man/grub-mkstandalone.h2m new file mode 100644 index 000000000..c77313978 --- /dev/null +++ b/docs/man/grub-mkstandalone.h2m @@ -0,0 +1,4 @@ +[NAME] +grub-mkstandalone \- make a memdisk-based GRUB image +[SEE ALSO] +.BR grub-mkimage (1) diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in new file mode 100644 index 000000000..aaff99051 --- /dev/null +++ b/util/grub-mkstandalone.in @@ -0,0 +1,189 @@ +#! /bin/sh +set -e + +# Make GRUB rescue image +# Copyright (C) 1999,2000,2001,2002,2003,2004,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 . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" + +self=`basename $0` + +source_dirrectory= +compression=auto +format= +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` +source= + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +argument () { + opt=$1 + shift + + if test $# -eq 0; then + echo "$0: option requires an argument -- '$opt'" 1>&2 + exit 1 + fi + echo $1 +} + +# Check the arguments. +while test $# -gt 0 +do + option=$1 + shift + + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" + exit 0 ;; + + --modules) + modules=`argument $option "$@"`; shift ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + + -o | --output) + output_image=`argument $option "$@"`; shift ;; + --output=*) + output_image=`echo "$option" | sed 's/--output=//'` ;; + + --directory | -d) + source_directory=`argument $option "$@"`; shift ;; + --directory=*) + source_directory=`echo "$option" | sed 's/--rom-directory=//'` ;; + + --grub-mkimage) + grub_mkimage=`argument $option "$@"`; shift ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + + --compression | -C) + compression=`argument $option "$@"`; shift ;; + --compression=*) + compression=`echo "${option}/" | sed 's/--xorriso=//'` ;; + + --format | -O) + format=`argument $option "$@"`; shift ;; + --format=*) + format=`echo "${option}/" | sed 's/--xorriso=//'` ;; + + *) + source="${source} ${option} $@"; break ;; + esac +done + +if [ "x${output_image}" = x ] ; then + echo "output file must be given" >&2 + usage + exit 1 +fi + +if [ "x${format}" = x ] ; then + echo "format must be given" >&2 + usage + exit 1 +fi + +if [ "x$source_directory" = x ] ; then + cpu="`echo $format | awk -F - '{ print $1; }'`" + platform="`echo $format | awk -F - '{ print $2; }'`" + case "$platform" in + yeeloong | fuloong) + platform=loongson ;; + esac + case "$cpu-$platform" in + mips-loongson) + cpu=mipsel ;; + esac + source_directory="${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/$cpu-$platform" +fi + +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +memdisk_dir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +mkdir -p "${memdisk_dir}"/boot/grub + +for file in "${source_directory}/"*.mod "${source_directory}/"efiemu32.o "${source_directory}/"efiemu64.o; do + if test -f "$file"; then + cp -f "$file" "${memdisk_dir}"/boot/grub/ + fi +done +for file in ${pkglib_DATA}; do + if test -f "${source_directory}/${file}"; then + cp -f "${source_directory}/${file}" "${memdisk_dir}"/boot/grub/ + fi +done + +mkdir -p "${memdisk_dir}"/boot/grub/locale +for file in "${source_directory}"/po/*.mo; do + if test -f "$file"; then + cp -f "$file" "${memdisk_dir}"/boot/grub/locale/ + fi +done + +for file in $source; do + cp -f "$file" "${memdisk_dir}"/"$file"; +done + +memdisk_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + +(cd "${memdisk_dir}"; tar -cf - * $source) > "${memdisk_img}" +rm -rf "${memdisk_dir}" +$grub_mkimage -O "${format}" -C "$compression" -d "${source_directory}" -m "${memdisk_img}" -o "$output_image" --prefix='(memdisk)/boot/grub' memdisk tar $modules +rm -rf "${memdisk_img}" + +exit 0 From 303b6246a3a44d51cf9263b754efbfe0e5f4272a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 26 Jul 2011 11:59:47 +0100 Subject: [PATCH 1178/1414] * util/grub-install.in: Don't source grub-mkconfig_lib until after processing arguments (otherwise help2man fails when GRUB has not yet been installed). --- ChangeLog | 6 ++++++ util/grub-install.in | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2593d598b..fa33902ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-07-26 Colin Watson + + * util/grub-install.in: Don't source grub-mkconfig_lib until after + processing arguments (otherwise help2man fails when GRUB has not yet + been installed). + 2011-07-25 Vladimir Serbinenko New script grub-mkstandalone. diff --git a/util/grub-install.in b/util/grub-install.in index 3d2420b91..f9e1510d1 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -59,8 +59,6 @@ update_nvram=yes removable=no efi_quiet= -. ${libdir}/@PACKAGE@/grub-mkconfig_lib - # Get GRUB_DISTRIBUTOR. if test -f "${sysconfdir}/default/grub" ; then . "${sysconfdir}/default/grub" @@ -265,6 +263,8 @@ do esac done +. ${libdir}/@PACKAGE@/grub-mkconfig_lib + if test "x$install_device" = x && ([ "${target_cpu}-${platform}" = "i386-pc" ] \ || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ]); then echo "install_device not specified." 1>&2 From 20168fcafeed3d87f437914a09e35a926c009faa Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 26 Jul 2011 16:19:47 +0100 Subject: [PATCH 1179/1414] * configure.ac: The Loongson port requires grub-mkfont due to its use of -DUSE_ASCII_FAILBACK. Raise an error if it is not going to be built. --- ChangeLog | 6 ++++++ configure.ac | 3 +++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index fa33902ab..19e034dc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-07-26 Colin Watson + + * configure.ac: The Loongson port requires grub-mkfont due to its + use of -DUSE_ASCII_FAILBACK. Raise an error if it is not going to + be built. + 2011-07-26 Colin Watson * util/grub-install.in: Don't source grub-mkconfig_lib until after diff --git a/configure.ac b/configure.ac index f674a90aa..e6d726548 100644 --- a/configure.ac +++ b/configure.ac @@ -866,6 +866,9 @@ enable_grub_mkfont=yes else enable_grub_mkfont=no fi +if test x"$enable_grub_mkfont" = xno && test "x$platform" = xloongson; then + AC_MSG_ERROR([loongson port needs grub-mkfont]) +fi AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) From 66816d85565bc362b07ce0c623c3379d6b21119e Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 3 Aug 2011 13:30:46 +0200 Subject: [PATCH 1180/1414] 2011-08-03 Robert Millan * include/grub/zfs/zap_leaf.h (typedef union zap_leaf_chunk): Mark la_array as packed. Reported by: Zachary Bedell --- ChangeLog | 6 ++++++ include/grub/zfs/zap_leaf.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 19e034dc0..184b0d763 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-08-03 Robert Millan + + * include/grub/zfs/zap_leaf.h (typedef union zap_leaf_chunk): Mark + la_array as packed. + Reported by: Zachary Bedell + 2011-07-26 Colin Watson * configure.ac: The Loongson port requires grub-mkfont due to its diff --git a/include/grub/zfs/zap_leaf.h b/include/grub/zfs/zap_leaf.h index 1ef654054..5adfdc290 100644 --- a/include/grub/zfs/zap_leaf.h +++ b/include/grub/zfs/zap_leaf.h @@ -90,7 +90,7 @@ typedef union zap_leaf_chunk { { grub_uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; grub_uint64_t la_array64; - }; + } __attribute__ ((packed)); grub_uint16_t la_next; /* next blk or CHAIN_END */ } l_array; struct zap_leaf_free { From 6dc212f953b2ff19245a125a938e35b8b0f929ba Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 10 Aug 2011 22:24:02 +0200 Subject: [PATCH 1181/1414] 2011-08-10 Robert Millan Detect LSI MegaRAID SAS (`mfi') devices on GNU/kFreeBSD. * util/deviceiter.c [__FreeBSD_kernel__] (get_mfi_disk_name): New function. [__FreeBSD_kernel__] (grub_util_iterate_devices): Scan for mfi (/dev/mfid[0-9]+) devices using get_mfi_disk_name(). --- ChangeLog | 9 +++++++++ util/deviceiter.c | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ChangeLog b/ChangeLog index 184b0d763..039621768 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-08-10 Robert Millan + + Detect LSI MegaRAID SAS (`mfi') devices on GNU/kFreeBSD. + + * util/deviceiter.c [__FreeBSD_kernel__] (get_mfi_disk_name): New + function. + [__FreeBSD_kernel__] (grub_util_iterate_devices): Scan for mfi + (/dev/mfid[0-9]+) devices using get_mfi_disk_name(). + 2011-08-03 Robert Millan * include/grub/zfs/zap_leaf.h (typedef union zap_leaf_chunk): Mark diff --git a/util/deviceiter.c b/util/deviceiter.c index 2a8acec0e..208dcfdde 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -298,6 +298,12 @@ get_ataraid_disk_name (char *name, int unit) { sprintf (name, "/dev/ar%d", unit); } + +static void +get_mfi_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/mfid%d", unit); +} #endif #ifdef __linux__ @@ -661,6 +667,19 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), goto out; } } + + /* LSI MegaRAID SAS. */ + for (i = 0; i < 32; i++) + { + char name[20]; + + get_mfi_disk_name (name, i); + if (check_device_readable_unique (name)) + { + if (hook (name, 0)) + goto out; + } + } #endif #ifdef __linux__ From 1f1a380be9ba10bf904240106b3bbb274c11e65a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:39:31 +0200 Subject: [PATCH 1182/1414] Import minilzo library for LZO decompression support. * grub-core/lib/minilzo/lzoconf.h: New file. * grub-core/lib/minilzo/lzodefs.h: Likewise. * grub-core/lib/minilzo/minilzo.c: Likewise. * grub-core/lib/minilzo/minilzo.h: Likewise. * include/grub/types.h (GRUB_UCHAR_MAX): New define. (GRUB_USHRT_MAX): Likewise. (GRUB_UINT_MAX): Likewise. * grub-core/lib/posix_wrap/limits.h (USHRT_MAX): New define. (UINT_MAX): Likewise. (CHAR_BIT): Likewise. * grub-core/lib/posix_wrap/sys/types.h (ULONG_MAX): Moved to grub-core/lib/posix_wrap/limits.h (UCHAR_MAX): Likewise. --- ChangeLog.lzo | 18 + grub-core/lib/minilzo/lzoconf.h | 446 +++ grub-core/lib/minilzo/lzodefs.h | 1852 +++++++++++ grub-core/lib/minilzo/minilzo.c | 4562 ++++++++++++++++++++++++++ grub-core/lib/minilzo/minilzo.h | 109 + grub-core/lib/posix_wrap/limits.h | 31 + grub-core/lib/posix_wrap/sys/types.h | 3 - include/grub/types.h | 4 + 8 files changed, 7022 insertions(+), 3 deletions(-) create mode 100644 ChangeLog.lzo create mode 100644 grub-core/lib/minilzo/lzoconf.h create mode 100644 grub-core/lib/minilzo/lzodefs.h create mode 100644 grub-core/lib/minilzo/minilzo.c create mode 100644 grub-core/lib/minilzo/minilzo.h diff --git a/ChangeLog.lzo b/ChangeLog.lzo new file mode 100644 index 000000000..6f5191db2 --- /dev/null +++ b/ChangeLog.lzo @@ -0,0 +1,18 @@ +2011-08-14 Szymon Janc + + Import minilzo library for LZO decompression support. + + * grub-core/lib/minilzo/lzoconf.h: New file. + * grub-core/lib/minilzo/lzodefs.h: Likewise. + * grub-core/lib/minilzo/minilzo.c: Likewise. + * grub-core/lib/minilzo/minilzo.h: Likewise. + * include/grub/types.h (GRUB_UCHAR_MAX): New define. + (GRUB_USHRT_MAX): Likewise. + (GRUB_UINT_MAX): Likewise. + * grub-core/lib/posix_wrap/limits.h (USHRT_MAX): New define. + (UINT_MAX): Likewise. + (CHAR_BIT): Likewise. + * grub-core/lib/posix_wrap/sys/types.h (ULONG_MAX): Moved to + grub-core/lib/posix_wrap/limits.h + (UCHAR_MAX): Likewise. + diff --git a/grub-core/lib/minilzo/lzoconf.h b/grub-core/lib/minilzo/lzoconf.h new file mode 100644 index 000000000..1d0fe14fc --- /dev/null +++ b/grub-core/lib/minilzo/lzoconf.h @@ -0,0 +1,446 @@ +/* lzoconf.h -- configuration of the LZO data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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 2 of + the License, or (at your option) any later version. + + The LZO 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED 1 + +#define LZO_VERSION 0x2050 +#define LZO_VERSION_STRING "2.05" +#define LZO_VERSION_DATE "Apr 23 2011" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +#if !defined(LZO_UINT32_C) +# if (UINT_MAX < LZO_0xffffffffL) +# define LZO_UINT32_C(c) c ## UL +# else +# define LZO_UINT32_C(c) ((c) + 0U) +# endif +#endif + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint should match size_t */ +#if !defined(LZO_UINT_MAX) +# if defined(LZO_ABI_LLP64) /* WIN64 */ +# if defined(LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# else + typedef unsigned long long lzo_uint; + typedef long long lzo_int; +# endif +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* Integral types with 32 bits or more. */ +#if !defined(LZO_UINT32_MAX) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef unsigned int lzo_uint32; + typedef int lzo_int32; +# define LZO_UINT32_MAX UINT_MAX +# define LZO_INT32_MAX INT_MAX +# define LZO_INT32_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint32; + typedef long lzo_int32; +# define LZO_UINT32_MAX ULONG_MAX +# define LZO_INT32_MAX LONG_MAX +# define LZO_INT32_MIN LONG_MIN +# else +# error "lzo_uint32" +# endif +#endif + +/* Integral types with exactly 64 bits. */ +#if !defined(LZO_UINT64_MAX) +# if (LZO_UINT_MAX >= LZO_0xffffffffL) +# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3) +# define lzo_uint64 lzo_uint +# define lzo_int64 lzo_int +# define LZO_UINT64_MAX LZO_UINT_MAX +# define LZO_INT64_MAX LZO_INT_MAX +# define LZO_INT64_MIN LZO_INT_MIN +# endif +# elif (ULONG_MAX >= LZO_0xffffffffL) +# if ((((ULONG_MAX) >> 31) >> 31) == 3) + typedef unsigned long lzo_uint64; + typedef long lzo_int64; +# define LZO_UINT64_MAX ULONG_MAX +# define LZO_INT64_MAX LONG_MAX +# define LZO_INT64_MIN LONG_MIN +# endif +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32. */ +#if (LZO_UINT_MAX >= LZO_UINT32_MAX) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32 +#endif + +/* Memory model that allows to access memory at offsets of lzo_uint. */ +#if !defined(__LZO_MMODEL) +# if (LZO_UINT_MAX <= UINT_MAX) +# define __LZO_MMODEL /*empty*/ +# elif defined(LZO_HAVE_MM_HUGE_PTR) +# define __LZO_MMODEL_HUGE 1 +# define __LZO_MMODEL __huge +# else +# define __LZO_MMODEL /*empty*/ +# endif +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_uint32p lzo_uint32 __LZO_MMODEL * +#define lzo_int32p lzo_int32 __LZO_MMODEL * +#if defined(LZO_UINT64_MAX) +#define lzo_uint64p lzo_uint64 __LZO_MMODEL * +#define lzo_int64p lzo_int64 __LZO_MMODEL * +#endif +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * +/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */ +#define lzo_byte unsigned char __LZO_MMODEL + +typedef int lzo_bool; + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 /*empty*/ +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 /*empty*/ +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* NOTE: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ +#define LZO_E_INVALID_ARGUMENT (-10) + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) + lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memset(lzo_voidp buf, int c, lzo_uint len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32) + lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(lzo_uint32) + lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(const lzo_uint32p) + lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; +typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; +typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of 'size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); +#define LZO_PTR_ALIGN_UP(p,size) \ + ((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility with LZO v1.xx +************************************************************************/ + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL /*empty*/ +#define __LZO_DMODEL /*empty*/ +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 et: */ diff --git a/grub-core/lib/minilzo/lzodefs.h b/grub-core/lib/minilzo/lzodefs.h new file mode 100644 index 000000000..0e40e332a --- /dev/null +++ b/grub-core/lib/minilzo/lzodefs.h @@ -0,0 +1,1852 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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 2 of + the License, or (at your option) any later version. + + The LZO 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) +# else +# define LZO_CC_CLANG_CLANG 0x010000L +# endif +# define LZO_CC_CLANG LZO_CC_CLANG_GNUC +# define LZO_INFO_CC "clang" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_inline __inline__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline /*empty*/ +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# if 0 && defined(__cplusplus) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e)))))) +# else +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if (LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif /* already included */ + +/* vim:set ts=4 et: */ diff --git a/grub-core/lib/minilzo/minilzo.c b/grub-core/lib/minilzo/minilzo.c new file mode 100644 index 000000000..25a1f68b3 --- /dev/null +++ b/grub-core/lib/minilzo/minilzo.c @@ -0,0 +1,4562 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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 2 of + the License, or (at your option) any later version. + + The LZO 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO 1 + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) +# else +# define LZO_CC_CLANG_CLANG 0x010000L +# endif +# define LZO_CC_CLANG LZO_CC_CLANG_GNUC +# define LZO_INFO_CC "clang" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_inline __inline__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline /*empty*/ +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# if 0 && defined(__cplusplus) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e)))))) +# else +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if (LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2050) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H 1 +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H 1 + +#if !defined(__LZO_IN_MINILZO) +#if (LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +# define ACC_LIBC_FREESTANDING 1 +# define ACC_OS_FREESTANDING 1 +#endif +#if (LZO_CFG_NO_UNALIGNED) +# define ACC_CFG_NO_UNALIGNED 1 +#endif +#if (LZO_ARCH_GENERIC) +# define ACC_ARCH_GENERIC 1 +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# define ACC_ABI_NEUTRAL_ENDIAN 1 +#endif +#if (LZO_HAVE_CONFIG_H) +# define ACC_CONFIG_NO_HEADER 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#include "lzo/lzoconf.h" +#endif + +#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +# error "version mismatch" +#endif + +#if (LZO_CC_BORLANDC && LZO_ARCH_I086) +# pragma option -h +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +# pragma warning(disable: 4514 4710 4711) +#endif + +#if (LZO_CC_SUNPROC) +#if !defined(__cplusplus) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +# pragma error_messages(off,E_STATEMENT_NOT_REACHED) +#endif +#endif + +#if (__LZO_MMODEL_HUGE) && !(LZO_HAVE_MM_HUGE_PTR) +# error "this should not happen - check defines for __huge" +#endif + +#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING) +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define ACC_WANT_ACC_INCD_H 1 +# define ACC_WANT_ACC_INCE_H 1 +# define ACC_WANT_ACC_INCI_H 1 +#elif 1 +# include +#else +# define ACC_WANT_ACC_INCD_H 1 +#endif + +#if (LZO_ARCH_I086) +# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT +# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0]) +# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1]) +# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o))) +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16) +# define __LZO_UINTPTR_T_IS_POINTER 1 + typedef char* lzo_uintptr_t; +# define lzo_uintptr_t lzo_uintptr_t +# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t size_t +# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long +# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned int +# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long long +# else +# define lzo_uintptr_t size_t +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if (LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memcmp +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memcpy +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memmove +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#elif !(__LZO_MMODEL_HUGE) +# undef lzo_memset +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if (LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if !defined(__lzo_inline) +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +# define __lzo_forceinline /*empty*/ +#endif +#if !defined(__lzo_noinline) +# define __lzo_noinline /*empty*/ +#endif + +#if (LZO_CFG_PGO) +# undef __acc_likely +# undef __acc_unlikely +# undef __lzo_likely +# undef __lzo_unlikely +# define __acc_likely(e) (e) +# define __acc_unlikely(e) (e) +# define __lzo_likely(e) (e) +# define __lzo_unlikely(e) (e) +#endif + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits) (1ul << (bits)) +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386 || LZO_ARCH_POWERPC) +# if (LZO_SIZEOF_SHORT == 2) +# define LZO_UNALIGNED_OK_2 1 +# endif +# if (LZO_SIZEOF_INT == 4) +# define LZO_UNALIGNED_OK_4 1 +# endif +#endif +#if 1 && (LZO_ARCH_AMD64) +# if defined(LZO_UINT64_MAX) +# define LZO_UNALIGNED_OK_8 1 +# endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_UNALIGNED_OK_2 +# undef LZO_UNALIGNED_OK_4 +# undef LZO_UNALIGNED_OK_8 +#endif + +#undef UA_GET16 +#undef UA_SET16 +#undef UA_COPY16 +#undef UA_GET32 +#undef UA_SET32 +#undef UA_COPY32 +#undef UA_GET64 +#undef UA_SET64 +#undef UA_COPY64 +#if defined(LZO_UNALIGNED_OK_2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(unsigned short) == 2) +# if 1 && defined(ACC_UA_COPY16) +# define UA_GET16 ACC_UA_GET16 +# define UA_SET16 ACC_UA_SET16 +# define UA_COPY16 ACC_UA_COPY16 +# else +# define UA_GET16(p) (* (__lzo_ua_volatile const lzo_ushortp) (__lzo_ua_volatile const lzo_voidp) (p)) +# define UA_SET16(p,v) ((* (__lzo_ua_volatile lzo_ushortp) (__lzo_ua_volatile lzo_voidp) (p)) = (unsigned short) (v)) +# define UA_COPY16(d,s) UA_SET16(d, UA_GET16(s)) +# endif +#endif +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +# if 1 && defined(ACC_UA_COPY32) +# define UA_GET32 ACC_UA_GET32 +# define UA_SET32 ACC_UA_SET32 +# define UA_COPY32 ACC_UA_COPY32 +# else +# define UA_GET32(p) (* (__lzo_ua_volatile const lzo_uint32p) (__lzo_ua_volatile const lzo_voidp) (p)) +# define UA_SET32(p,v) ((* (__lzo_ua_volatile lzo_uint32p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint32) (v)) +# define UA_COPY32(d,s) UA_SET32(d, UA_GET32(s)) +# endif +#endif +#if defined(LZO_UNALIGNED_OK_8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64) == 8) +# if 1 && defined(ACC_UA_COPY64) +# define UA_GET64 ACC_UA_GET64 +# define UA_SET64 ACC_UA_SET64 +# define UA_COPY64 ACC_UA_COPY64 +# else +# define UA_GET64(p) (* (__lzo_ua_volatile const lzo_uint64p) (__lzo_ua_volatile const lzo_voidp) (p)) +# define UA_SET64(p,v) ((* (__lzo_ua_volatile lzo_uint64p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint64) (v)) +# define UA_COPY64(d,s) UA_SET64(d, UA_GET64(s)) +# endif +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(lzo_uintptr_t) +# if (__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# else +# define lzo_uintptr_t acc_uintptr_t +# ifdef __ACC_INTPTR_T_IS_POINTER +# define __LZO_UINTPTR_T_IS_POINTER 1 +# endif +# endif +#endif + +#if (LZO_ARCH_I086) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0) +#elif (LZO_MM_PVP) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0) +#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0) +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_int32 a_lzo_int32; + lzo_uint32 a_lzo_uint32; +#if defined(LZO_UINT64_MAX) + lzo_int64 a_lzo_int64; + lzo_uint64 a_lzo_uint64; +#endif + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + lzo_voidp a_lzo_voidp; + void * a_void_p; + lzo_bytep a_lzo_bytep; + lzo_bytepp a_lzo_bytepp; + lzo_uintp a_lzo_uintp; + lzo_uint * a_lzo_uint_p; + lzo_uint32p a_lzo_uint32p; + lzo_uint32 * a_lzo_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef LZO_DETERMINISTIC +#define LZO_DETERMINISTIC 1 +#endif + +#ifndef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 1 +#if 0 && (LZO_ARCH_I086) +# undef LZO_DICT_USE_PTR +# define LZO_DICT_USE_PTR 0 +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) + p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr)); +#elif (LZO_MM_PVP) + p = (lzo_uintptr_t) (ptr); + p = (p << 3) | (p >> 61); +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if defined(__LZO_UINTPTR_T_IS_POINTER) + size_t n = (size_t) ptr; + n = (((n + size - 1) / size) * size) - n; +#else + lzo_uintptr_t p, n; + p = __lzo_ptr_linear(ptr); + n = (((p + size - 1) / size) * size) - p; +#endif + + assert(size > 0); + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_UTIL) + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +static const char __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO Copyright (C) 1996-2011 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ +#if (LZO_OS_DOS16 && LZO_CC_TURBOC) + return (lzo_voidp) __lzo_copyright; +#else + return (const lzo_bytep) __lzo_copyright; +#endif +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32 s1 = adler & 0xffff; + lzo_uint32 s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP) + const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2; + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET) + lzo_hbyte_p p = (lzo_hbyte_p) s; + if __lzo_likely(len > 0) do + *p++ = (unsigned char) c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, c, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_INIT) + +#if !defined(__LZO_IN_MINILZO) + +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32) + ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4) +#if defined(LZO_UINT64_MAX) + ACCCHK_ASSERT(sizeof(lzo_uint64) == 8) + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int64) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint64) +#endif + +#if !defined(__LZO_UINTPTR_T_IS_POINTER) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32)) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint)) + ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint)) + +#endif +#undef ACCCHK_ASSERT + +#if 0 +#define WANT_lzo_bitops_clz32 1 +#define WANT_lzo_bitops_clz64 1 +#endif +#define WANT_lzo_bitops_ctz32 1 +#define WANT_lzo_bitops_ctz64 1 + +#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#include +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0 +#pragma intrinsic(_BitScanReverse) +static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanReverse(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz32 lzo_bitops_clz32 +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0 +#pragma intrinsic(_BitScanReverse64) +static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanReverse64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz64 lzo_bitops_clz64 +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#pragma intrinsic(_BitScanForward) +static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanForward(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz32 lzo_bitops_ctz32 +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#pragma intrinsic(_BitScanForward64) +static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanForward64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz64 lzo_bitops_ctz64 +#endif + +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || LZO_CC_LLVM) +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) +#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v)) +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v)) +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v)) +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32) +#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v)) +#endif +#endif + +#if 0 +#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off))) +#else +static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) +{ + return (lzo_voidp) ((lzo_bytep) ptr + off); +} +#endif + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ + lzo_bool r = 1; + union { + lzo_xint a[2]; unsigned char b[2*LZO_MAX(8,sizeof(lzo_xint))]; +#if defined(LZO_UNALIGNED_OK_8) + lzo_uint64 c[2]; +#endif + unsigned short x[2]; lzo_uint32 y[2]; lzo_uint z[2]; + } u; + lzo_voidp p; + + u.a[0] = u.a[1] = 0; + p = u2p(&u, 0); + r &= ((* (lzo_bytep) p) == 0); +#if !defined(LZO_CFG_NO_CONFIG_CHECK) +#if defined(LZO_ABI_BIG_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if defined(LZO_ABI_LITTLE_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[0] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if defined(LZO_UNALIGNED_OK_2) + u.a[0] = u.a[1] = 0; + u.b[0] = 1; u.b[sizeof(unsigned short) + 1] = 2; + p = u2p(&u, 1); + r &= ((* (lzo_ushortp) p) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_4) + u.a[0] = u.a[1] = 0; + u.b[0] = 3; u.b[sizeof(lzo_uint32) + 1] = 4; + p = u2p(&u, 1); + r &= ((* (lzo_uint32p) p) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_8) + u.c[0] = u.c[1] = 0; + u.b[0] = 5; u.b[sizeof(lzo_uint64) + 1] = 6; + p = u2p(&u, 1); + r &= ((* (lzo_uint64p) p) == 0); +#endif +#if defined(lzo_bitops_clz32) + { unsigned i; lzo_uint32 v = 1; + for (i = 0; i < 31; i++, v <<= 1) + r &= lzo_bitops_clz32(v) == 31 - i; + } +#endif +#if defined(lzo_bitops_clz64) + { unsigned i; lzo_uint64 v = 1; + for (i = 0; i < 63; i++, v <<= 1) + r &= lzo_bitops_clz64(v) == 63 - i; + } +#endif +#if defined(lzo_bitops_ctz32) + { unsigned i; lzo_uint32 v = 1; + for (i = 0; i < 31; i++, v <<= 1) + r &= lzo_bitops_ctz32(v) == i; + } +#endif +#if defined(lzo_bitops_ctz64) + { unsigned i; lzo_uint64 v = 1; + for (i = 0; i < 63; i++, v <<= 1) + r &= lzo_bitops_ctz64(v) == i; + } +#endif +#endif + + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT +#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef ACCCHK_ASSERT + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#endif + +#define LZO1X 1 +#define LZO_EOF_CODE 1 +#define M2_MAX_OFFSET 0x0800 + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#if 1 && defined(UA_GET32) +#undef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 0 +#undef lzo_dict_t +#define lzo_dict_t unsigned short +#endif + +#define LZO_NEED_DICT_H 1 +#ifndef D_BITS +#define D_BITS 14 +#endif +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#if 1 +#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) +#else +#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) +#endif + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H 1 + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X 1 +#endif + +#if !defined(__LZO_IN_MINILZO) +#include "lzo/lzo1x.h" +#endif + +#ifndef LZO_EOF_CODE +#define LZO_EOF_CODE 1 +#endif +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 6 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 6 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +#if (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_LLVM) +static void __attribute__((__unused__)) +#else +static void +#endif +DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if (LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if (LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) + +#ifndef DO_COMPRESS +#define DO_COMPRESS lzo1x_1_compress +#endif + +#if 1 && defined(DO_COMPRESS) && !defined(do_compress) +# define do_compress LZO_CPP_ECONCAT2(DO_COMPRESS,_core) +#endif + +#if defined(UA_GET64) +# define WANT_lzo_bitops_ctz64 1 +#elif defined(UA_GET32) +# define WANT_lzo_bitops_ctz32 1 +#endif + +#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#include +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0 +#pragma intrinsic(_BitScanReverse) +static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanReverse(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz32 lzo_bitops_clz32 +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0 +#pragma intrinsic(_BitScanReverse64) +static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanReverse64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_clz64 lzo_bitops_clz64 +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#pragma intrinsic(_BitScanForward) +static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v) +{ + unsigned long r; + (void) _BitScanForward(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz32 lzo_bitops_ctz32 +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#pragma intrinsic(_BitScanForward64) +static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v) +{ + unsigned long r; + (void) _BitScanForward64(&r, v); + return (unsigned) r; +} +#define lzo_bitops_ctz64 lzo_bitops_ctz64 +#endif + +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || LZO_CC_LLVM) +#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) +#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v)) +#endif +#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v)) +#endif +#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) +#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v)) +#endif +#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32) +#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v)) +#endif +#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX) +#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v)) +#endif +#endif + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_uint ti, lzo_voidp wrkmem) +{ + register const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - 20; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip - ti; + + ip += ti < 4 ? 4 - ti : 0; + for (;;) + { + const lzo_bytep m_pos; +#if !(LZO_DETERMINISTIC) + LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0); + lzo_uint m_len; + lzo_uint dindex; +next: + if __lzo_unlikely(ip >= ip_end) + break; + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if defined(UA_GET32) + if (UA_GET32(m_pos) != UA_GET32(ip)) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3]) +#endif + { +literal: + UPDATE_I(dict,0,dindex,ip,in); + ip += 1 + ((ip - ii) >> 5); + continue; + } + UPDATE_I(dict,0,dindex,ip,in); +#else + lzo_uint m_off; + lzo_uint m_len; + { + lzo_uint32 dv; + lzo_uint dindex; +literal: + ip += 1 + ((ip - ii) >> 5); +next: + if __lzo_unlikely(ip >= ip_end) + break; + dv = UA_GET32(ip); + dindex = DINDEX(dv,ip); + GINDEX(m_off,m_pos,in+dict,dindex,in); + UPDATE_I(dict,0,dindex,ip,in); + if __lzo_unlikely(dv != UA_GET32(m_pos)) + goto literal; + } +#endif + + { + register lzo_uint t = pd(ip,ii); + if (t != 0) + { + if (t <= 3) + { + op[-2] |= LZO_BYTE(t); +#if defined(UA_COPY32) + UA_COPY32(op, ii); + op += t; +#else + { do *op++ = *ii++; while (--t > 0); } +#endif + } +#if defined(UA_COPY32) || defined(UA_COPY64) + else if (t <= 16) + { + *op++ = LZO_BYTE(t - 3); +#if defined(UA_COPY64) + UA_COPY64(op, ii); + UA_COPY64(op+8, ii+8); +#else + UA_COPY32(op, ii); + UA_COPY32(op+4, ii+4); + UA_COPY32(op+8, ii+8); + UA_COPY32(op+12, ii+12); +#endif + op += t; + } +#endif + else + { + if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + register lzo_uint tt = t - 18; + *op++ = 0; + while __lzo_unlikely(tt > 255) + { + tt -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } +#if defined(UA_COPY32) || defined(UA_COPY64) + do { +#if defined(UA_COPY64) + UA_COPY64(op, ii); + UA_COPY64(op+8, ii+8); +#else + UA_COPY32(op, ii); + UA_COPY32(op+4, ii+4); + UA_COPY32(op+8, ii+8); + UA_COPY32(op+12, ii+12); +#endif + op += 16; ii += 16; t -= 16; + } while (t >= 16); if (t > 0) +#endif + { do *op++ = *ii++; while (--t > 0); } + } + } + } + m_len = 4; + { +#if defined(UA_GET64) + lzo_uint64 v; + v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 8; + v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz64) + m_len += lzo_bitops_ctz64(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#elif defined(UA_GET32) + lzo_uint32 v; + v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 4; + v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz32) + m_len += lzo_bitops_ctz32(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#else + if __lzo_unlikely(ip[m_len] == m_pos[m_len]) { + do { + m_len += 1; + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (ip[m_len] == m_pos[m_len]); + } +#endif + } +m_len_done: + m_off = pd(ip,m_pos); + ip += m_len; + ii = ip; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + else + { + m_off -= 0x4000; + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8)); + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + goto next; + } + + *out_len = pd(op, out); + return pd(in_end,ii); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + const lzo_bytep ip = in; + lzo_bytep op = out; + lzo_uint l = in_len; + lzo_uint t = 0; + + while (l > 20) + { + lzo_uint ll = l; + lzo_uintptr_t ll_end; +#if 0 || (LZO_DETERMINISTIC) + ll = LZO_MIN(ll, 49152); +#endif + ll_end = (lzo_uintptr_t)ip + ll; + if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll) + break; +#if (LZO_DETERMINISTIC) + lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t)); +#endif + t = do_compress(ip,ll,op,out_len,t,wrkmem); + ip += ll; + op += *out_len; + l -= ll; + } + t += l; + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] |= LZO_BYTE(t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; +#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) + + * (volatile unsigned char *) op++ = 0; +#else + *op++ = 0; +#endif + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + t += 3; + if (t >= 8) do + { + UA_COPY64(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY32(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY64(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN 1 +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + t += 3; + if (t >= 8) do + { + UA_COPY64(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY32(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY32(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY64(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY32(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ + diff --git a/grub-core/lib/minilzo/minilzo.h b/grub-core/lib/minilzo/minilzo.h new file mode 100644 index 000000000..74fefa9fe --- /dev/null +++ b/grub-core/lib/minilzo/minilzo.h @@ -0,0 +1,109 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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 2 of + the License, or (at your option) any later version. + + The LZO 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H +#define __MINILZO_H 1 + +#define MINILZO_VERSION 0x2050 + +#ifdef __LZOCONF_H +# error "you cannot use both LZO and miniLZO" +#endif + +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h index e69de29bb..fe8523e68 100644 --- a/grub-core/lib/posix_wrap/limits.h +++ b/grub-core/lib/posix_wrap/limits.h @@ -0,0 +1,31 @@ +/* + * 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_POSIX_LIMITS_H +#define GRUB_POSIX_LIMITS_H + +#include + +#define UCHAR_MAX GRUB_UCHAR_MAX +#define USHRT_MAX GRUB_USHRT_MAX +#define UINT_MAX GRUB_UINT_MAX +#define ULONG_MAX GRUB_ULONG_MAX + +#define CHAR_BIT 8 + +#endif diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h index 69e49509e..0c58d6c44 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h @@ -24,9 +24,6 @@ typedef grub_size_t size_t; typedef enum { false = 0, true = 1 } bool; -#define ULONG_MAX GRUB_ULONG_MAX -#define UCHAR_MAX 0xff - typedef grub_uint8_t uint8_t; typedef grub_uint16_t uint16_t; typedef grub_uint32_t uint32_t; diff --git a/include/grub/types.h b/include/grub/types.h index 4fd7a3a4b..32d255d40 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -116,6 +116,10 @@ typedef grub_int32_t grub_ssize_t; # define PRIuGRUB_SIZE "u" #endif +#define GRUB_UCHAR_MAX 0xFF +#define GRUB_USHRT_MAX 65535 +#define GRUB_UINT_MAX 4294967295U + #if GRUB_CPU_SIZEOF_LONG == 8 # define GRUB_ULONG_MAX 18446744073709551615UL # define GRUB_LONG_MAX 9223372036854775807L From b2d7e331e2b5cb9899a13e5e105e96d2632da995 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:41:19 +0200 Subject: [PATCH 1183/1414] Add helper functions for easier unaligned memory access. * include/grub/types.h (grub_get_unaligned16): New function. (grub_get_unaligned32): Likewise. (grub_get_unaligned64): Likewise. --- ChangeLog.lzo | 8 ++++++++ include/grub/types.h | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 6f5191db2..701715747 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,11 @@ +2001-08-14 Szymon Janc + + Add helper functions for easier unaligned memory access. + + * include/grub/types.h (grub_get_unaligned16): New function. + (grub_get_unaligned32): Likewise. + (grub_get_unaligned64): Likewise. + 2011-08-14 Szymon Janc Import minilzo library for LZO decompression support. diff --git a/include/grub/types.h b/include/grub/types.h index 32d255d40..f057dd3d3 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -222,4 +222,31 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_cpu_to_le32_compile_time(x) ((grub_uint32_t) (x)) #endif /* ! WORDS_BIGENDIAN */ +static inline grub_uint16_t grub_get_unaligned16(void *ptr) +{ + struct + { + grub_uint16_t d; + } __attribute__((packed)) *dd = ptr; + return dd->d; +} + +static inline grub_uint32_t grub_get_unaligned32(void *ptr) +{ + struct + { + grub_uint32_t d; + } __attribute__((packed)) *dd = ptr; + return dd->d; +} + +static inline grub_uint64_t grub_get_unaligned64(void *ptr) +{ + struct + { + grub_uint64_t d; + } __attribute__((packed)) *dd = ptr; + return dd->d; +} + #endif /* ! GRUB_TYPES_HEADER */ From b6085f323611098c84177e90701809b6a8c5dcaf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:42:53 +0200 Subject: [PATCH 1184/1414] * grub-core/fs/btrfs.c: Some code style fixes. --- ChangeLog.lzo | 4 + grub-core/fs/btrfs.c | 187 +++++++++++++++++++++---------------------- 2 files changed, 94 insertions(+), 97 deletions(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 701715747..0a9d852a4 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,7 @@ +2011-08-14 Szymon Janc + + * grub-core/fs/btrfs.c: Some code style fixes. + 2001-08-14 Szymon Janc Add helper functions for easier unaligned memory access. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 6470c9819..1336c8f02 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -41,7 +41,7 @@ struct grub_btrfs_device } __attribute__ ((packed)); struct grub_btrfs_superblock -{ +{ grub_btrfs_checksum_t checksum; grub_btrfs_uuid_t uuid; grub_uint8_t dummy[0x10]; @@ -160,7 +160,8 @@ struct grub_btrfs_leaf_descriptor { unsigned depth; unsigned allocated; - struct { + struct + { grub_disk_addr_t addr; unsigned iter; unsigned maxiter; @@ -179,7 +180,7 @@ struct grub_btrfs_time { grub_int64_t sec; grub_uint32_t nanosec; -} __attribute__ ((aligned(4))); +} __attribute__ ((aligned (4))); struct grub_btrfs_inode { @@ -219,8 +220,8 @@ struct grub_btrfs_extent_data #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, - 256 * 1048576 * 2, - 1048576ULL * 1048576ULL * 2 }; + 256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 +}; static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, @@ -283,7 +284,7 @@ free_iterator (struct grub_btrfs_leaf_descriptor *desc) } static grub_err_t -save_ref (struct grub_btrfs_leaf_descriptor *desc, +save_ref (struct grub_btrfs_leaf_descriptor *desc, grub_disk_addr_t addr, unsigned i, unsigned m, int l) { desc->depth++; @@ -307,7 +308,7 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, static int next (struct grub_btrfs_data *data, struct grub_btrfs_leaf_descriptor *desc, - grub_disk_addr_t *outaddr, grub_size_t *outsize, + grub_disk_addr_t * outaddr, grub_size_t * outsize, struct grub_btrfs_key *key_out) { grub_err_t err; @@ -316,8 +317,8 @@ next (struct grub_btrfs_data *data, for (; desc->depth > 0; desc->depth--) { desc->data[desc->depth - 1].iter++; - if (desc->data[desc->depth - 1].iter - < desc->data[desc->depth - 1].maxiter) + if (desc->data[desc->depth - 1].iter < + desc->data[desc->depth - 1].maxiter) break; } if (desc->depth == 0) @@ -330,17 +331,17 @@ next (struct grub_btrfs_data *data, err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter * sizeof (node) + sizeof (struct btrfs_header) - + desc->data[desc->depth - 1].addr, &node, - sizeof (node)); + + desc->data[desc->depth - 1].addr, + &node, sizeof (node)); if (err) return -err; - err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), &head, - sizeof (head)); + err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), + &head, sizeof (head)); if (err) return -err; - save_ref (desc, grub_le_to_cpu64 (node.addr), 0, + save_ref (desc, grub_le_to_cpu64 (node.addr), 0, grub_le_to_cpu32 (head.nitems), !head.level); } err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter @@ -354,15 +355,15 @@ next (struct grub_btrfs_data *data, *outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header) + grub_le_to_cpu32 (leaf.offset); *key_out = leaf.key; - return 1; + return 1; } static grub_err_t lower_bound (struct grub_btrfs_data *data, - const struct grub_btrfs_key *key_in, + const struct grub_btrfs_key *key_in, struct grub_btrfs_key *key_out, grub_disk_addr_t root, - grub_disk_addr_t *outaddr, grub_size_t *outsize, + grub_disk_addr_t * outaddr, grub_size_t * outsize, struct grub_btrfs_leaf_descriptor *desc) { grub_disk_addr_t addr = root; @@ -410,8 +411,9 @@ lower_bound (struct grub_btrfs_data *data, grub_dprintf ("btrfs", "internal node (depth %d) %" PRIxGRUB_UINT64_T " %x %" PRIxGRUB_UINT64_T "\n", depth, - node.key.object_id, node.key.type, node.key.offset); - + node.key.object_id, node.key.type, + node.key.offset); + if (key_cmp (&node.key, key_in) == 0) { err = GRUB_ERR_NONE; @@ -433,7 +435,7 @@ lower_bound (struct grub_btrfs_data *data, err = GRUB_ERR_NONE; if (desc) err = save_ref (desc, addr - sizeof (head), i - 1, - grub_le_to_cpu32 (head.nitems), 0); + grub_le_to_cpu32 (head.nitems), 0); if (err) return err; addr = grub_le_to_cpu64 (node_last.addr); @@ -457,7 +459,7 @@ lower_bound (struct grub_btrfs_data *data, &leaf, sizeof (leaf)); if (err) return err; - + grub_dprintf ("btrfs", "leaf (depth %d) %" PRIxGRUB_UINT64_T " %x %" PRIxGRUB_UINT64_T "\n", depth, @@ -465,31 +467,31 @@ lower_bound (struct grub_btrfs_data *data, if (key_cmp (&leaf.key, key_in) == 0) { - grub_memcpy (key_out, &leaf.key, sizeof(*key_out)); + grub_memcpy (key_out, &leaf.key, sizeof (*key_out)); *outsize = grub_le_to_cpu32 (leaf.size); *outaddr = addr + grub_le_to_cpu32 (leaf.offset); if (desc) return save_ref (desc, addr - sizeof (head), i, grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } - + if (key_cmp (&leaf.key, key_in) > 0) break; - + have_last = 1; leaf_last = leaf; } if (have_last) { - grub_memcpy (key_out, &leaf_last.key, sizeof(*key_out)); + grub_memcpy (key_out, &leaf_last.key, sizeof (*key_out)); *outsize = grub_le_to_cpu32 (leaf_last.size); *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); if (desc) return save_ref (desc, addr - sizeof (head), i - 1, grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } *outsize = 0; *outaddr = 0; @@ -503,8 +505,7 @@ lower_bound (struct grub_btrfs_data *data, } static grub_device_t -find_device (struct grub_btrfs_data *data, grub_uint64_t id, - int do_rescan) +find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) { grub_device_t dev_found = NULL; auto int hook (const char *name); @@ -540,7 +541,7 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, grub_device_close (dev); return 0; } - + dev_found = dev; return 1; } @@ -579,17 +580,16 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, } static grub_err_t -grub_btrfs_read_logical (struct grub_btrfs_data *data, - grub_disk_addr_t addr, +grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, void *buf, grub_size_t size) { while (size > 0) { grub_uint8_t *ptr; struct grub_btrfs_key *key; - struct grub_btrfs_chunk_item *chunk; + struct grub_btrfs_chunk_item *chunk; grub_uint64_t csize; - grub_err_t err = 0; + grub_err_t err = 0; struct grub_btrfs_key key_out; int challoc = 0; grub_device_t dev; @@ -601,20 +601,20 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, addr); for (ptr = data->sblock.bootstrap_mapping; ptr < data->sblock.bootstrap_mapping - + sizeof (data->sblock.bootstrap_mapping) - - sizeof (struct grub_btrfs_key); - ) + + sizeof (data->sblock.bootstrap_mapping) + - sizeof (struct grub_btrfs_key);) { key = (struct grub_btrfs_key *) ptr; if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK) break; chunk = (struct grub_btrfs_chunk_item *) (key + 1); - grub_dprintf ("btrfs", "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", + grub_dprintf ("btrfs", + "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", grub_le_to_cpu64 (key->offset), grub_le_to_cpu64 (chunk->size)); if (grub_le_to_cpu64 (key->offset) <= addr - && addr < grub_le_to_cpu64 (key->offset) - + grub_le_to_cpu64 (chunk->size)) + && addr < + grub_le_to_cpu64 (key->offset) + grub_le_to_cpu64 (chunk->size)) goto chunk_found; ptr += sizeof (*key) + sizeof (*chunk) + sizeof (struct grub_btrfs_chunk_stripe) @@ -704,11 +704,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), &low); - + high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes), &stripen); - stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) - * high; + stripe_offset = + low + grub_le_to_cpu64 (chunk->stripe_length) * high; csize = grub_le_to_cpu64 (chunk->stripe_length) - low; break; } @@ -719,7 +719,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, middle = grub_divmod64 (off, grub_le_to_cpu64 (chunk->stripe_length), &low); - + high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nsubstripes), &stripen); @@ -759,7 +759,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, paddr = stripe->offset + stripe_offset; grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T " (%d stripes (%d substripes) of %" + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T " maps to 0x%" PRIxGRUB_UINT64_T "\n", grub_le_to_cpu64 (key->offset), @@ -769,7 +770,7 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_le_to_cpu64 (chunk->stripe_length), stripen, stripe->offset); grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - " for laddr 0x%" PRIxGRUB_UINT64_T"\n", paddr, + " for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr, addr); dev = find_device (data, stripe->device_id, j); @@ -815,7 +816,7 @@ grub_btrfs_mount (grub_device_t dev) } data = grub_zalloc (sizeof (*data)); - if (! data) + if (!data) return NULL; err = read_sblock (dev->disk, &data->sblock); @@ -866,8 +867,7 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; key_in.offset = 0; - err = lower_bound (data, &key_in, &key_out, tree, - &elemaddr, &elemsize, NULL); + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL); if (err) return err; if (num != key_out.object_id @@ -917,19 +917,17 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (!data->extent) return grub_errno; - err = grub_btrfs_read_logical (data, elemaddr, - data->extent, elemsize); + err = grub_btrfs_read_logical (data, elemaddr, data->extent, + elemsize); if (err) return err; - data->extend = data->extstart - + grub_le_to_cpu64 (data->extent->size); + data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size); if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR - && (char *) &data->extent + elemsize - >= (char *) &data->extent->filled - + sizeof (data->extent->filled)) - data->extend = data->extstart - + grub_le_to_cpu64 (data->extent->filled); + && (char *) &data->extent + elemsize >= + (char *) &data->extent->filled + sizeof (data->extent->filled)) + data->extend = + data->extstart + grub_le_to_cpu64 (data->extent->filled); grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" PRIxGRUB_UINT64_T " (0x%" @@ -966,8 +964,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (data->extent->encoding) { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "encoding not supported"); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encoding not supported"); return -1; } @@ -1008,8 +1005,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_free (tmp); return -1; } - if (grub_zlib_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), + if (grub_zlib_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), buf, csize) != (grub_ssize_t) csize) { grub_free (tmp); @@ -1021,14 +1018,13 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + grub_le_to_cpu64 (data->extent->offset) - + extoff, - buf, csize); + + extoff, buf, csize); if (err) return -1; break; default: grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported extent type 0x%x", data->extent->type); + "unsupported extent type 0x%x", data->extent->type); return -1; } buf += csize; @@ -1041,7 +1037,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, static grub_err_t find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, - grub_uint64_t *tree, grub_uint8_t *type) + grub_uint64_t * tree, grub_uint8_t * type) { const char *slash = path; grub_err_t err; @@ -1096,9 +1092,9 @@ find_path (struct grub_btrfs_data *data, key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); - - err = lower_bound (data, key, &key_out, *tree, - &elemaddr, &elemsize, NULL); + + err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, + NULL); if (err) { grub_free (direl); @@ -1140,7 +1136,7 @@ find_path (struct grub_btrfs_data *data, for (cdirel = direl; (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; + < (grub_ssize_t) elemsize; cdirel = (void *) ((grub_uint8_t *) (direl + 1) + grub_le_to_cpu16 (cdirel->n) + grub_le_to_cpu16 (cdirel->m))) @@ -1174,7 +1170,7 @@ find_path (struct grub_btrfs_data *data, return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); } - + err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, *tree); if (err) @@ -1205,7 +1201,7 @@ find_path (struct grub_btrfs_data *data, grub_free (tmp); return grub_errno; } - grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, + grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, grub_strlen (path) + 1); grub_free (path_alloc); grub_free (origpath); @@ -1247,8 +1243,7 @@ find_path (struct grub_btrfs_data *data, grub_free (origpath); return err; } - err = grub_btrfs_read_logical (data, elemaddr, - &ri, sizeof (ri)); + err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri)); if (err) { grub_free (direl); @@ -1279,7 +1274,7 @@ find_path (struct grub_btrfs_data *data, grub_free (path_alloc); grub_free (origpath); grub_free (direl); - return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", + return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", cdirel->key.type); } } @@ -1290,8 +1285,8 @@ find_path (struct grub_btrfs_data *data, static grub_err_t grub_btrfs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) + int (*hook) (const char *filename, + const struct grub_dirhook_info * info)) { struct grub_btrfs_data *data = grub_btrfs_mount (device); struct grub_btrfs_key key_in, key_out; @@ -1312,10 +1307,9 @@ grub_btrfs_dir (grub_device_t device, const char *path, if (err) return err; if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); - err = lower_bound (data, &key_in, &key_out, tree, - &elemaddr, &elemsize, &desc); + err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, &desc); if (err) return err; if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM @@ -1355,7 +1349,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, for (cdirel = direl; (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; + < (grub_ssize_t) elemsize; cdirel = (void *) ((grub_uint8_t *) (direl + 1) + grub_le_to_cpu16 (cdirel->n) + grub_le_to_cpu16 (cdirel->m))) @@ -1384,7 +1378,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, } while (r > 0); - out: +out: grub_free (direl); free_iterator (&desc); @@ -1456,7 +1450,7 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) *uuid = NULL; data = grub_btrfs_mount (device); - if (! data) + if (!data) return grub_errno; *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", @@ -1482,7 +1476,7 @@ grub_btrfs_label (grub_device_t device, char **label) *label = NULL; data = grub_btrfs_mount (device); - if (! data) + if (!data) return grub_errno; *label = grub_strndup (data->sblock.label, sizeof (data->sblock.label)); @@ -1492,26 +1486,25 @@ grub_btrfs_label (grub_device_t device, char **label) return grub_errno; } -static struct grub_fs grub_btrfs_fs = - { - .name = "btrfs", - .dir = grub_btrfs_dir, - .open = grub_btrfs_open, - .read = grub_btrfs_read, - .close = grub_btrfs_close, - .uuid = grub_btrfs_uuid, - .label = grub_btrfs_label, +static struct grub_fs grub_btrfs_fs = { + .name = "btrfs", + .dir = grub_btrfs_dir, + .open = grub_btrfs_open, + .read = grub_btrfs_read, + .close = grub_btrfs_close, + .uuid = grub_btrfs_uuid, + .label = grub_btrfs_label, #ifdef GRUB_UTIL - .reserved_first_sector = 1, + .reserved_first_sector = 1, #endif - }; +}; -GRUB_MOD_INIT(btrfs) +GRUB_MOD_INIT (btrfs) { grub_fs_register (&grub_btrfs_fs); } -GRUB_MOD_FINI(btrfs) +GRUB_MOD_FINI (btrfs) { grub_fs_unregister (&grub_btrfs_fs); } From 095f077e6db33fefb9c9eae6fcbb47b2bef577f8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 14 Aug 2011 11:46:05 +0200 Subject: [PATCH 1185/1414] Add support for LZO compression in btrfs. * Makefile.util.def (libgrubmods.a): Add minilzo.c and add required flags to cflags in cppflags. * Makefile.core.def (btrfs): Likewise. * grub-core/fs/btrfs.c: Include minilzo.h. (grub_btrfs_superblock): Add sectorsize, nodesize, leafsize, stripsize and dummy5 field. (GRUB_BTRFS_COMPRESSION_LZO): New define. (grub_btrfs_extent_read): Add support for LZO compression type. --- ChangeLog.lzo | 13 ++++ Makefile.util.def | 3 + grub-core/Makefile.core.def | 3 + grub-core/fs/btrfs.c | 136 ++++++++++++++++++++++++++++++++---- 4 files changed, 143 insertions(+), 12 deletions(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 0a9d852a4..c89255389 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,16 @@ +2011-08-14 Szymon Janc + + Add support for LZO compression in btrfs. + + * Makefile.util.def (libgrubmods.a): Add minilzo.c and add required flags + to cflags in cppflags. + * Makefile.core.def (btrfs): Likewise. + * grub-core/fs/btrfs.c: Include minilzo.h. + (grub_btrfs_superblock): Add sectorsize, nodesize, leafsize, stripsize and + dummy5 field. + (GRUB_BTRFS_COMPRESSION_LZO): New define. + (grub_btrfs_extent_read): Add support for LZO compression type. + 2011-08-14 Szymon Janc * grub-core/fs/btrfs.c: Some code style fixes. diff --git a/Makefile.util.def b/Makefile.util.def index d86cb9761..3628e48f6 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -33,6 +33,8 @@ library = { library = { name = libgrubmods.a; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(top_srcdir)/grub-core/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; common_nodist = grub_script.tab.c; common_nodist = grub_script.yy.c; @@ -107,6 +109,7 @@ library = { common = grub-core/script/argv.c; common = grub-core/io/gzio.c; common = grub-core/kern/ia64/dl_helper.c; + common = grub-core/lib/minilzo/minilzo.c; }; program = { diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 0924602f3..1ff179c67 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -979,6 +979,9 @@ module = { name = btrfs; common = fs/btrfs.c; common = lib/crc.c; + common = lib/minilzo/minilzo.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; module = { diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 1336c8f02..1d24da3e3 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -26,6 +26,7 @@ #include #include #include +#include "minilzo.h" GRUB_MOD_LICENSE ("GPLv3+"); @@ -51,10 +52,15 @@ struct grub_btrfs_superblock grub_uint64_t chunk_tree; grub_uint8_t dummy2[0x20]; grub_uint64_t root_dir_objectid; - grub_uint8_t dummy3[0x41]; + grub_uint8_t dummy3[0x8]; + grub_uint32_t sectorsize; + grub_uint32_t nodesize; + grub_uint32_t leafsize; + grub_uint32_t stripsize; + grub_uint8_t dummy4[0x29]; struct grub_btrfs_device this_device; char label[0x100]; - grub_uint8_t dummy4[0x100]; + grub_uint8_t dummy5[0x100]; grub_uint8_t bootstrap_mapping[0x800]; } __attribute__ ((packed)); @@ -216,6 +222,7 @@ struct grub_btrfs_extent_data #define GRUB_BTRFS_COMPRESSION_NONE 0 #define GRUB_BTRFS_COMPRESSION_ZLIB 1 +#define GRUB_BTRFS_COMPRESSION_LZO 2 #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 @@ -954,7 +961,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE - && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB) + && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB + && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "compression type 0x%x not supported", @@ -980,6 +988,42 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, != (grub_ssize_t) csize) return -1; } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + { + grub_uint32_t total_size, chunk_size; + unsigned char *obuf; + unsigned char *ibuf = (unsigned char *) data->extent->inl; + lzo_uint ocnt = extoff + csize; + int ret; + + obuf = grub_malloc (extoff + csize); + if (!obuf) + return -1; + + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (chunk_size); + + /* Can we have multiple chunks in inline extent? */ + if (chunk_size + (sizeof (grub_uint32_t) * 2) != total_size) + { + grub_free (obuf); + return -1; + } + + ret = lzo1x_decompress_safe (ibuf, chunk_size, obuf, &ocnt, NULL); + + if (ret != LZO_E_OK) + { + grub_free (obuf); + return -1; + } + + grub_memcpy (buf, obuf + extoff, ocnt - extoff); + grub_free (obuf); + } else grub_memcpy (buf, data->extent->inl + extoff, csize); break; @@ -989,9 +1033,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_memset (buf, 0, csize); break; } - if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) + + if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE) { - char *tmp; + void *tmp; grub_uint64_t zsize; zsize = grub_le_to_cpu64 (data->extent->compressed_size); tmp = grub_malloc (zsize); @@ -1005,16 +1050,83 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_free (tmp); return -1; } - if (grub_zlib_decompress (tmp, zsize, extoff + - grub_le_to_cpu64 (data->extent->offset), - buf, csize) != (grub_ssize_t) csize) + + if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) { + grub_ssize_t ret; + + ret = grub_zlib_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + grub_free (tmp); - return -1; + + if (ret != (grub_ssize_t) csize) + return -1; + + break; } - grub_free (tmp); - break; - } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + { + grub_uint32_t total_size, chunk_size, usize = 0; + grub_size_t off = extoff; + unsigned char *chunk, *ibuf = tmp; + char *obuf = buf; + /* XXX Is this correct size from sblock? */ + grub_uint32_t udata_size = grub_le_to_cpu32 (data->sblock.sectorsize); + + chunk = grub_malloc (udata_size); + if (!chunk) + { + grub_free (tmp); + return -1; + } + + /* XXX Use this for some sanity checks while decompressing. */ + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (chunk_size); + + /* Jump to first chunk with requested data. */ + while (off >= udata_size) + { + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (chunk_size); + ibuf += chunk_size; + off -= udata_size; + } + + while (usize < csize) + { + chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + lzo_uint csize2 = udata_size; + int diff; + + ibuf += sizeof (chunk_size); + + if (lzo1x_decompress_safe (ibuf, chunk_size, chunk, &csize2, NULL) != LZO_E_OK) + { + grub_free (tmp); + grub_free (chunk); + return -1; + } + + diff = grub_min (csize2 - off, csize - usize); + + grub_memcpy (obuf, chunk + off, diff); + obuf += diff; + ibuf += chunk_size; + usize += diff; + off = 0; + } + + grub_free (tmp); + grub_free (chunk); + break; + } + } err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + grub_le_to_cpu64 (data->extent->offset) From 5f60ccac6f0c1a4236a964bed630c95ab67331cb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 15 Aug 2011 23:21:29 +0100 Subject: [PATCH 1186/1414] * util/grub-probe.c: Remove duplicate #include. --- ChangeLog | 4 ++++ util/grub-probe.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 039621768..b4ec6f677 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-15 Colin Watson + + * util/grub-probe.c: Remove duplicate #include. + 2011-08-10 Robert Millan Detect LSI MegaRAID SAS (`mfi') devices on GNU/kFreeBSD. diff --git a/util/grub-probe.c b/util/grub-probe.c index 7c0a75123..3f519bcb4 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include From 828bc390d82e119133877f67ddd1eb3795fb8afc Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 15 Aug 2011 23:30:11 +0100 Subject: [PATCH 1187/1414] * util/grub-probe.c (probe): Canonicalise the path argument, fixing use of "/path/.." as in grub-install for EFI as well as handling symlinks correctly. Fixes Debian bug #637768. --- ChangeLog | 8 ++++++++ util/grub-probe.c | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b4ec6f677..f3c2cf690 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-08-15 Mario Limonciello +2011-08-15 Colin Watson + + * util/grub-probe.c (probe): Canonicalise the path argument, fixing + use of "/path/.." as in grub-install for EFI as well as handling + symlinks correctly. + Fixes Debian bug #637768. + 2011-08-15 Colin Watson * util/grub-probe.c: Remove duplicate #include. diff --git a/util/grub-probe.c b/util/grub-probe.c index 3f519bcb4..ae58c89f3 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -180,7 +180,10 @@ probe (const char *path, char *device_name) #endif } else - device_name = grub_guess_root_device (path); + { + grub_path = canonicalize_file_name (path); + device_name = grub_guess_root_device (grub_path); + } if (! device_name) grub_util_error ("cannot find a device for %s (is /dev mounted?)", path); From b1257f653367e8d21b625276f53f086d68fab0b3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Aug 2011 16:11:10 +0200 Subject: [PATCH 1188/1414] Don't accept text modes on EFI when booting Linux. * grub-core/loader/i386/linux.c (ACCEPTS_PURE_TEXT): New define. (grub_linux_boot) [!ACCEPTS_PURE_TEXT]: Restrict to graphics modes. --- ChangeLog | 7 +++++++ grub-core/loader/i386/linux.c | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3c2cf690..fc1ea8713 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-08-16 Vladimir Serbinenko + + Don't accept text modes on EFI when booting Linux. + + * grub-core/loader/i386/linux.c (ACCEPTS_PURE_TEXT): New define. + (grub_linux_boot) [!ACCEPTS_PURE_TEXT]: Restrict to graphics modes. + 2011-08-15 Mario Limonciello 2011-08-15 Colin Watson diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 9e3d482ab..5356d7ace 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -45,15 +45,18 @@ GRUB_MOD_LICENSE ("GPLv3+"); #include #define HAS_VGA_TEXT 0 #define DEFAULT_VIDEO_MODE "auto" +#define ACCEPTS_PURE_TEXT 0 #elif defined (GRUB_MACHINE_IEEE1275) #include #define HAS_VGA_TEXT 0 #define DEFAULT_VIDEO_MODE "text" +#define ACCEPTS_PURE_TEXT 1 #else #include #include #define HAS_VGA_TEXT 1 #define DEFAULT_VIDEO_MODE "text" +#define ACCEPTS_PURE_TEXT 1 #endif #define GRUB_LINUX_CL_OFFSET 0x1000 @@ -483,12 +486,22 @@ grub_linux_boot (void) tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; +#if ACCEPTS_PURE_TEXT err = grub_video_set_mode (tmp, 0, 0); +#else + err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +#endif grub_free (tmp); } else - err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); - + { +#if ACCEPTS_PURE_TEXT + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); +#else + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +#endif + } if (err) { grub_print_error (); From 5c144cc8b2cd13b88a0cd214cfa8ee8207aad1c0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Aug 2011 16:19:06 +0200 Subject: [PATCH 1189/1414] * util/grub-setup.c (main): Add missing gcry initialisation. --- ChangeLog | 4 ++++ util/grub-setup.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index fc1ea8713..7acaf320c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-16 Vladimir Serbinenko + + * util/grub-setup.c (main): Add missing gcry initialisation. + 2011-08-16 Vladimir Serbinenko Don't accept text modes on EFI when booting Linux. diff --git a/util/grub-setup.c b/util/grub-setup.c index 8482e11c9..2505c03a4 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -893,6 +893,7 @@ main (int argc, char *argv[]) /* Initialize all modules. */ grub_init_all (); + grub_gcry_init_all (); grub_lvm_fini (); grub_mdraid09_fini (); From 43526629e58ac5d5eec0c7b6454bb96d750d197b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Aug 2011 23:10:38 +0200 Subject: [PATCH 1190/1414] * grub-core/fs/jfs.c (grub_jfs_read_file): New parameter ino. All users updated. (grub_jfs_lookup_symlink): Use correct starting inode. --- ChangeLog | 6 ++++++ grub-core/fs/jfs.c | 15 ++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7acaf320c..c414d79e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-08-16 Vladimir Serbinenko + + * grub-core/fs/jfs.c (grub_jfs_read_file): New parameter ino. + All users updated. + (grub_jfs_lookup_symlink): Use correct starting inode. + 2011-08-16 Vladimir Serbinenko * util/grub-setup.c (main): Add missing gcry initialisation. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 36ec5fd25..ebc2c688a 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -614,7 +614,8 @@ grub_jfs_read_file (struct grub_jfs_data *data, /* Find the file with the pathname PATH on the filesystem described by DATA. */ static grub_err_t -grub_jfs_find_file (struct grub_jfs_data *data, const char *path) +grub_jfs_find_file (struct grub_jfs_data *data, const char *path, + grub_uint32_t start_ino) { char fpath[grub_strlen (path)]; char *name = fpath; @@ -623,7 +624,7 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path) grub_strncpy (fpath, path, grub_strlen (path) + 1); - if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode)) + if (grub_jfs_read_inode (data, start_ino, &data->currinode)) return grub_errno; /* Skip the first slashes. */ @@ -724,11 +725,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) if (symlink[0] == '/') ino = 2; - /* Now load in the old inode. */ - if (grub_jfs_read_inode (data, ino, &data->currinode)) - return grub_errno; - - grub_jfs_find_file (data, symlink); + grub_jfs_find_file (data, symlink, ino); if (grub_errno) grub_error (grub_errno, "cannot follow symlink `%s'", symlink); @@ -750,7 +747,7 @@ grub_jfs_dir (grub_device_t device, const char *path, if (!data) goto fail; - if (grub_jfs_find_file (data, path)) + if (grub_jfs_find_file (data, path, GRUB_JFS_AGGR_INODE)) goto fail; diro = grub_jfs_opendir (data, &data->currinode); @@ -801,7 +798,7 @@ grub_jfs_open (struct grub_file *file, const char *name) if (!data) goto fail; - grub_jfs_find_file (data, name); + grub_jfs_find_file (data, name, GRUB_JFS_AGGR_INODE); if (grub_errno) goto fail; From 2bba8cfd55fb65fe92d47c9b14d6953940128a5e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Aug 2011 23:12:20 +0200 Subject: [PATCH 1191/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_iterate): Skip with non-zero pull. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index c414d79e7..946dcbd80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-16 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_iterate): Skip with + non-zero pull. + 2011-08-16 Vladimir Serbinenko * grub-core/fs/jfs.c (grub_jfs_read_file): New parameter ino. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index d1f76b28c..000ef2f79 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -217,6 +217,9 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), { unsigned i; + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) if (map[i].drive && hook (map[i].drive)) return 1; From d6beefcfc9d3451fe262b6d57ccc215db8ce5681 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 17 Aug 2011 19:40:25 +0200 Subject: [PATCH 1192/1414] Add initial support for lzop files decompression. * grub-core/Makefile.core.def (lzopio): New module. * grub-core/io/lzopio.c: New file. * include/grub/file.h (grub_file_filter_id): New compression filter GRUB_FILE_FILTER_LZOPIO. --- ChangeLog.lzo | 9 + grub-core/Makefile.core.def | 8 + grub-core/io/lzopio.c | 527 ++++++++++++++++++++++++++++++++++++ include/grub/file.h | 1 + 4 files changed, 545 insertions(+) create mode 100644 grub-core/io/lzopio.c diff --git a/ChangeLog.lzo b/ChangeLog.lzo index c89255389..782c6b60d 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,12 @@ +2011-08-17 Szymon Janc + + Add initial support for lzop files decompression. + + * grub-core/Makefile.core.def (lzopio): New module. + * grub-core/io/lzopio.c: New file. + * include/grub/file.h (grub_file_filter_id): New compression filter + GRUB_FILE_FILTER_LZOPIO. + 2011-08-14 Szymon Janc Add support for LZO compression in btrfs. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 1ff179c67..67959d861 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1651,6 +1651,14 @@ module = { cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed'; }; +module = { + name = lzopio; + common = io/lzopio.c; + common = lib/minilzo/minilzo.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; +}; + module = { name = testload; common = commands/testload.c; diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c new file mode 100644 index 000000000..4ccc41a16 --- /dev/null +++ b/grub-core/io/lzopio.c @@ -0,0 +1,527 @@ +/* lzopio.c - decompression support for lzop */ +/* + * 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 + +#include "minilzo.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" +#define LZOP_MAGIC_SIZE 9 +#define CHECK_SIZE 4 +#define NEW_LZO_LIB 0x0940 +#define MIN_HEADER_SIZE 0 +#define MAX_HEADER_SIZE 0 + +/* Header flags - copied from conf.h of LZOP source code. */ +#define F_ADLER32_D 0x00000001L +#define F_ADLER32_C 0x00000002L +#define F_STDIN 0x00000004L +#define F_STDOUT 0x00000008L +#define F_NAME_DEFAULT 0x00000010L +#define F_DOSISH 0x00000020L +#define F_H_EXTRA_FIELD 0x00000040L +#define F_H_GMTDIFF 0x00000080L +#define F_CRC32_D 0x00000100L +#define F_CRC32_C 0x00000200L +#define F_MULTIPART 0x00000400L +#define F_H_FILTER 0x00000800L +#define F_H_CRC32 0x00001000L +#define F_H_PATH 0x00002000L +#define F_MASK 0x00003FFFL + +struct block_header +{ + grub_uint32_t usize; + grub_uint32_t csize; + grub_uint32_t ucheck; + grub_uint32_t ccheck; + unsigned char *cdata; + unsigned char *udata; +}; + +struct grub_lzopio +{ + grub_file_t file; + int ucheck; /* XXX Use gcry to validate checks. */ + int ccheck; + grub_off_t saved_off; /* Rounded down to block boundary. */ + grub_off_t start_block_off; + struct block_header block; +}; + +typedef struct grub_lzopio *grub_lzopio_t; +static struct grub_fs grub_lzopio_fs; + +/* Some helper functions. Memory allocated by those function is free either + * on next read_block_header() or on close() so no risk of leaks. This makes + * those function simpler. */ + +/* Read block header from file, after successful exit file points to + * beginning of block data. */ +static int +read_block_header (struct grub_lzopio *lzopio) +{ + /* Free cached block data if any. */ + grub_free (lzopio->block.udata); + grub_free (lzopio->block.cdata); + lzopio->block.udata = NULL; + lzopio->block.cdata = NULL; + + if (grub_file_read (lzopio->file, &lzopio->block.usize, + sizeof (lzopio->block.usize)) != + sizeof (lzopio->block.usize)) + return -1; + + lzopio->block.usize = grub_be_to_cpu32 (lzopio->block.usize); + + /* Last block has uncompressed data size == 0 and no other fields. */ + if (lzopio->block.usize == 0) + { + if (grub_file_tell (lzopio->file) == grub_file_size (lzopio->file)) + return 0; + else + return -1; + } + + /* Read compressed data block size. */ + if (grub_file_read (lzopio->file, &lzopio->block.csize, + sizeof (lzopio->block.csize)) != + sizeof (lzopio->block.csize)) + return -1; + + lzopio->block.csize = grub_be_to_cpu32 (lzopio->block.csize); + + /* XXX Handle incompressible data case here rather than in uncompress_block. + * This will allow to handle switch of ccheck/ucheck easier and also + * make uncompress_block() a bit simpler. */ + + /* Read data checks. */ + if (lzopio->ucheck) + { + if (grub_file_read (lzopio->file, &lzopio->block.ucheck, + sizeof (lzopio->block.ucheck)) != + sizeof (lzopio->block.ucheck)) + return -1; + } + + if (lzopio->ccheck) + { + if (grub_file_read (lzopio->file, &lzopio->block.ccheck, + sizeof (lzopio->block.ccheck)) != + sizeof (lzopio->block.ccheck)) + return -1; + } + return 0; +} + +/* Read block data into memory. File must be set to beginning of block data. + * Can't be called on last block. */ +static int +read_block_data (struct grub_lzopio *lzopio) +{ + lzopio->block.cdata = grub_malloc (lzopio->block.csize); + if (!lzopio->block.cdata) + return -1; + + if (grub_file_read (lzopio->file, lzopio->block.cdata, lzopio->block.csize) + != (grub_ssize_t) lzopio->block.csize) + return -1; + + if (lzopio->ccheck) + { + /* XXX Validate data checksum here. */ + } + + return 0; +} + +/* Read block data, uncompressed and also store it in memory. */ +/* XXX Investigate possibility of in-place decompression to reduce memory + * footprint. */ +static int +uncompress_block (struct grub_lzopio *lzopio) +{ + lzo_uint usize = lzopio->block.usize; + + if (read_block_data (lzopio) < 0) + return -1; + + if (lzopio->block.usize > lzopio->block.csize) + { + lzopio->block.udata = grub_malloc (lzopio->block.usize); + if (!lzopio->block.udata) + return -1; + + if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, + lzopio->block.udata, &usize, + NULL) != LZO_E_OK) + return -1; + + if (lzopio->ucheck) + { + /* XXX Validate data checksum here. */ + } + + /* Compressed data can be free now. */ + grub_free (lzopio->block.cdata); + lzopio->block.cdata = NULL; + } + /* Incompressible block of data. */ + else if (lzopio->block.usize == lzopio->block.csize) + { + lzopio->block.udata = lzopio->block.cdata; + lzopio->block.cdata = NULL; + } + else + { + return -1; + } + + return 0; +} + +/* Jump to next block and read its header. */ +static int +jump_block (struct grub_lzopio *lzopio) +{ + /* only jump if block was not decompressed (and read from disk) */ + if (!lzopio->block.udata) + { + grub_off_t off = grub_file_tell (lzopio->file) + lzopio->block.csize; + + if (grub_file_seek (lzopio->file, off) == ((grub_off_t) - 1)) + return -1; + } + + lzopio->saved_off += lzopio->block.usize; + + return read_block_header (lzopio); +} + +static int +calculate_uncompressed_size (grub_file_t file) +{ + grub_lzopio_t lzopio = file->data; + grub_off_t usize_total = 0; + + if (read_block_header (lzopio) < 0) + return 0; + + /* FIXME: Don't do this for not easily seekable files. */ + while (lzopio->block.usize != 0) + { + usize_total += lzopio->block.usize; + + if (jump_block (lzopio) < 0) + return 0; + } + + file->size = usize_total; + + return 1; +} + +/* XXX Do something with this function, it is insane now:) */ +static int +test_header (grub_file_t file) +{ + grub_lzopio_t lzopio = file->data; + unsigned char magic[LZOP_MAGIC_SIZE]; + grub_uint16_t lzopver, ver, ver_ext; + grub_uint8_t method, level, name_len; + grub_uint32_t flags, mode, filter, mtime_lo, mtime_hi, checksum; + unsigned char *name = NULL; + + if (grub_file_read (lzopio->file, magic, sizeof (magic)) != sizeof (magic)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); + return 0; + } + + if (grub_memcmp (magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); + return 0; + } + + /* LZOP version. */ + if (grub_file_read (lzopio->file, &lzopver, sizeof (lzopver)) != + sizeof (lzopver)) + goto CORRUPTED; + + /* LZO lib version. */ + if (grub_file_read (lzopio->file, &ver, sizeof (ver)) != sizeof (ver)) + goto CORRUPTED; + + ver = grub_be_to_cpu16 (ver); + + if (ver >= NEW_LZO_LIB) + { + /* Read version of lib needed to extract data. */ + if (grub_file_read (lzopio->file, &ver_ext, sizeof (ver_ext)) != + sizeof (ver_ext)) + goto CORRUPTED; + + /* Too new version, should upgrade minilzo? */ + if (grub_be_to_cpu16 (ver_ext) > MINILZO_VERSION) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "unsupported LZO version"); + return 0; + } + } + + if (grub_file_read (lzopio->file, &method, sizeof (method)) != + sizeof (method)) + goto CORRUPTED; + + if (ver >= NEW_LZO_LIB) + { + if (grub_file_read (lzopio->file, &level, sizeof (level)) != + sizeof (level)) + goto CORRUPTED; + } + + if (grub_file_read (lzopio->file, &flags, sizeof (flags)) != sizeof (flags)) + goto CORRUPTED; + + flags = grub_be_to_cpu32 (flags); + + if (flags & F_CRC32_D) + lzopio->ucheck = 1; + else if (flags & F_ADLER32_D) + lzopio->ucheck = 2; + + if (flags & F_CRC32_C) + lzopio->ccheck = 1; + else if (flags & F_ADLER32_C) + lzopio->ccheck = 2; + + if (flags & F_H_FILTER) + { + if (grub_file_read (lzopio->file, &filter, sizeof (filter)) != + sizeof (filter)) + goto CORRUPTED; + } + + if (grub_file_read (lzopio->file, &mode, sizeof (mode)) != sizeof (mode)) + goto CORRUPTED; + + if (grub_file_read (lzopio->file, &mtime_lo, sizeof (mtime_lo)) != + sizeof (mtime_lo)) + goto CORRUPTED; + + if (ver >= NEW_LZO_LIB) + { + if (grub_file_read (lzopio->file, &mtime_hi, sizeof (mtime_hi)) != + sizeof (mtime_hi)) + goto CORRUPTED; + } + + if (grub_file_read (lzopio->file, &name_len, sizeof (name_len)) != + sizeof (name_len)) + goto CORRUPTED; + + if (name_len != 0) + { + name = grub_malloc (name_len); + if (!name) + return 0; + + if (grub_file_read (lzopio->file, name, name_len) != name_len) + { + grub_free (name); + goto CORRUPTED; + } + } + + if (grub_file_read (lzopio->file, &checksum, sizeof (checksum)) != + sizeof (checksum)) + { + grub_free (name); + goto CORRUPTED; + } + + grub_free (name); + + /* XXX Validate header checksum here. */ + if (checksum == checksum) + { + lzopio->start_block_off = grub_file_tell (lzopio->file); + + if (calculate_uncompressed_size (file) < 0) + goto CORRUPTED; + + lzopio->saved_off = 0; + + /* Get back to start block. */ + grub_file_seek (lzopio->file, lzopio->start_block_off); + + /* Read first block - grub_lzopio_read() expects valid block. */ + if (read_block_header (lzopio) < 0) + goto CORRUPTED; + + return 1; + } + +CORRUPTED: + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "lzop file corrupted"); + return 0; +} + +static grub_file_t +grub_lzopio_open (grub_file_t io) +{ + grub_file_t file; + grub_lzopio_t lzopio; + + file = (grub_file_t) grub_zalloc (sizeof (*file)); + if (!file) + return 0; + + lzopio = grub_zalloc (sizeof (*lzopio)); + if (!lzopio) + { + grub_free (file); + return 0; + } + + lzopio->file = io; + + file->device = io->device; + file->offset = 0; + file->data = lzopio; + file->read_hook = 0; + file->fs = &grub_lzopio_fs; + file->size = GRUB_FILE_SIZE_UNKNOWN; + file->not_easily_seekable = 1; + + if (grub_file_tell (lzopio->file) != 0) + grub_file_seek (lzopio->file, 0); + + if (!test_header (file)) + { + grub_errno = GRUB_ERR_NONE; + grub_file_seek (io, 0); + grub_free (lzopio); + grub_free (file); + + return io; + } + + return file; +} + +static grub_ssize_t +grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_lzopio_t lzopio = file->data; + grub_ssize_t ret = 0; + + /* Backward seek before last read block. */ + if (lzopio->saved_off > grub_file_tell (file)) + { + lzopio->saved_off = 0; + grub_file_seek (lzopio->file, lzopio->start_block_off); + + if (read_block_header (lzopio) < 0) + goto CORRUPTED; + } + + /* Forward to first block with requested data. */ + while (lzopio->saved_off + lzopio->block.usize <= grub_file_tell (file)) + { + /* EOF, could be possible files with unknown size. */ + if (lzopio->block.usize == 0) + return 0; + + if (jump_block (lzopio) < 0) + goto CORRUPTED; + } + + while (len != 0 && lzopio->block.usize != 0) + { + grub_off_t off = grub_file_tell (file) - lzopio->saved_off; + long to_copy; + + /* Block not decompressed yet. */ + if (!lzopio->block.udata && uncompress_block (lzopio) < 0) + goto CORRUPTED; + + /* Copy requested data into buffer. */ + to_copy = grub_min (lzopio->block.usize - off, len); + grub_memcpy (buf, lzopio->block.udata + off, to_copy); + + len -= to_copy; + buf += to_copy; + ret += to_copy; + + /* Read to next block if needed. */ + if (len > 0 && read_block_header (lzopio) < 0) + goto CORRUPTED; + } + + return ret; + +CORRUPTED: + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "lzop file corrupted"); + return -1; +} + +/* Release everything, including the underlying file object. */ +static grub_err_t +grub_lzopio_close (grub_file_t file) +{ + grub_lzopio_t lzopio = file->data; + + grub_file_close (lzopio->file); + grub_free (lzopio->block.cdata); + grub_free (lzopio->block.udata); + grub_free (lzopio); + + /* Device must not be closed twice. */ + file->device = 0; + return grub_errno; +} + +static struct grub_fs grub_lzopio_fs = { + .name = "lzopio", + .dir = 0, + .open = 0, + .read = grub_lzopio_read, + .close = grub_lzopio_close, + .label = 0, + .next = 0 +}; + +GRUB_MOD_INIT (lzopio) +{ + grub_file_filter_register (GRUB_FILE_FILTER_LZOPIO, grub_lzopio_open); +} + +GRUB_MOD_FINI (lzopio) +{ + grub_file_filter_unregister (GRUB_FILE_FILTER_LZOPIO); +} diff --git a/include/grub/file.h b/include/grub/file.h index 3adb1706f..8fe87e6b4 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -56,6 +56,7 @@ typedef enum grub_file_filter_id { GRUB_FILE_FILTER_GZIO, GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_LZOPIO, GRUB_FILE_FILTER_MAX, GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_XZIO, From 055e2b8b4f31be61160384d202c2f90422a723c2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 19 Aug 2011 17:24:18 +0200 Subject: [PATCH 1193/1414] * configure.ac: Fixed typo in --enable-cache-stats description. --- ChangeLog.cacheinfo | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.cacheinfo b/ChangeLog.cacheinfo index a26271cca..7e24e1083 100644 --- a/ChangeLog.cacheinfo +++ b/ChangeLog.cacheinfo @@ -1,3 +1,7 @@ +2011-08-19 Szymon Janc + + * configure.ac: Fixed typo in --enable-cache-stats description. + 2010-10-05 Szymon Janc Make enable of disk cache statistics code configurable. diff --git a/configure.ac b/configure.ac index 5f7846d41..224c9c9de 100644 --- a/configure.ac +++ b/configure.ac @@ -719,7 +719,7 @@ AC_ARG_ENABLE([mm-debug], AC_ARG_ENABLE([cache-stats], AS_HELP_STRING([--enable-cache-stats], - [enable disk cache statistics collection])]) + [enable disk cache statistics collection])) if test x$enable_cache_stats = xyes; then DISK_CACHE_STATS=1 From fb739ccd7923fb3d11d825d744faaf1cdf884d73 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 19 Aug 2011 20:06:42 +0200 Subject: [PATCH 1194/1414] * Makefile.am (AUTOMAKE_OPTIONS): = Added -Wno-portability flag. * grub-core/Makefile.am: Likewise. --- ChangeLog | 5 +++++ Makefile.am | 2 +- grub-core/Makefile.am | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 946dcbd80..17e2643b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-19 Szymon Janc + + * Makefile.am (AUTOMAKE_OPTIONS): = Added -Wno-portability flag. + * grub-core/Makefile.am: Likewise. + 2011-08-16 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_iterate): Skip with diff --git a/Makefile.am b/Makefile.am index 9301c91a5..c5f486e0d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = subdir-objects +AUTOMAKE_OPTIONS = subdir-objects -Wno-portability DEPDIR = .deps-util SUBDIRS = grub-core/gnulib . grub-core po docs util/bash-completion.d diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 3a085eb2c..f30014635 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = subdir-objects +AUTOMAKE_OPTIONS = subdir-objects -Wno-portability DEPDIR=.deps-core From 14a2562cf7e8bb2d6f8d13b297d8e3b07308d945 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 22:46:11 +0200 Subject: [PATCH 1195/1414] Rename Fuloong into Fuloong 2F. Add new ID for Fuloong2E. * grub-core/Makefile.core.def (fwstart_fuloong): Rename fwstart_fuloong into fwstart_fuloong2f. Use boot/mips/loongson/fuloong2f.S. * grub-core/boot/mips/loongson/fuloong.S: Rename to ... * grub-core/boot/mips/loongson/fuloong2f.S: ... this. (FULOONG): Rename to ... (FULOONG2F): ... this. All users updated. * grub-core/boot/mips/startup_raw.S (machtype_fuloong_str): Rename to (machtype_fuloong2f_str): ... this. (machtype_fuloong2e_str): New string. Check for machtype_fuloong2e_str. * grub-core/loader/mips/linux.c (loongson_machtypes) [GRUB_MACHINE_MIPS_LOONGSON]: Add GRUB_ARCH_MACHINE_FULOONG2E. * grub-core/term/serial.c (loongson_defserial) [GRUB_MACHINE_MIPS_LOONGSON]: New array. (grub_serial_register) [GRUB_MACHINE_MIPS_LOONGSON]: Use loongson_defserial. * include/grub/mips/loongson/kernel.h (GRUB_ARCH_MACHINE_FULOONG): Rename to ... (GRUB_ARCH_MACHINE_FULOONG2F): ... this. (GRUB_ARCH_MACHINE_FULOONG2E): New const. * util/grub-mkimage.c (image_target_desc): Rename IMAGE_FULOONG_FLASH to IMAGE_FULOONG2F_FLASH. All users updated. (image_targets): Rename images. * util/grub-mkstandalone.in: Accept fuloong2f and fuloong2e. --- ChangeLog | 29 +++++++++++++++++++ grub-core/Makefile.core.def | 4 +-- .../mips/loongson/{fuloong.S => fuloong2f.S} | 2 +- grub-core/boot/mips/loongson/fwstart.S | 26 ++++++++--------- grub-core/boot/mips/startup_raw.S | 14 +++++---- grub-core/bus/cs5536.c | 2 +- grub-core/kern/mips/loongson/init.c | 4 ++- grub-core/kern/mips/startup.S | 2 +- grub-core/loader/mips/linux.c | 3 +- grub-core/term/serial.c | 13 +++++++-- include/grub/mips/loongson/kernel.h | 3 +- util/grub-mkimage.c | 17 ++++++----- util/grub-mkstandalone.in | 2 +- 13 files changed, 82 insertions(+), 39 deletions(-) rename grub-core/boot/mips/loongson/{fuloong.S => fuloong2f.S} (51%) diff --git a/ChangeLog b/ChangeLog index 21975a2d3..fdc89b5a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2011-08-19 Vladimir Serbinenko + + Rename Fuloong into Fuloong 2F. Add new ID for Fuloong2E. + + * grub-core/Makefile.core.def (fwstart_fuloong): Rename fwstart_fuloong + into fwstart_fuloong2f. Use boot/mips/loongson/fuloong2f.S. + * grub-core/boot/mips/loongson/fuloong.S: Rename to ... + * grub-core/boot/mips/loongson/fuloong2f.S: ... this. + (FULOONG): Rename to ... + (FULOONG2F): ... this. All users updated. + * grub-core/boot/mips/startup_raw.S (machtype_fuloong_str): Rename to + (machtype_fuloong2f_str): ... this. + (machtype_fuloong2e_str): New string. + Check for machtype_fuloong2e_str. + * grub-core/loader/mips/linux.c (loongson_machtypes) + [GRUB_MACHINE_MIPS_LOONGSON]: Add GRUB_ARCH_MACHINE_FULOONG2E. + * grub-core/term/serial.c (loongson_defserial) + [GRUB_MACHINE_MIPS_LOONGSON]: New array. + (grub_serial_register) [GRUB_MACHINE_MIPS_LOONGSON]: Use + loongson_defserial. + * include/grub/mips/loongson/kernel.h (GRUB_ARCH_MACHINE_FULOONG): + Rename to ... + (GRUB_ARCH_MACHINE_FULOONG2F): ... this. + (GRUB_ARCH_MACHINE_FULOONG2E): New const. + * util/grub-mkimage.c (image_target_desc): Rename IMAGE_FULOONG_FLASH + to IMAGE_FULOONG2F_FLASH. All users updated. + (image_targets): Rename images. + * util/grub-mkstandalone.in: Accept fuloong2f and fuloong2e. + 2011-08-19 Szymon Janc Make enable of disk cache statistics code configurable. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index de57d2f0c..f129e98db 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -363,8 +363,8 @@ image = { }; image = { - name = fwstart_fuloong; - mips_loongson = boot/mips/loongson/fuloong.S; + name = fwstart_fuloong2f; + mips_loongson = boot/mips/loongson/fuloong2f.S; objcopyflags = '-O binary'; ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; enable = mips_loongson; diff --git a/grub-core/boot/mips/loongson/fuloong.S b/grub-core/boot/mips/loongson/fuloong2f.S similarity index 51% rename from grub-core/boot/mips/loongson/fuloong.S rename to grub-core/boot/mips/loongson/fuloong2f.S index 5df0d54c1..a88c81efe 100644 --- a/grub-core/boot/mips/loongson/fuloong.S +++ b/grub-core/boot/mips/loongson/fuloong2f.S @@ -1,2 +1,2 @@ -#define FULOONG 1 +#define FULOONG2F 1 #include "fwstart.S" diff --git a/grub-core/boot/mips/loongson/fwstart.S b/grub-core/boot/mips/loongson/fwstart.S index 38e87ad72..7ed5d30ae 100644 --- a/grub-core/boot/mips/loongson/fwstart.S +++ b/grub-core/boot/mips/loongson/fwstart.S @@ -26,7 +26,7 @@ #include #include -#ifdef FULOONG +#ifdef FULOONG2F #define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2 #define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 #else @@ -43,10 +43,10 @@ start: _start: __start: - /* Put serial init as soon as possible. But on Fuloong serial is past - Geode, so on Fuloong we need Geode first. + /* Put serial init as soon as possible. But on Fuloong2f serial is past + Geode, so on Fuloong2f we need Geode first. */ -#ifndef FULOONG +#ifndef FULOONG2F bal serial_hw_init nop #endif @@ -72,7 +72,7 @@ retry_cs5536: bnel $t2, $t3, 1b sll $t4, $t4, 1 -#ifndef FULOONG +#ifndef FULOONG2F bal message addiu $a0, $a0, %lo(cs5536_found) bal printhex @@ -95,7 +95,7 @@ retry_cs5536: bal gpio_init nop -#ifdef FULOONG +#ifdef FULOONG2F bal serial_hw_init nop #endif @@ -130,7 +130,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 and Fuloong have only one memory slot. */ + /* Yeeloong and Fuloong2f have only one memory slot. */ /* Output first byte on serial for debugging. */ ori $a1, $zero, GRUB_SMB_RAM_START_ADDR bal read_spd @@ -252,7 +252,7 @@ gpio_init: /* In: none. Out: none. Clobbered: $t0, $t1, $t2, $a0, $a1, $a2. */ serial_hw_init: move $t2, $ra -#ifdef FULOONG +#ifdef FULOONG2F lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_LEG_IO) addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_LEG_IO) lui $a1, %hi (GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 \ @@ -471,7 +471,7 @@ regdump: .quad 0x0100020200010101 /* 4 */ .quad 0x0a04030603050203 /* 6 */ .quad 0x0f0e040000010a0b /* 7 */ -#ifdef FULOONG +#ifdef FULOONG2F .quad 0x0000000100000001 /* 8 */ #else .quad 0x0000010200000102 /* 8 */ @@ -482,7 +482,7 @@ regdump: .quad 0x002a3c0615000000 /* c */ .quad 0x002a002a002a002a /* d */ .quad 0x002a002a002a002a /* e */ -#ifdef FULOONG +#ifdef FULOONG2F .quad 0x00b40020005b0004 /* f */ #else .quad 0x00b40020006d0004 /* f */ @@ -503,7 +503,7 @@ regdump: /* Dump of GPIO connections. FIXME: Remove useless and macroify. */ gpio_dump: -#ifdef FULOONG +#ifdef FULOONG2F .long 0xffff0000, 0x2eefd110, 0xffff0000, 0xffff0000 .long 0x2eefd110, 0xffff0000, 0x1000efff, 0xefff1000 .long 0x3df3c20c, 0xffff0000, 0xffff0000, 0xffff0000 @@ -740,8 +740,8 @@ 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) +#ifdef FULOONG2F + addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_FULOONG2F) #else addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_YEELOONG) #endif diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index 4ecff5efd..aefd387b6 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -109,7 +109,7 @@ argcont: 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) + DO_CHECKT1 (pmon_fuloong2f_verstr, GRUB_ARCH_MACHINE_FULOONG2F) 2: b argcont addiu $t0, $t0, 4 @@ -155,11 +155,12 @@ 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-" +machtype_fuloong2f_str: .asciiz "machtype=lemote-fuloong-2f" +machtype_fuloong2e_str: .asciiz "machtype=lemote-fuloong-2e" pmon_yeeloong_str: .asciiz "PMON_VER=LM8" -pmon_fuloong_str: .asciiz "PMON_VER=LM6" +pmon_fuloong2f_str: .asciiz "PMON_VER=LM6" pmon_yeeloong_verstr: .asciiz "Version=LM8" -pmon_fuloong_verstr: .asciiz "Version=LM6" +pmon_fuloong2f_verstr: .asciiz "Version=LM6" .p2align 2 argdone: @@ -173,8 +174,9 @@ argdone: 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) + DO_CHECKA1 (machtype_fuloong2f_str, GRUB_ARCH_MACHINE_FULOONG2F) + DO_CHECKA1 (machtype_fuloong2e_str, GRUB_ARCH_MACHINE_FULOONG2E) + DO_CHECKA1 (pmon_fuloong2f_str, GRUB_ARCH_MACHINE_FULOONG2F) addiu $a0, $a0, -1 b argdone addiu $a1, $a1, 4 diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index 58ffeb60a..1aae7852e 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -281,7 +281,7 @@ grub_cs5536_init_geode (grub_pci_device_t dev) | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); break; - case GRUB_ARCH_MACHINE_FULOONG: + case GRUB_ARCH_MACHINE_FULOONG2F: 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 diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index bcef391b9..0e4948beb 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -213,7 +213,9 @@ grub_halt (void) { switch (grub_arch_machine) { - case GRUB_ARCH_MACHINE_FULOONG: + case GRUB_ARCH_MACHINE_FULOONG2E: + break; + case GRUB_ARCH_MACHINE_FULOONG2F: { grub_pci_device_t dev; grub_port_t p; diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 6220a8c33..da6450237 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -61,7 +61,7 @@ VARIABLE (grub_arch_highmemsize) .long 0 #ifdef GRUB_MACHINE_MIPS_LOONGSON VARIABLE (grub_arch_machine) - .long GRUB_ARCH_MACHINE_FULOONG + .long GRUB_ARCH_MACHINE_FULOONG2F #endif cont: /* Save our base. */ diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 64c4a0531..2b4875983 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -41,7 +41,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); const char loongson_machtypes[][60] = { [GRUB_ARCH_MACHINE_YEELOONG] = "machtype=lemote-yeeloong-2f-8.9inches", - [GRUB_ARCH_MACHINE_FULOONG] = "machtype=lemote-fuloong-2f-unknown" + [GRUB_ARCH_MACHINE_FULOONG2F] = "machtype=lemote-fuloong-2f-unknown", + [GRUB_ARCH_MACHINE_FULOONG2E] = "machtype=lemote-fuloong-2e-unknown" }; #endif diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 0381349a4..b724a945a 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -239,6 +239,15 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) return GRUB_ERR_NONE; } +#ifdef GRUB_MACHINE_MIPS_LOONGSON +const char loongson_defserial[][6] = + { + [GRUB_ARCH_MACHINE_YEELOONG] = "com0", + [GRUB_ARCH_MACHINE_FULOONG2F] = "com2", + [GRUB_ARCH_MACHINE_FULOONG2E] = "com1" + }; +#endif + grub_err_t grub_serial_register (struct grub_serial_port *port) { @@ -301,9 +310,7 @@ grub_serial_register (struct grub_serial_port *port) port->term_out = out; grub_terminfo_output_register (out, "vt100"); #ifdef GRUB_MACHINE_MIPS_LOONGSON - if (grub_strcmp (port->name, - (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG) - ? "com0" : "com2") == 0) + if (grub_strcmp (port->name, loongson_defserial[grub_arch_machine]) == 0) { grub_term_register_input_active ("serial_*", in); grub_term_register_output_active ("serial_*", out); diff --git a/include/grub/mips/loongson/kernel.h b/include/grub/mips/loongson/kernel.h index 612221ed2..ba94e4331 100644 --- a/include/grub/mips/loongson/kernel.h +++ b/include/grub/mips/loongson/kernel.h @@ -23,7 +23,8 @@ #include #define GRUB_ARCH_MACHINE_YEELOONG 0 -#define GRUB_ARCH_MACHINE_FULOONG 1 +#define GRUB_ARCH_MACHINE_FULOONG2F 1 +#define GRUB_ARCH_MACHINE_FULOONG2E 2 #ifndef ASM_FILE diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index b05507242..420690923 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -67,7 +67,7 @@ struct image_target_desc IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, - IMAGE_FULOONG_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, + IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, IMAGE_QEMU_MIPS_FLASH } id; enum @@ -298,10 +298,10 @@ struct image_target_desc image_targets[] = }, { .dirname = "mipsel-loongson", - .names = { "mipsel-fuloong-flash", NULL }, + .names = { "mipsel-fuloong2f-flash", NULL }, .voidp_sizeof = 4, .bigendian = 0, - .id = IMAGE_FULOONG_FLASH, + .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, @@ -321,6 +321,7 @@ struct image_target_desc image_targets[] = { .dirname = "mipsel-loongson", .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf", + "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf", "mipsel-fuloong-elf", NULL }, .voidp_sizeof = 4, .bigendian = 0, @@ -1362,7 +1363,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } break; case IMAGE_YEELOONG_FLASH: - case IMAGE_FULOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: { char *rom_img; size_t rom_size; @@ -1381,7 +1382,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], 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] = + const grub_uint8_t fuloong2f_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, @@ -1393,10 +1394,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], }; const grub_uint8_t *fwstart_good_hash; - if (image_target->id == IMAGE_FULOONG_FLASH) + if (image_target->id == IMAGE_FULOONG2F_FLASH) { - fwstart_good_hash = fuloong_fwstart_good_hash; - boot_path = grub_util_get_path (dir, "fwstart_fuloong.img"); + fwstart_good_hash = fuloong2f_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart_fuloong2f.img"); } else { diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in index aaff99051..e140ecc82 100644 --- a/util/grub-mkstandalone.in +++ b/util/grub-mkstandalone.in @@ -136,7 +136,7 @@ if [ "x$source_directory" = x ] ; then cpu="`echo $format | awk -F - '{ print $1; }'`" platform="`echo $format | awk -F - '{ print $2; }'`" case "$platform" in - yeeloong | fuloong) + yeeloong | fuloong | fuloong2f | fuloong2e) platform=loongson ;; esac case "$cpu-$platform" in From 9594c6897ec93b27066244a71005f262dab91f82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 22:49:48 +0200 Subject: [PATCH 1196/1414] * configure.ac: Don't impose march=loongson2f on loongson platform. (It can still be specified in TARGET_CFLAGS) --- ChangeLog | 5 +++++ configure.ac | 17 ----------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index fdc89b5a2..c2f501c00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-19 Vladimir Serbinenko + + * configure.ac: Don't impose march=loongson2f on loongson platform. (It + can still be specified in TARGET_CFLAGS) + 2011-08-19 Vladimir Serbinenko Rename Fuloong into Fuloong 2F. Add new ID for Fuloong2E. diff --git a/configure.ac b/configure.ac index 224c9c9de..9cfbd2340 100644 --- a/configure.ac +++ b/configure.ac @@ -412,23 +412,6 @@ 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}" = mipsel-loongson; then - AC_CACHE_CHECK([whether -march=loongson2f works], [grub_cv_cc_march_loongson2f], [ - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -march=loongson2f" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_march_loongson2f=yes], - [grub_cv_cc_march_loongson2f=no]) - CFLAGS="$SAVE_CFLAGS" - ]) - - if test "x$grub_cv_cc_march_loongson2f" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -march=loongson2f" - else - TARGET_CFLAGS="$TARGET_CFLAGS -march=mips3" - fi -fi - grub_apple_target_cc if test x$grub_cv_apple_target_cc = xyes ; then TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1" From 1227c1339017349e6d011fe4bc927ff394141272 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 22:56:49 +0200 Subject: [PATCH 1197/1414] Fix PCI iterating on functions >= 4. * grub-core/bus/pci.c (grub_pci_iterate): Remove useless ghost skipping. * include/grub/mips/loongson/pci.h (GRUB_LOONGSON_OHCI_GHOST_FUNCTION): Removed. (GRUB_LOONGSON_EHCI_GHOST_FUNCTION): Likewise. (grub_pci_read): Fix bitmask. (grub_pci_read_word): Likewise. (grub_pci_read_byte): Likewise. (grub_pci_write): Likewise. (grub_pci_write_word): Likewise. (grub_pci_write_byte): Likewise. --- ChangeLog | 15 +++++++++++++++ grub-core/bus/pci.c | 10 ---------- include/grub/mips/loongson/pci.h | 14 ++++++-------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2f501c00..cfd46dad7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-08-19 Vladimir Serbinenko + + Fix PCI iterating on functions >= 4. + + * grub-core/bus/pci.c (grub_pci_iterate): Remove useless ghost skipping. + * include/grub/mips/loongson/pci.h (GRUB_LOONGSON_OHCI_GHOST_FUNCTION): + Removed. + (GRUB_LOONGSON_EHCI_GHOST_FUNCTION): Likewise. + (grub_pci_read): Fix bitmask. + (grub_pci_read_word): Likewise. + (grub_pci_read_byte): Likewise. + (grub_pci_write): Likewise. + (grub_pci_write_word): Likewise. + (grub_pci_write_byte): Likewise. + 2011-08-19 Vladimir Serbinenko * configure.ac: Don't impose march=loongson2f on loongson platform. (It diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index 51006a20e..f007ec33a 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -115,16 +115,6 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) continue; } -#ifdef GRUB_MACHINE_MIPS_LOONGSON - /* Skip ghosts. */ - if (id == GRUB_LOONGSON_OHCI_PCIID - && dev.function == GRUB_LOONGSON_OHCI_GHOST_FUNCTION) - continue; - if (id == GRUB_LOONGSON_EHCI_PCIID - && dev.function == GRUB_LOONGSON_EHCI_GHOST_FUNCTION) - continue; -#endif - if (hook (dev, id)) return; diff --git a/include/grub/mips/loongson/pci.h b/include/grub/mips/loongson/pci.h index 3f828c2f8..57c7dd1fc 100644 --- a/include/grub/mips/loongson/pci.h +++ b/include/grub/mips/loongson/pci.h @@ -26,8 +26,6 @@ #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 @@ -66,7 +64,7 @@ grub_pci_read (grub_pci_address_t addr) { GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x03ff)); + | (addr & 0x07ff)); } static inline grub_uint16_t @@ -74,7 +72,7 @@ grub_pci_read_word (grub_pci_address_t addr) { GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x03ff)); + | (addr & 0x07ff)); } static inline grub_uint8_t @@ -82,7 +80,7 @@ grub_pci_read_byte (grub_pci_address_t addr) { GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x03ff)); + | (addr & 0x07ff)); } static inline void @@ -90,7 +88,7 @@ grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) { GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x03ff)) = data; + | (addr & 0x07ff)) = data; } static inline void @@ -98,7 +96,7 @@ grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) { GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x03ff)) = data; + | (addr & 0x07ff)) = data; } static inline void @@ -106,7 +104,7 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) { GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0x03ff)) = data; + | (addr & 0x07ff)) = data; } volatile void * From 84beb0eeb95ef792fd1bab516324e62f0fb50b09 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 22:59:24 +0200 Subject: [PATCH 1198/1414] * grub-core/kern/misc.c (grub_vprintf): Fix a bug on malloc failure. --- ChangeLog | 4 ++++ grub-core/kern/misc.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index cfd46dad7..5e45756c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-19 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_vprintf): Fix a bug on malloc failure. + 2011-08-19 Vladimir Serbinenko Fix PCI iterating on functions >= 4. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index a3dfabf82..ebf80f100 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -210,6 +210,7 @@ grub_vprintf (const char *fmt, va_list args) buf[PREALLOC_SIZE - 2] = '.'; buf[PREALLOC_SIZE - 1] = '.'; buf[PREALLOC_SIZE] = 0; + curbuf = buf; } else s = grub_vsnprintf_real (curbuf, s, fmt, ap2); From 0d1fd0113ba001d6fd379274e34ff7c3782ee347 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 23:04:18 +0200 Subject: [PATCH 1199/1414] * include/grub/mips/loongson.h (GRUB_CPU_LOONGSON_COP0_PRID): New define. * grub-core/kern/mips/loongson/init.c (grub_machine_init): Check that PRID matches the detected subplatform and reset the subplatform if it doesn't. --- ChangeLog | 8 ++++++++ grub-core/kern/mips/loongson/init.c | 17 +++++++++++++++++ include/grub/mips/loongson.h | 1 + 3 files changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5e45756c8..23283d924 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-08-19 Vladimir Serbinenko + + * include/grub/mips/loongson.h (GRUB_CPU_LOONGSON_COP0_PRID): New + define. + * grub-core/kern/mips/loongson/init.c (grub_machine_init): Check + that PRID matches the detected subplatform and reset the subplatform + if it doesn't. + 2011-08-19 Vladimir Serbinenko * grub-core/kern/misc.c (grub_vprintf): Fix a bug on malloc failure. diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 0e4948beb..7df0ec876 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -123,6 +123,23 @@ void grub_machine_init (void) { grub_addr_t modend; + grub_uint32_t prid; + + asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_PRID : "=r" (prid)); + + switch (prid) + { + /* Loongson 2E. */ + case 0x6302: + grub_arch_machine = GRUB_ARCH_MACHINE_FULOONG2E; + break; + /* Loongson 2F. */ + case 0x6303: + if (grub_arch_machine != GRUB_ARCH_MACHINE_FULOONG2F + && grub_arch_machine != GRUB_ARCH_MACHINE_YEELOONG) + grub_arch_machine = GRUB_ARCH_MACHINE_YEELOONG; + break; + } /* FIXME: measure this. */ if (grub_arch_busclock == 0) diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h index ce5eb5e3d..e6f0241f2 100644 --- a/include/grub/mips/loongson.h +++ b/include/grub/mips/loongson.h @@ -66,6 +66,7 @@ #define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8) #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_PRID GRUB_CPU_REGISTER_WRAP($15) #define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO GRUB_CPU_REGISTER_WRAP($28) #define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI GRUB_CPU_REGISTER_WRAP($29) From d94497eacaac10d678f1d4919ac257ce7040c6d8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 23:08:36 +0200 Subject: [PATCH 1200/1414] * grub-core/Makefile.core.def (kernel): Add video/radeon_fuloong2e.c on loongson. * grub-core/kern/mips/loongson/init.c (grub_machine_init): Init video_radeon_fuloong2e. * grub-core/video/radeon_fuloong2e.c: New file. * include/grub/video.h (grub_video_id_t): Add new ID GRUB_VIDEO_DRIVER_RADEON_FULOONG2E. --- ChangeLog | 10 ++ grub-core/Makefile.core.def | 1 + grub-core/kern/mips/loongson/init.c | 2 + grub-core/video/radeon_fuloong2e.c | 231 ++++++++++++++++++++++++++++ include/grub/video.h | 1 + 5 files changed, 245 insertions(+) create mode 100644 grub-core/video/radeon_fuloong2e.c diff --git a/ChangeLog b/ChangeLog index 23283d924..2bff79544 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-08-19 Vladimir Serbinenko + + * grub-core/Makefile.core.def (kernel): Add video/radeon_fuloong2e.c on + loongson. + * grub-core/kern/mips/loongson/init.c (grub_machine_init): Init + video_radeon_fuloong2e. + * grub-core/video/radeon_fuloong2e.c: New file. + * include/grub/video.h (grub_video_id_t): Add new ID + GRUB_VIDEO_DRIVER_RADEON_FULOONG2E. + 2011-08-19 Vladimir Serbinenko * include/grub/mips/loongson.h (GRUB_CPU_LOONGSON_COP0_PRID): New diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index f129e98db..e95d87d37 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -180,6 +180,7 @@ kernel = { mips_loongson = term/serial.c; mips_loongson = video/sm712.c; mips_loongson = video/sis315pro.c; + mips_loongson = video/radeon_fuloong2e.c; extra_dist = video/sm712_init.c; mips_loongson = commands/keylayouts.c; diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 7df0ec876..5a95d29ed 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -35,6 +35,7 @@ extern void grub_video_sm712_init (void); extern void grub_video_sis315pro_init (void); +extern void grub_video_radeon_fuloong2e_init (void); extern void grub_video_init (void); extern void grub_bitmap_init (void); extern void grub_font_init (void); @@ -206,6 +207,7 @@ grub_machine_init (void) grub_video_init (); grub_video_sm712_init (); grub_video_sis315pro_init (); + grub_video_radeon_fuloong2e_init (); grub_bitmap_init (); grub_font_init (); grub_gfxterm_init (); diff --git a/grub-core/video/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c new file mode 100644 index 000000000..3a65b6720 --- /dev/null +++ b/grub-core/video/radeon_fuloong2e.c @@ -0,0 +1,231 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2010,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 . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_RADEON_FULOONG2E_TOTAL_MEMORY_SPACE 1048576 + +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; + +static grub_err_t +grub_video_radeon_fuloong2e_video_init (void) +{ + /* Reset frame buffer. */ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_radeon_fuloong2e_video_fini (void) +{ + if (framebuffer.mapped) + grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, + GRUB_RADEON_FULOONG2E_TOTAL_MEMORY_SPACE); + + return grub_video_fb_fini (); +} + +static grub_err_t +grub_video_radeon_fuloong2e_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 != 0x515a1002) + 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 != 480 && height != 0) + || (depth != 16 && depth != 0)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Only 1024x600x16 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 = 480; + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + framebuffer.mode_info.bpp = 16; + framebuffer.mode_info.bytes_per_pixel = 2; + framebuffer.mode_info.pitch = 640 * 2; + framebuffer.mode_info.number_of_colors = 256; + framebuffer.mode_info.red_mask_size = 5; + framebuffer.mode_info.red_field_pos = 11; + framebuffer.mode_info.green_mask_size = 6; + framebuffer.mode_info.green_field_pos = 5; + framebuffer.mode_info.blue_mask_size = 5; + 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_RADEON_FULOONG2E_TOTAL_MEMORY_SPACE); +#endif + framebuffer.mapped = 1; + + /* Prevent garbage from appearing on the screen. */ + grub_memset (framebuffer.ptr, 0x55, + framebuffer.mode_info.height * framebuffer.mode_info.pitch); + +#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; +} + +static grub_err_t +grub_video_radeon_fuloong2e_swap_buffers (void) +{ + /* TODO: Implement buffer swapping. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_radeon_fuloong2e_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_radeon_fuloong2e_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_radeon_fuloong2e_adapter = + { + .name = "RADEON RV100 QZ (Fuloong2E) Video Driver", + .id = GRUB_VIDEO_DRIVER_RADEON_FULOONG2E, + + .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, + + .init = grub_video_radeon_fuloong2e_video_init, + .fini = grub_video_radeon_fuloong2e_video_fini, + .setup = grub_video_radeon_fuloong2e_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_radeon_fuloong2e_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_radeon_fuloong2e_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_radeon_fuloong2e_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(video_radeon_fuloong2e) +{ + grub_video_register (&grub_video_radeon_fuloong2e_adapter); +} + +GRUB_MOD_FINI(video_radeon_fuloong2e) +{ + grub_video_unregister (&grub_video_radeon_fuloong2e_adapter); +} diff --git a/include/grub/video.h b/include/grub/video.h index e30589a3d..352544c85 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -282,6 +282,7 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_BOCHS, GRUB_VIDEO_DRIVER_SDL, GRUB_VIDEO_DRIVER_SIS315PRO, + GRUB_VIDEO_DRIVER_RADEON_FULOONG2E, } grub_video_driver_id_t; typedef enum grub_video_adapter_prio From f87abff5381b312299b37f3d2a1b9d121e8ff8ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 19 Aug 2011 23:11:09 +0200 Subject: [PATCH 1201/1414] * grub-core/kern/mips/loongson/init.c (grub_reboot): Reboot Fuloong. * include/grub/cs5536.h (GRUB_CS5536_MSR_DIVIL_RESET): New definition. --- ChangeLog | 5 +++++ grub-core/kern/mips/loongson/init.c | 23 +++++++++++++++++++++-- include/grub/cs5536.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2bff79544..d8ad1d634 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-19 Vladimir Serbinenko + + * grub-core/kern/mips/loongson/init.c (grub_reboot): Reboot Fuloong. + * include/grub/cs5536.h (GRUB_CS5536_MSR_DIVIL_RESET): New definition. + 2011-08-19 Vladimir Serbinenko * grub-core/Makefile.core.def (kernel): Add video/radeon_fuloong2e.c on diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 5a95d29ed..d1cac7a67 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -269,8 +269,27 @@ grub_exit (void) void grub_reboot (void) { - grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); - + switch (grub_arch_machine) + { + case GRUB_ARCH_MACHINE_FULOONG2E: + grub_outb (grub_inb (0xbfe00104) & ~4, 0xbfe00104); + grub_outb (grub_inb (0xbfe00104) | 4, 0xbfe00104); + break; + case GRUB_ARCH_MACHINE_FULOONG2F: + { + grub_pci_device_t dev; + if (!grub_cs5536_find (&dev)) + break; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET, + grub_cs5536_read_msr (dev, + GRUB_CS5536_MSR_DIVIL_RESET) + | 1); + break; + } + case GRUB_ARCH_MACHINE_YEELOONG: + grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); + break; + } grub_millisleep (1500); grub_printf ("Reboot failed\n"); diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h index 103b30633..fcacb23e8 100644 --- a/include/grub/cs5536.h +++ b/include/grub/cs5536.h @@ -77,6 +77,7 @@ #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_RESET 0x80000017 #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 4334690fbf512f5df2de965e8f5a89695734184e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 02:05:08 +0200 Subject: [PATCH 1202/1414] More work on LZO for btrfs support. Some fixes and code refactoring. --- ChangeLog.lzo | 11 +++ grub-core/fs/btrfs.c | 176 +++++++++++++++++++++---------------------- 2 files changed, 96 insertions(+), 91 deletions(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 782c6b60d..2ff940e21 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,14 @@ +2011-08-20 Szymon Janc + + More work on LZO for btrfs support. Some fixes and code refactoring. + + * grub-core/fs/btrfs.c (grub_btrfs_superblock): Removed sectorsize, + nodesize, leafsize, stripsize and dummy5 fields. + (grub_btrfs_lzo_decompress): New function. + (grub_btrfs_extent_read): Use grub_btrfs_lzo_decompress for LZO blocks + decompression. + (GRUB_BTRFS_LZO_BLOCK_SIZE): New define. + 2011-08-17 Szymon Janc Add initial support for lzop files decompression. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 1d24da3e3..7af735630 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -31,6 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_BTRFS_SIGNATURE "_BHRfS_M" +#define GRUB_BTRFS_LZO_BLOCK_SIZE 4096 typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; typedef grub_uint16_t grub_btrfs_uuid_t[8]; @@ -52,15 +53,10 @@ struct grub_btrfs_superblock grub_uint64_t chunk_tree; grub_uint8_t dummy2[0x20]; grub_uint64_t root_dir_objectid; - grub_uint8_t dummy3[0x8]; - grub_uint32_t sectorsize; - grub_uint32_t nodesize; - grub_uint32_t leafsize; - grub_uint32_t stripsize; - grub_uint8_t dummy4[0x29]; + grub_uint8_t dummy3[0x41]; struct grub_btrfs_device this_device; char label[0x100]; - grub_uint8_t dummy5[0x100]; + grub_uint8_t dummy4[0x100]; grub_uint8_t bootstrap_mapping[0x800]; } __attribute__ ((packed)); @@ -884,6 +880,77 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode)); } +static int +grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, + char *obuf, grub_size_t osize) +{ + grub_uint32_t total_size, cblock_size; + unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; + + total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (total_size); + + if (isize < total_size) + return -1; + + while (osize != 0) + { + lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE; + + cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (cblock_size); + + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_SIZE) + return -1; + + /* Jump forward to first block with requested data. */ + if (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; + ibuf += cblock_size; + continue; + } + + /* First block partially filled with requested data. */ + if (off > 0) + { + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, + NULL) != LZO_E_OK) + return -1; + + grub_memcpy(obuf, buf + off, usize - off); + + osize -= usize - off; + obuf += usize - off; + ibuf += cblock_size; + off = 0; + continue; + } + + /* 'Main' case, decompress whole block directly to output buffer. */ + if (osize >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, + (lzo_bytep)obuf, &usize, NULL) != LZO_E_OK) + return -1; + + osize -= usize; + obuf += usize; + ibuf += cblock_size; + } + else /* Last possible block partially filled with requested data. */ + { + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, + NULL) != LZO_E_OK) + return -1; + + grub_memcpy(obuf, buf, osize); + break; + } + } + return 0; +} + static grub_ssize_t grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_uint64_t ino, grub_uint64_t tree, @@ -990,39 +1057,11 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) { - grub_uint32_t total_size, chunk_size; - unsigned char *obuf; - unsigned char *ibuf = (unsigned char *) data->extent->inl; - lzo_uint ocnt = extoff + csize; - int ret; - - obuf = grub_malloc (extoff + csize); - if (!obuf) + if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) < 0) return -1; - - total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (total_size); - - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (chunk_size); - - /* Can we have multiple chunks in inline extent? */ - if (chunk_size + (sizeof (grub_uint32_t) * 2) != total_size) - { - grub_free (obuf); - return -1; - } - - ret = lzo1x_decompress_safe (ibuf, chunk_size, obuf, &ocnt, NULL); - - if (ret != LZO_E_OK) - { - grub_free (obuf); - return -1; - } - - grub_memcpy (buf, obuf + extoff, ocnt - extoff); - grub_free (obuf); } else grub_memcpy (buf, data->extent->inl + extoff, csize); @@ -1068,62 +1107,17 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) { - grub_uint32_t total_size, chunk_size, usize = 0; - grub_size_t off = extoff; - unsigned char *chunk, *ibuf = tmp; - char *obuf = buf; - /* XXX Is this correct size from sblock? */ - grub_uint32_t udata_size = grub_le_to_cpu32 (data->sblock.sectorsize); + int ret ; - chunk = grub_malloc (udata_size); - if (!chunk) - { - grub_free (tmp); - return -1; - } + ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); - /* XXX Use this for some sanity checks while decompressing. */ - total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (total_size); + grub_free(tmp); - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (chunk_size); + if (ret < 0) + return -1; - /* Jump to first chunk with requested data. */ - while (off >= udata_size) - { - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (chunk_size); - ibuf += chunk_size; - off -= udata_size; - } - - while (usize < csize) - { - chunk_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - lzo_uint csize2 = udata_size; - int diff; - - ibuf += sizeof (chunk_size); - - if (lzo1x_decompress_safe (ibuf, chunk_size, chunk, &csize2, NULL) != LZO_E_OK) - { - grub_free (tmp); - grub_free (chunk); - return -1; - } - - diff = grub_min (csize2 - off, csize - usize); - - grub_memcpy (obuf, chunk + off, diff); - obuf += diff; - ibuf += chunk_size; - usize += diff; - off = 0; - } - - grub_free (tmp); - grub_free (chunk); break; } } From a5219af18967bcca59478a4515b36c77caa814bd Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 11:48:46 +0200 Subject: [PATCH 1203/1414] * grub-core/io/gzio.c (grub_gzio_open): Always return original io if file type was not recognized correctly (not gzip or corrupted). --- ChangeLog | 5 +++++ grub-core/io/gzio.c | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8ad1d634..17e39bf15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-20 Szymon Janc + + * grub-core/io/gzio.c (grub_gzio_open): Always return original io if + file type was not recognized correctly (not gzip or corrupted). + 2011-08-19 Vladimir Serbinenko * grub-core/kern/mips/loongson/init.c (grub_reboot): Reboot Fuloong. diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 5d3e5332e..7380221aa 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -1179,12 +1179,9 @@ grub_gzio_open (grub_file_t io) grub_free (gzio); grub_free (file); grub_file_seek (io, 0); + grub_errno = GRUB_ERR_NONE; - if (grub_errno == GRUB_ERR_BAD_FILE_TYPE) - { - grub_errno = GRUB_ERR_NONE; - return io; - } + return io; } return file; From fe8d4a7bc207d44170a24534f13355230250dc5b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 11:58:41 +0200 Subject: [PATCH 1204/1414] * grub-core/loader/i386/linux.c (grub_linux_setup_video): Add GRUB_VIDEO_DRIVER_RADEON_FULOONG2E to switch case statement. --- ChangeLog | 5 +++++ grub-core/loader/i386/linux.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 17e39bf15..742a8cec2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-20 Szymon Janc + + * grub-core/loader/i386/linux.c (grub_linux_setup_video): Add + GRUB_VIDEO_DRIVER_RADEON_FULOONG2E to switch case statement. + 2011-08-20 Szymon Janc * grub-core/io/gzio.c (grub_gzio_open): Always return original io if diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 5356d7ace..fded7bb0a 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -374,6 +374,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) case GRUB_VIDEO_DRIVER_VGA: case GRUB_VIDEO_DRIVER_CIRRUS: case GRUB_VIDEO_DRIVER_BOCHS: + case GRUB_VIDEO_DRIVER_RADEON_FULOONG2E: /* Make gcc happy. */ case GRUB_VIDEO_DRIVER_SDL: case GRUB_VIDEO_DRIVER_NONE: From 7dc3c6863edb827234ec6045026dfc9f2ab9fffd Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 13:04:38 +0200 Subject: [PATCH 1205/1414] Add grub-fstest option to uncompress data for commands. * util/grub-fstest.c (uncompress): New var. (options): New option -u. --- ChangeLog | 7 +++++++ util/grub-fstest.c | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 742a8cec2..76526f4ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-08-20 Szymon Janc + + Add grub-fstest option to uncompress data for commands. + + * util/grub-fstest.c (uncompress): New var. + (options): New option -u. + 2011-08-20 Szymon Janc * grub-core/loader/i386/linux.c (grub_linux_setup_video): Add diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 972d462da..ad64701a2 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -68,6 +68,7 @@ enum { #define BUF_SIZE 32256 static grub_disk_addr_t skip, leng; +static int uncompress = 0; static void read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) @@ -111,7 +112,8 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) return; } - grub_file_filter_disable_compression (); + if (uncompress == 0) + grub_file_filter_disable_compression (); file = grub_file_open (pathname); if (!file) { @@ -409,6 +411,7 @@ static struct argp_option options[] = { {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, + {"uncompress", 'u', NULL, OPTION_ARG_OPTIONAL, N_("Uncompress data."), 2}, {0, 0, 0, 0, 0, 0} }; @@ -469,6 +472,10 @@ argp_parser (int key, char *arg, struct argp_state *state) verbosity++; return 0; + case 'u': + uncompress = 1; + return 0; + case ARGP_KEY_END: if (args_count < num_disks) { From 9a8d32a24fe7d0a1865be8ae83308cc001d1d091 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 18:24:54 +0200 Subject: [PATCH 1206/1414] Add support for adler32 checksuming. * grub-core/lib/adler32.c: New file. * Makefile.util.def (library): Add grub-core/lib/adler32.c to common. * util/import_gcry.py (cryptolist): Add adler32. --- ChangeLog.lzo | 8 ++ Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 ++ grub-core/lib/adler32.c | 152 ++++++++++++++++++++++++++++++++++++ util/import_gcry.py | 2 + 5 files changed, 168 insertions(+) create mode 100644 grub-core/lib/adler32.c diff --git a/ChangeLog.lzo b/ChangeLog.lzo index 2ff940e21..d24d913d8 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,11 @@ +2011-08-20 Szymon Janc + + Add support for adler32 checksuming. + + * grub-core/lib/adler32.c: New file. + * Makefile.util.def (library): Add grub-core/lib/adler32.c to common. + * util/import_gcry.py (cryptolist): Add adler32. + 2011-08-20 Szymon Janc More work on LZO for btrfs support. Some fixes and code refactoring. diff --git a/Makefile.util.def b/Makefile.util.def index 3628e48f6..365f718a1 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -91,6 +91,7 @@ library = { common = grub-core/lib/LzFind.c; common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/crc.c; + common = grub-core/lib/adler32.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; common = grub-core/partmap/acorn.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fc017b780..77dc7ed4b 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1687,3 +1687,8 @@ module = { common = commands/cacheinfo.c; condition = COND_ENABLE_CACHE_STATS; }; + +module = { + name = adler32; + common = lib/adler32.c; +}; diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c new file mode 100644 index 000000000..cc40735cb --- /dev/null +++ b/grub-core/lib/adler32.c @@ -0,0 +1,152 @@ +/* adler32.c - adler32 check. */ +/* + * 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 + +/* Based on adler32() from adler32.c of zlib-1.2.5 library. */ + +#define BASE 65521UL +#define NMAX 5552 + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +static grub_uint32_t +update_adler32 (grub_uint32_t adler, const grub_uint8_t *buf, grub_size_t len) +{ + unsigned long sum2; + unsigned int n; + + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + if (len == 1) + { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + if (len < 16) + { + while (len--) + { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + sum2 %= BASE; + return adler | (sum2 << 16); + } + + while (len >= NMAX) + { + len -= NMAX; + n = NMAX / 16; + do + { + DO16 (buf); + buf += 16; + } + while (--n); + adler %= BASE; + sum2 %= BASE; + } + + if (len) + { + while (len >= 16) + { + len -= 16; + DO16 (buf); + buf += 16; + } + while (len--) + { + adler += *buf++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; + } + + return adler | (sum2 << 16); +} + +typedef struct +{ + grub_uint32_t adler; + grub_uint8_t buf[4]; +} +adler32_context; + +static void +adler32_init (void *context) +{ + adler32_context *ctx = (adler32_context *) context; + ctx->adler = 1; +} + +static void +adler32_write (void *context, const void *inbuf, grub_size_t inlen) +{ + adler32_context *ctx = (adler32_context *) context; + if (!inbuf) + return; + ctx->adler = update_adler32 (ctx->adler, inbuf, inlen); +} + +static grub_uint8_t * +adler32_read (void *context) +{ + adler32_context *ctx = (adler32_context *) context; + return ctx->buf; +} + +static void +adler32_final (void *context __attribute__ ((unused))) +{ +} + +gcry_md_spec_t _gcry_digest_spec_adler32 = { + "ADLER32",0 , 0, 0 , 4, + adler32_init, adler32_write, adler32_final, adler32_read, + sizeof (adler32_context), + .blocksize = 64 +}; + +GRUB_MOD_INIT(adler32) +{ + grub_md_register (&_gcry_digest_spec_adler32); +} + +GRUB_MOD_FINI(adler32) +{ + grub_md_unregister (&_gcry_digest_spec_adler32); +} diff --git a/util/import_gcry.py b/util/import_gcry.py index 727492f10..ee75b1b8e 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -81,6 +81,8 @@ cryptolist.write ("AES-128: gcry_rijndael\n"); cryptolist.write ("AES-192: gcry_rijndael\n"); cryptolist.write ("AES-256: gcry_rijndael\n"); +cryptolist.write ("ADLER32: adler32\n"); + for cipher_file in cipher_files: infile = os.path.join (cipher_dir_in, cipher_file) outfile = os.path.join (cipher_dir_out, cipher_file) From ab178c084a251fe568430f250d9719979957ec53 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 20 Aug 2011 21:10:00 +0200 Subject: [PATCH 1207/1414] * acinclude.m4: Use AC_LANG_PROGRAM macro to generate source code for AC_LANG_CONFTEST macros. --- ChangeLog | 5 +++++ acinclude.m4 | 16 ++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76526f4ec..88b883028 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-21 Szymon Janc + + * acinclude.m4: Use AC_LANG_PROGRAM macro to generate source code for + AC_LANG_CONFTEST macros. + 2011-08-20 Szymon Janc Add grub-fstest option to uncompress data for commands. diff --git a/acinclude.m4 b/acinclude.m4 index 7c38155d4..5c623baee 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -316,14 +316,14 @@ fi dnl Check if the C compiler generates calls to `__enable_execute_stack()'. AC_DEFUN([grub_CHECK_ENABLE_EXECUTE_STACK],[ AC_MSG_CHECKING([whether `$CC' generates calls to `__enable_execute_stack()']) -AC_LANG_CONFTEST([[ +AC_LANG_CONFTEST([AC_LANG_SOURCE([[ void f (int (*p) (void)); void g (int i) { int nestedfunc (void) { return i; } f (nestedfunc); } -]]) +]])]) if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then true else @@ -346,7 +346,9 @@ AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[ ssp_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) # Is this a reliable test case? -AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]]) +AC_LANG_CONFTEST([AC_LANG_SOURCE([[ +void foo (void) { volatile char a[8]; a[3]; } +]])]) [# `$CC -c -o ...' might not be portable. But, oh, well... Is calling # `ac_compile' like this correct, after all? if eval "$ac_compile -S -fstack-protector -o conftest.s" 2> /dev/null; then] @@ -364,7 +366,9 @@ AC_DEFUN([grub_CHECK_STACK_ARG_PROBE],[ [# Smashing stack arg probe. sap_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-mstack-arg-probe']) -AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]]) +AC_LANG_CONFTEST([AC_LANG_SOURCE([[ +void foo (void) { volatile char a[8]; a[3]; } +]])]) [if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then] AC_MSG_RESULT([yes]) [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? @@ -399,7 +403,7 @@ AC_DEFUN([grub_CHECK_PIE],[ pie_possible=yes] AC_MSG_CHECKING([whether `$CC' has `-fPIE' as default]) # Is this a reliable test case? -AC_LANG_CONFTEST([[ +AC_LANG_CONFTEST([AC_LANG_SOURCE([[ #ifdef __PIE__ int main() { return 0; @@ -407,7 +411,7 @@ int main() { #else #error NO __PIE__ DEFINED #endif -]]) +]])]) [# `$CC -c -o ...' might not be portable. But, oh, well... Is calling # `ac_compile' like this correct, after all? From 6401c37058fd2ea0ddf187d6a8c2563471dc0252 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 21 Aug 2011 14:49:07 +0200 Subject: [PATCH 1208/1414] Return correct adler32 value in read() call. --- grub-core/lib/adler32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c index cc40735cb..6fb0b00f8 100644 --- a/grub-core/lib/adler32.c +++ b/grub-core/lib/adler32.c @@ -102,7 +102,6 @@ update_adler32 (grub_uint32_t adler, const grub_uint8_t *buf, grub_size_t len) typedef struct { grub_uint32_t adler; - grub_uint8_t buf[4]; } adler32_context; @@ -126,7 +125,7 @@ static grub_uint8_t * adler32_read (void *context) { adler32_context *ctx = (adler32_context *) context; - return ctx->buf; + return (grub_uint8_t *) &ctx->adler; } static void From 90b0a05579001a4474b69f65c98501bb8078a8c3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sun, 21 Aug 2011 18:48:19 +0200 Subject: [PATCH 1209/1414] Various bug fixes and improvements in lzopio. Should properly handle more files now. Also added support for lzop checksums verification. --- grub-core/io/lzopio.c | 174 +++++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 61 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index 4ccc41a16..f80d4beb9 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -22,17 +22,15 @@ #include #include #include - +#include #include "minilzo.h" GRUB_MOD_LICENSE ("GPLv3+"); #define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" #define LZOP_MAGIC_SIZE 9 -#define CHECK_SIZE 4 -#define NEW_LZO_LIB 0x0940 -#define MIN_HEADER_SIZE 0 -#define MAX_HEADER_SIZE 0 +#define LZOP_CHECK_SIZE 4 +#define LZOP_NEW_LIB 0x0940 /* Header flags - copied from conf.h of LZOP source code. */ #define F_ADLER32_D 0x00000001L @@ -64,8 +62,10 @@ struct block_header struct grub_lzopio { grub_file_t file; - int ucheck; /* XXX Use gcry to validate checks. */ - int ccheck; + int has_ccheck; + int has_ucheck; + const gcry_md_spec_t *ucheck_fun; + const gcry_md_spec_t *ccheck_fun; grub_off_t saved_off; /* Rounded down to block boundary. */ grub_off_t start_block_off; struct block_header block; @@ -74,15 +74,16 @@ struct grub_lzopio typedef struct grub_lzopio *grub_lzopio_t; static struct grub_fs grub_lzopio_fs; -/* Some helper functions. Memory allocated by those function is free either - * on next read_block_header() or on close() so no risk of leaks. This makes - * those function simpler. */ +/* Some helper functions. On errors memory allocated by those function is free + * either on close() so no risk of leaks. This makes functions simpler. */ /* Read block header from file, after successful exit file points to * beginning of block data. */ static int read_block_header (struct grub_lzopio *lzopio) { + lzopio->saved_off += lzopio->block.usize; + /* Free cached block data if any. */ grub_free (lzopio->block.udata); grub_free (lzopio->block.cdata); @@ -113,26 +114,40 @@ read_block_header (struct grub_lzopio *lzopio) lzopio->block.csize = grub_be_to_cpu32 (lzopio->block.csize); - /* XXX Handle incompressible data case here rather than in uncompress_block. - * This will allow to handle switch of ccheck/ucheck easier and also - * make uncompress_block() a bit simpler. */ + /* Corrupted. */ + if (lzopio->block.csize > lzopio->block.usize) + return -1; - /* Read data checks. */ - if (lzopio->ucheck) + /* Read checksum of uncompressed data. */ + if (lzopio->has_ucheck) { if (grub_file_read (lzopio->file, &lzopio->block.ucheck, sizeof (lzopio->block.ucheck)) != sizeof (lzopio->block.ucheck)) return -1; + + lzopio->block.ucheck = grub_be_to_cpu32 (lzopio->block.ucheck); } - if (lzopio->ccheck) + /* Read checksum of compressed data. */ + if (lzopio->has_ccheck) { - if (grub_file_read (lzopio->file, &lzopio->block.ccheck, - sizeof (lzopio->block.ccheck)) != - sizeof (lzopio->block.ccheck)) - return -1; + /* Incompressible data block. */ + if (lzopio->block.csize == lzopio->block.usize) + { + lzopio->block.ccheck = lzopio->block.ucheck; + } + else + { + if (grub_file_read (lzopio->file, &lzopio->block.ccheck, + sizeof (lzopio->block.ccheck)) != + sizeof (lzopio->block.ccheck)) + return -1; + + lzopio->block.ccheck = grub_be_to_cpu32 (lzopio->block.ccheck); + } } + return 0; } @@ -149,9 +164,19 @@ read_block_data (struct grub_lzopio *lzopio) != (grub_ssize_t) lzopio->block.csize) return -1; - if (lzopio->ccheck) + if (lzopio->ccheck_fun) { - /* XXX Validate data checksum here. */ + grub_uint8_t context[lzopio->ccheck_fun->contextsize]; + + lzopio->ccheck_fun->init (context); + lzopio->ccheck_fun->write (context, lzopio->block.cdata, + lzopio->block.csize); + lzopio->ccheck_fun->final (context); + + if (grub_memcmp + (lzopio->ccheck_fun->read (context), &lzopio->block.ccheck, + sizeof (lzopio->block.ccheck)) != 0) + return -1; } return 0; @@ -159,7 +184,7 @@ read_block_data (struct grub_lzopio *lzopio) /* Read block data, uncompressed and also store it in memory. */ /* XXX Investigate possibility of in-place decompression to reduce memory - * footprint. */ + * footprint. Or try to uncompress directly to buf if possible. */ static int uncompress_block (struct grub_lzopio *lzopio) { @@ -168,35 +193,41 @@ uncompress_block (struct grub_lzopio *lzopio) if (read_block_data (lzopio) < 0) return -1; - if (lzopio->block.usize > lzopio->block.csize) - { - lzopio->block.udata = grub_malloc (lzopio->block.usize); - if (!lzopio->block.udata) - return -1; - - if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, - lzopio->block.udata, &usize, - NULL) != LZO_E_OK) - return -1; - - if (lzopio->ucheck) - { - /* XXX Validate data checksum here. */ - } - - /* Compressed data can be free now. */ - grub_free (lzopio->block.cdata); - lzopio->block.cdata = NULL; - } - /* Incompressible block of data. */ - else if (lzopio->block.usize == lzopio->block.csize) + /* Incompressible data. */ + if (lzopio->block.csize == lzopio->block.usize) { lzopio->block.udata = lzopio->block.cdata; lzopio->block.cdata = NULL; } else { - return -1; + lzopio->block.udata = grub_malloc (lzopio->block.usize); + if (!lzopio->block.udata) + return -1; + + if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, + lzopio->block.udata, &usize, NULL) + != LZO_E_OK) + return -1; + + if (lzopio->ucheck_fun) + { + grub_uint8_t context[lzopio->ucheck_fun->contextsize]; + + lzopio->ucheck_fun->init (context); + lzopio->ucheck_fun->write (context, lzopio->block.udata, + lzopio->block.usize); + lzopio->ucheck_fun->final (context); + + if (grub_memcmp + (lzopio->ucheck_fun->read (context), &lzopio->block.ucheck, + sizeof (lzopio->block.ucheck)) != 0) + return -1; + } + + /* Compressed data can be free now. */ + grub_free (lzopio->block.cdata); + lzopio->block.cdata = NULL; } return 0; @@ -215,8 +246,6 @@ jump_block (struct grub_lzopio *lzopio) return -1; } - lzopio->saved_off += lzopio->block.usize; - return read_block_header (lzopio); } @@ -243,7 +272,7 @@ calculate_uncompressed_size (grub_file_t file) return 1; } -/* XXX Do something with this function, it is insane now:) */ +/* XXX Do something with this function... */ static int test_header (grub_file_t file) { @@ -253,6 +282,7 @@ test_header (grub_file_t file) grub_uint8_t method, level, name_len; grub_uint32_t flags, mode, filter, mtime_lo, mtime_hi, checksum; unsigned char *name = NULL; + const gcry_md_spec_t *hcheck; if (grub_file_read (lzopio->file, magic, sizeof (magic)) != sizeof (magic)) { @@ -277,7 +307,7 @@ test_header (grub_file_t file) ver = grub_be_to_cpu16 (ver); - if (ver >= NEW_LZO_LIB) + if (ver >= LZOP_NEW_LIB) { /* Read version of lib needed to extract data. */ if (grub_file_read (lzopio->file, &ver_ext, sizeof (ver_ext)) != @@ -297,7 +327,7 @@ test_header (grub_file_t file) sizeof (method)) goto CORRUPTED; - if (ver >= NEW_LZO_LIB) + if (ver >= LZOP_NEW_LIB) { if (grub_file_read (lzopio->file, &level, sizeof (level)) != sizeof (level)) @@ -310,14 +340,33 @@ test_header (grub_file_t file) flags = grub_be_to_cpu32 (flags); if (flags & F_CRC32_D) - lzopio->ucheck = 1; + { + lzopio->has_ucheck = 1; + lzopio->ucheck_fun = grub_crypto_lookup_md_by_name ("crc32"); + } else if (flags & F_ADLER32_D) - lzopio->ucheck = 2; + { + lzopio->has_ucheck = 1; + lzopio->ucheck_fun = grub_crypto_lookup_md_by_name ("adler32"); + } if (flags & F_CRC32_C) - lzopio->ccheck = 1; + { + lzopio->has_ccheck = 1; + lzopio->ccheck_fun = grub_crypto_lookup_md_by_name ("crc32"); + } else if (flags & F_ADLER32_C) - lzopio->ccheck = 2; + { + lzopio->has_ccheck = 1; + lzopio->ccheck_fun = grub_crypto_lookup_md_by_name ("adler32"); + } + + if (flags & F_H_CRC32) + hcheck = grub_crypto_lookup_md_by_name ("crc32"); + else + hcheck = grub_crypto_lookup_md_by_name ("adler32"); + + hcheck++; if (flags & F_H_FILTER) { @@ -333,7 +382,7 @@ test_header (grub_file_t file) sizeof (mtime_lo)) goto CORRUPTED; - if (ver >= NEW_LZO_LIB) + if (ver >= LZOP_NEW_LIB) { if (grub_file_read (lzopio->file, &mtime_hi, sizeof (mtime_hi)) != sizeof (mtime_hi)) @@ -374,8 +423,6 @@ test_header (grub_file_t file) if (calculate_uncompressed_size (file) < 0) goto CORRUPTED; - lzopio->saved_off = 0; - /* Get back to start block. */ grub_file_seek (lzopio->file, lzopio->start_block_off); @@ -383,6 +430,7 @@ test_header (grub_file_t file) if (read_block_header (lzopio) < 0) goto CORRUPTED; + lzopio->saved_off = 0; return 1; } @@ -439,15 +487,17 @@ grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) { grub_lzopio_t lzopio = file->data; grub_ssize_t ret = 0; + grub_off_t off; /* Backward seek before last read block. */ if (lzopio->saved_off > grub_file_tell (file)) { - lzopio->saved_off = 0; grub_file_seek (lzopio->file, lzopio->start_block_off); if (read_block_header (lzopio) < 0) goto CORRUPTED; + + lzopio->saved_off = 0; } /* Forward to first block with requested data. */ @@ -461,9 +511,10 @@ grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) goto CORRUPTED; } + off = grub_file_tell (file) - lzopio->saved_off; + while (len != 0 && lzopio->block.usize != 0) { - grub_off_t off = grub_file_tell (file) - lzopio->saved_off; long to_copy; /* Block not decompressed yet. */ @@ -477,8 +528,9 @@ grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) len -= to_copy; buf += to_copy; ret += to_copy; + off = 0; - /* Read to next block if needed. */ + /* Read next block if needed. */ if (len > 0 && read_block_header (lzopio) < 0) goto CORRUPTED; } From 1f0e4eed6bdd61b8653625bfb5646bb3d70365be Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 22 Aug 2011 09:18:22 +0200 Subject: [PATCH 1210/1414] * include/grub/file.h (grub_file_filter_id): Set GRUB_FILE_FILTER_LZOPIO as GRUB_FILE_FILTER_COMPRESSION_LAST. --- ChangeLog.lzo | 5 +++++ include/grub/file.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index d24d913d8..e3d08c6da 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,8 @@ +2011-08-22 Szymon Janc + + * include/grub/file.h (grub_file_filter_id): Set + GRUB_FILE_FILTER_LZOPIO as GRUB_FILE_FILTER_COMPRESSION_LAST. + 2011-08-20 Szymon Janc Add support for adler32 checksuming. diff --git a/include/grub/file.h b/include/grub/file.h index 8fe87e6b4..e08ac2e26 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -59,7 +59,7 @@ typedef enum grub_file_filter_id GRUB_FILE_FILTER_LZOPIO, GRUB_FILE_FILTER_MAX, GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, } grub_file_filter_id_t; typedef grub_file_t (*grub_file_filter_t) (grub_file_t in); From 4155e6974ad15f963eff5dfbe03cb36b48c7183b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Aug 2011 11:18:00 +0200 Subject: [PATCH 1211/1414] * util/grub-install.in: Move cryptodisk logic to appropriate place. --- ChangeLog | 4 ++++ util/grub-install.in | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88b883028..26af06ed3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-23 Vladimir Serbinenko + + * util/grub-install.in: Move cryptodisk logic to appropriate place. + 2011-08-21 Szymon Janc * acinclude.m4: Use AC_LANG_PROGRAM macro to generate source code for diff --git a/util/grub-install.in b/util/grub-install.in index f9e1510d1..d11d24421 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -558,11 +558,6 @@ if [ "x${devabstraction_module}" = "x" ] ; then exit 1 fi - if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then - for uuid in "`"${grub_probe}" --device "${device}" --target=cryptodisk_uuid`"; do - echo "cryptomount -u $uuid" - done - fi echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg" echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" @@ -577,6 +572,14 @@ if [ "x${devabstraction_module}" = "x" ] ; then fi fi else + if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then + for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do + echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg" + done + fi + + config_opt="-c ${grubdir}/load.cfg " + prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1 fi From ab80f326f47e2e83aaf35ac8b05e8b2c7e0966c8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Aug 2011 11:19:26 +0200 Subject: [PATCH 1212/1414] * grub-core/commands/wildcard.c (make_regex): Handle @. --- ChangeLog | 4 ++++ grub-core/commands/wildcard.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 26af06ed3..345f8f4cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-08-23 Vladimir Serbinenko + + * grub-core/commands/wildcard.c (make_regex): Handle @. + 2011-08-23 Vladimir Serbinenko * util/grub-install.in: Move cryptodisk logic to appropriate place. diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index d2f4347d5..256c07e51 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -139,6 +139,7 @@ make_regex (const char *start, const char *end, regex_t *regexp) case '.': case '(': case ')': + case '@': buffer[i++] = '\\'; buffer[i++] = ch; break; From ca51c4a04f4a67fe86bcdbddd899a28ae508f8a4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 23 Aug 2011 11:20:56 +0200 Subject: [PATCH 1213/1414] * grub-core/kern/mips/loongson/init.c (grub_machine_init): Handle the case of less than 256 MiB of RAM. --- ChangeLog | 5 +++++ grub-core/kern/mips/loongson/init.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 345f8f4cd..ad7dea7c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-23 Vladimir Serbinenko + + * grub-core/kern/mips/loongson/init.c (grub_machine_init): Handle the + case of less than 256 MiB of RAM. + 2011-08-23 Vladimir Serbinenko * grub-core/commands/wildcard.c (make_regex): Handle @. diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index d1cac7a67..2d1a0653e 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -188,7 +188,7 @@ grub_machine_init (void) } else { - grub_arch_memsize = (totalmem >> 20); + grub_arch_memsize = totalmem; grub_arch_highmemsize = 0; } From 00b98c9b2ef86d4cc4254dd163798388fc1f4d52 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 23 Aug 2011 19:49:01 +0200 Subject: [PATCH 1214/1414] * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Random fixes and some cleanup. --- grub-core/fs/btrfs.c | 120 ++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 64 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 7af735630..ae1ce1c7d 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -31,7 +31,17 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_BTRFS_SIGNATURE "_BHRfS_M" + +/* From http://www.oberhumer.com/opensource/lzo/lzofaq.php + * LZO will expand incompressible data by a little amount. I still haven't + * computed the exact values, but I suggest using these formulas for + * a worst-case expansion calculation: + * + * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + * */ #define GRUB_BTRFS_LZO_BLOCK_SIZE 4096 +#define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \ + (GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3) typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; typedef grub_uint16_t grub_btrfs_uuid_t[8]; @@ -880,11 +890,11 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode)); } -static int +static grub_ssize_t grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, char *obuf, grub_size_t osize) { - grub_uint32_t total_size, cblock_size; + grub_uint32_t total_size, cblock_size, uncompressed = 0; unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); @@ -893,62 +903,54 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, if (isize < total_size) return -1; - while (osize != 0) + /* Jump forward to first block with requested data. */ + while (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + { + cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); + ibuf += sizeof (cblock_size); + + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; + ibuf += cblock_size; + } + + while (osize > 0) { lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE; cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); ibuf += sizeof (cblock_size); - if (cblock_size > GRUB_BTRFS_LZO_BLOCK_SIZE) - return -1; - - /* Jump forward to first block with requested data. */ - if (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) + /* Block partially filled with requested data. */ + if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) { - off -= GRUB_BTRFS_LZO_BLOCK_SIZE; - ibuf += cblock_size; - continue; - } + grub_size_t to_copy = grub_min(osize, GRUB_BTRFS_LZO_BLOCK_SIZE - off); - /* First block partially filled with requested data. */ - if (off > 0) - { if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, NULL) != LZO_E_OK) return -1; - grub_memcpy(obuf, buf + off, usize - off); + grub_memcpy(obuf, buf + off, to_copy); - osize -= usize - off; - obuf += usize - off; + osize -= to_copy; + uncompressed += to_copy; + obuf += to_copy; ibuf += cblock_size; off = 0; continue; } /* 'Main' case, decompress whole block directly to output buffer. */ - if (osize >= GRUB_BTRFS_LZO_BLOCK_SIZE) - { - if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, - (lzo_bytep)obuf, &usize, NULL) != LZO_E_OK) - return -1; + if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf, + &usize, NULL) != LZO_E_OK) + return -1; - osize -= usize; - obuf += usize; - ibuf += cblock_size; - } - else /* Last possible block partially filled with requested data. */ - { - if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, - NULL) != LZO_E_OK) - return -1; - - grub_memcpy(obuf, buf, osize); - break; - } + osize -= usize; + uncompressed += usize; + obuf += usize; + ibuf += cblock_size; } - return 0; + + return uncompressed; } static grub_ssize_t @@ -1060,7 +1062,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize - ((grub_uint8_t *) data->extent->inl - (grub_uint8_t *) data->extent), - extoff, buf, csize) < 0) + extoff, buf, csize) + != (grub_ssize_t) csize) return -1; } else @@ -1075,8 +1078,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE) { - void *tmp; + char *tmp; grub_uint64_t zsize; + grub_ssize_t ret; + zsize = grub_le_to_cpu64 (data->extent->compressed_size); tmp = grub_malloc (zsize); if (!tmp) @@ -1091,36 +1096,23 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, } if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) - { - grub_ssize_t ret; - - ret = grub_zlib_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), - buf, csize); - - grub_free (tmp); - - if (ret != (grub_ssize_t) csize) - return -1; - - break; - } - else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) - { - int ret ; - - ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + ret = grub_zlib_decompress (tmp, zsize, extoff + grub_le_to_cpu64 (data->extent->offset), buf, csize); + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) + ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); + else + ret = -1; - grub_free(tmp); + grub_free(tmp); - if (ret < 0) - return -1; + if (ret != (grub_ssize_t) csize) + return -1; - break; - } - } + break; + } err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (data->extent->laddr) + grub_le_to_cpu64 (data->extent->offset) From ec543969bf07fbe60423ece81b29cd315116388b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 23 Aug 2011 19:53:49 +0200 Subject: [PATCH 1215/1414] * Makefile.util.def (libgrubmods.a): Add grub-core/io/lzopio.c to common. --- ChangeLog.lzo | 5 +++++ Makefile.util.def | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog.lzo b/ChangeLog.lzo index e3d08c6da..ef6145061 100644 --- a/ChangeLog.lzo +++ b/ChangeLog.lzo @@ -1,3 +1,8 @@ +2011-08-23 Szymon Janc + + * Makefile.util.def (libgrubmods.a): Add grub-core/io/lzopio.c to + common. + 2011-08-22 Szymon Janc * include/grub/file.h (grub_file_filter_id): Set diff --git a/Makefile.util.def b/Makefile.util.def index 365f718a1..1fe4f2464 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -109,6 +109,7 @@ library = { common = grub-core/script/script.c; common = grub-core/script/argv.c; common = grub-core/io/gzio.c; + common = grub-core/io/lzopio.c; common = grub-core/kern/ia64/dl_helper.c; common = grub-core/lib/minilzo/minilzo.c; }; From 579c12fbb4b757fc26cb6fcbe265250f734eaf68 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 24 Aug 2011 11:24:10 +0200 Subject: [PATCH 1216/1414] * grub-core/fs/btrfs.c: Some minor cleanups. --- grub-core/fs/btrfs.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index ae1ce1c7d..534ce15de 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -894,7 +894,7 @@ static grub_ssize_t grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, char *obuf, grub_size_t osize) { - grub_uint32_t total_size, cblock_size, uncompressed = 0; + grub_uint32_t total_size, cblock_size, ret = 0; unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE]; total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); @@ -909,6 +909,9 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); ibuf += sizeof (cblock_size); + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) + return -1; + off -= GRUB_BTRFS_LZO_BLOCK_SIZE; ibuf += cblock_size; } @@ -920,6 +923,9 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); ibuf += sizeof (cblock_size); + if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) + return -1; + /* Block partially filled with requested data. */ if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) { @@ -929,28 +935,29 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, NULL) != LZO_E_OK) return -1; + to_copy = grub_min(to_copy, usize); grub_memcpy(obuf, buf + off, to_copy); osize -= to_copy; - uncompressed += to_copy; + ret += to_copy; obuf += to_copy; ibuf += cblock_size; off = 0; continue; } - /* 'Main' case, decompress whole block directly to output buffer. */ + /* Decompress whole block directly to output buffer. */ if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf, &usize, NULL) != LZO_E_OK) return -1; osize -= usize; - uncompressed += usize; + ret += usize; obuf += usize; ibuf += cblock_size; } - return uncompressed; + return ret; } static grub_ssize_t From 2221ab6c62fdd6473f1ae4f147739b585fde8e1b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 5 Sep 2011 13:58:33 +0100 Subject: [PATCH 1217/1414] * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Return 1 for */README* as well as README*. Reported by: Axel Beckert. --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ad7dea7c8..c84aa30aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-09-05 Colin Watson + + * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Return 1 for + */README* as well as README*. + Reported by: Axel Beckert. + 2011-08-23 Vladimir Serbinenko * grub-core/kern/mips/loongson/init.c (grub_machine_init): Handle the diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 901b5752f..a453a6bb5 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -157,7 +157,7 @@ grub_file_is_not_garbage () if test -f "$1" ; then case "$1" in *.dpkg-*) return 1 ;; # debian dpkg - README*) return 1 ;; # documentation + README*|*/README*) return 1 ;; # documentation esac else return 1 From 9c4f9ca010ddf432c7c83cdabaf36c7a4b956cd6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 6 Sep 2011 21:21:13 +0200 Subject: [PATCH 1218/1414] * grub-core/io/lzopio.c (test_header): Some cleanups. --- grub-core/io/lzopio.c | 177 +++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 96 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index f80d4beb9..e303b29a3 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -272,72 +272,60 @@ calculate_uncompressed_size (grub_file_t file) return 1; } -/* XXX Do something with this function... */ +struct lzop_header +{ + grub_uint8_t magic[LZOP_MAGIC_SIZE]; + grub_uint16_t lzop_version; + grub_uint16_t lib_version; + grub_uint16_t lib_version_ext; + grub_uint8_t method; + grub_uint8_t level; + grub_uint32_t flags; + /* grub_uint32_t filter; */ /* No filters support. Rarely used anyway. */ + grub_uint32_t mode; + grub_uint32_t mtime_lo; + grub_uint32_t mtime_hi; + grub_uint8_t name_len; +} __attribute__ ((packed)); + static int test_header (grub_file_t file) { grub_lzopio_t lzopio = file->data; - unsigned char magic[LZOP_MAGIC_SIZE]; - grub_uint16_t lzopver, ver, ver_ext; - grub_uint8_t method, level, name_len; - grub_uint32_t flags, mode, filter, mtime_lo, mtime_hi, checksum; - unsigned char *name = NULL; + struct lzop_header header; + grub_uint32_t flags, checksum; const gcry_md_spec_t *hcheck; + grub_uint8_t *context = NULL; + grub_uint8_t *name = NULL; - if (grub_file_read (lzopio->file, magic, sizeof (magic)) != sizeof (magic)) + if (grub_file_read (lzopio->file, &header, sizeof (header)) != sizeof (header)) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); return 0; } - if (grub_memcmp (magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) + if (grub_memcmp (header.magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) { grub_error (GRUB_ERR_BAD_FILE_TYPE, "no lzop magic found"); return 0; } - /* LZOP version. */ - if (grub_file_read (lzopio->file, &lzopver, sizeof (lzopver)) != - sizeof (lzopver)) - goto CORRUPTED; - - /* LZO lib version. */ - if (grub_file_read (lzopio->file, &ver, sizeof (ver)) != sizeof (ver)) - goto CORRUPTED; - - ver = grub_be_to_cpu16 (ver); - - if (ver >= LZOP_NEW_LIB) + if (grub_be_to_cpu16(header.lib_version) < LZOP_NEW_LIB) { - /* Read version of lib needed to extract data. */ - if (grub_file_read (lzopio->file, &ver_ext, sizeof (ver_ext)) != - sizeof (ver_ext)) - goto CORRUPTED; - - /* Too new version, should upgrade minilzo? */ - if (grub_be_to_cpu16 (ver_ext) > MINILZO_VERSION) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "unsupported LZO version"); - return 0; - } + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "unsupported (too old) LZOP version"); + return 0; } - if (grub_file_read (lzopio->file, &method, sizeof (method)) != - sizeof (method)) - goto CORRUPTED; - - if (ver >= LZOP_NEW_LIB) + /* Too new version, should upgrade minilzo? */ + if (grub_be_to_cpu16 (header.lib_version_ext) > MINILZO_VERSION) { - if (grub_file_read (lzopio->file, &level, sizeof (level)) != - sizeof (level)) - goto CORRUPTED; + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "unsupported (too new) LZO version"); + return 0; } - if (grub_file_read (lzopio->file, &flags, sizeof (flags)) != sizeof (flags)) - goto CORRUPTED; - - flags = grub_be_to_cpu32 (flags); + flags = grub_be_to_cpu32 (header.flags); if (flags & F_CRC32_D) { @@ -366,76 +354,73 @@ test_header (grub_file_t file) else hcheck = grub_crypto_lookup_md_by_name ("adler32"); - hcheck++; + if (hcheck) { + context = grub_malloc(hcheck->contextsize); + if (! context) + return 0; - if (flags & F_H_FILTER) + hcheck->init(context); + + /* MAGIC is not included in check calculation. */ + hcheck->write(context, &header.lzop_version, sizeof(header)- LZOP_MAGIC_SIZE); + } + + if (header.name_len != 0) { - if (grub_file_read (lzopio->file, &filter, sizeof (filter)) != - sizeof (filter)) - goto CORRUPTED; - } - - if (grub_file_read (lzopio->file, &mode, sizeof (mode)) != sizeof (mode)) - goto CORRUPTED; - - if (grub_file_read (lzopio->file, &mtime_lo, sizeof (mtime_lo)) != - sizeof (mtime_lo)) - goto CORRUPTED; - - if (ver >= LZOP_NEW_LIB) - { - if (grub_file_read (lzopio->file, &mtime_hi, sizeof (mtime_hi)) != - sizeof (mtime_hi)) - goto CORRUPTED; - } - - if (grub_file_read (lzopio->file, &name_len, sizeof (name_len)) != - sizeof (name_len)) - goto CORRUPTED; - - if (name_len != 0) - { - name = grub_malloc (name_len); - if (!name) - return 0; - - if (grub_file_read (lzopio->file, name, name_len) != name_len) + name = grub_malloc (header.name_len); + if (! name) { - grub_free (name); + grub_free (context); + return 0; + } + + if (grub_file_read (lzopio->file, name, header.name_len) != + header.name_len) + { + grub_free(name); goto CORRUPTED; } + + if (hcheck) + hcheck->write(context, name, header.name_len); + + grub_free(name); } + if (hcheck) + hcheck->final(context); + if (grub_file_read (lzopio->file, &checksum, sizeof (checksum)) != sizeof (checksum)) - { - grub_free (name); + goto CORRUPTED; + + if (hcheck) + { + checksum = grub_cpu_to_be32(checksum); + if (memcmp(&checksum, hcheck->read(context), sizeof(checksum)) != 0) goto CORRUPTED; - } + } - grub_free (name); + lzopio->start_block_off = grub_file_tell (lzopio->file); - /* XXX Validate header checksum here. */ - if (checksum == checksum) - { - lzopio->start_block_off = grub_file_tell (lzopio->file); + if (calculate_uncompressed_size (file) < 0) + goto CORRUPTED; - if (calculate_uncompressed_size (file) < 0) - goto CORRUPTED; + /* Get back to start block. */ + grub_file_seek (lzopio->file, lzopio->start_block_off); - /* Get back to start block. */ - grub_file_seek (lzopio->file, lzopio->start_block_off); + /* Read first block - grub_lzopio_read() expects valid block. */ + if (read_block_header (lzopio) < 0) + goto CORRUPTED; - /* Read first block - grub_lzopio_read() expects valid block. */ - if (read_block_header (lzopio) < 0) - goto CORRUPTED; - - lzopio->saved_off = 0; - return 1; - } + lzopio->saved_off = 0; + return 1; CORRUPTED: grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "lzop file corrupted"); + + grub_free(name); + return 0; } From 1a7d7db97f34d0c38dd64655ef944b4cf0768ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 17 Sep 2011 23:01:48 +0200 Subject: [PATCH 1219/1414] Get sector size from disk label for NetBSD. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c84aa30aa..1acdce29e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-09-17 GrĂ©goire Sutre + + * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__NetBSD__]: + Get sector size from disk label. + 2011-09-05 Colin Watson * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Return 1 for diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 000ef2f79..b4c4eef7c 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -265,10 +265,13 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (ioctl (fd, DIOCGSECTORSIZE, §or_size)) + goto fail; +# elif defined(__NetBSD__) + sector_size = label.d_secsize; # else if (ioctl (fd, BLKSSZGET, §or_size)) -# endif goto fail; +# endif if (sector_size & (sector_size - 1) || !sector_size) goto fail; From 20fd15f9db1e5379d264e29f0f28e0b96391bf95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 17 Sep 2011 23:40:10 +0200 Subject: [PATCH 1220/1414] Add LIBUTIL for grub-mkrelpath and grub-fstest. Fixes build on NetBSD. --- ChangeLog | 6 ++++++ Makefile.util.def | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1acdce29e..a454f2f84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-09-17 GrĂ©goire Sutre + + * Makefile.util.def (grub-mkrelpath): Add LIBUTIL for getrawpartition(3) + on NetBSD. + * Makefile.util.def (grub-fstest): Likewise. + 2011-09-17 GrĂ©goire Sutre * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__NetBSD__]: diff --git a/Makefile.util.def b/Makefile.util.def index d86cb9761..713729c55 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -147,7 +147,7 @@ program = { ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { @@ -226,7 +226,7 @@ program = { ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { From 69915030942771f6813ebc238e86e05b5112f3b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 28 Sep 2011 14:07:53 +0200 Subject: [PATCH 1221/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Return 0 if disk isn't biosdisk. --- ChangeLog | 5 +++++ grub-core/kern/emu/hostdisk.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index a454f2f84..9d19fe450 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-09-28 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): + Return 0 if disk isn't biosdisk. + 2011-09-17 GrĂ©goire Sutre * Makefile.util.def (grub-mkrelpath): Add LIBUTIL for getrawpartition(3) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index b4c4eef7c..a9a8c066e 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1841,6 +1841,9 @@ grub_util_biosdisk_is_floppy (grub_disk_t disk) struct stat st; int fd; + if (disk->dev != &grub_util_biosdisk_dev) + return 0; + fd = open (map[disk->id].device, O_RDONLY); /* Shouldn't happen. */ if (fd == -1) From 2ded951ef70998ebebabd7b73d1a6bf0006a93d7 Mon Sep 17 00:00:00 2001 From: Andreas Born Date: Wed, 28 Sep 2011 14:19:21 +0200 Subject: [PATCH 1222/1414] Fix incorrect identifiers in bash-completion. * util/bash-completion.d/grub-completion.bash.in (_grub_mkpasswd-pbkdf2): Rename to ... (_grub_mkpasswd_pbkdf2): ... this. All users updated. (_grub_script-check): Rename to ... (_grub_script_check): ... this. All users updated. --- ChangeLog | 10 ++++++++++ util/bash-completion.d/grub-completion.bash.in | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d19fe450..5cc753c11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-09-28 Andreas Born + + Fix incorrect identifiers in bash-completion. + + * util/bash-completion.d/grub-completion.bash.in + (_grub_mkpasswd-pbkdf2): Rename to ... + (_grub_mkpasswd_pbkdf2): ... this. All users updated. + (_grub_script-check): Rename to ... + (_grub_script_check): ... this. All users updated. + 2011-09-28 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in index 65cbb80ee..64d49fe0b 100644 --- a/util/bash-completion.d/grub-completion.bash.in +++ b/util/bash-completion.d/grub-completion.bash.in @@ -402,7 +402,7 @@ unset __grub_mkimage_program # # grub-mkpasswd-pbkdf2 # -_grub_mkpasswd-pbkdf2 () { +_grub_mkpasswd_pbkdf2 () { local cur COMPREPLY=() @@ -417,7 +417,7 @@ _grub_mkpasswd-pbkdf2 () { } __grub_mkpasswd_pbkdf2_program=$( echo grub-mkpasswd-pbkdf2 | sed "@program_transform_name@" ) have ${__grub_mkpasswd_pbkdf2_program} && \ - complete -F _grub_mkpasswd-pbkdf2 -o filenames ${__grub_mkpasswd_pbkdf2_program} + complete -F _grub_mkpasswd_pbkdf2 -o filenames ${__grub_mkpasswd_pbkdf2_program} unset __grub_mkpasswd_pbkdf2_program @@ -462,7 +462,7 @@ unset __grub_probe_program # # grub-script-check # -_grub_script-check () { +_grub_script_check () { local cur COMPREPLY=() @@ -477,7 +477,7 @@ _grub_script-check () { } __grub_script_check_program=$( echo grub-script-check | sed "@program_transform_name@" ) have ${__grub_script_check_program} && \ - complete -F _grub_script-check -o filenames ${__grub_script_check_program} + complete -F _grub_script_check -o filenames ${__grub_script_check_program} # Local variables: From 91a1a164d66dfdeb4d36ac5bc4f39f62e4aee58f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 28 Sep 2011 16:43:00 +0200 Subject: [PATCH 1223/1414] * grub-core/loader/multiboot_elfxx.c (Elf_Shdr): Set according to loader. --- ChangeLog | 5 +++++ grub-core/loader/multiboot_elfxx.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5cc753c11..d415a4bcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-09-28 Thomas Haller + + * grub-core/loader/multiboot_elfxx.c (Elf_Shdr): Set according to + loader. + 2011-09-28 Andreas Born Fix incorrect identifiers in bash-completion. diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c index 0c29fe9c2..c6c88f177 100644 --- a/grub-core/loader/multiboot_elfxx.c +++ b/grub-core/loader/multiboot_elfxx.c @@ -22,12 +22,14 @@ # define ELFCLASSXX ELFCLASS32 # define Elf_Ehdr Elf32_Ehdr # define Elf_Phdr Elf32_Phdr +# define Elf_Shdr Elf32_Shdr #elif defined(MULTIBOOT_LOAD_ELF64) # define XX 64 # define E_MACHINE MULTIBOOT_ELF64_MACHINE # define ELFCLASSXX ELFCLASS64 # define Elf_Ehdr Elf64_Ehdr # define Elf_Phdr Elf64_Phdr +# define Elf_Shdr Elf64_Shdr #else #error "I'm confused" #endif @@ -223,3 +225,4 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) #undef ELFCLASSXX #undef Elf_Ehdr #undef Elf_Phdr +#undef Elf_Shdr From e0b0dc837b9717842584623126577c74c2dd65d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 28 Sep 2011 23:45:57 +0200 Subject: [PATCH 1224/1414] Make knetbsd pass bootinfo bootdisk and bootwedge. --- ChangeLog | 12 +++++ grub-core/loader/i386/bsd.c | 84 +++++++++++++++++++++++++++++ include/grub/bsdlabel.h | 5 +- include/grub/i386/netbsd_bootinfo.h | 11 ++++ 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d415a4bcd..8cdd158cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-09-28 GrĂ©goire Sutre + + * include/grub/bsdlabel.h (grub_partition_bsd_disk_label): Add fields + type and packname. + * include/grub/i386/netbsd_bootinfo.h (NETBSD_BTINFO_BOOTDISK): + Resurrected. + (NETBSD_BTINFO_BOOTWEDGE): New definition. + (grub_netbsd_btinfo_bootwedge): New struct. + * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): + New function. + (grub_cmd_netbsd): Call grub_netbsd_add_boot_disk_and_wedge. + 2011-09-28 Thomas Haller * grub-core/loader/multiboot_elfxx.c (Elf_Shdr): Set according to diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index dffe48257..18ebeb760 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -946,6 +948,86 @@ grub_netbsd_add_modules (void) return err; } +/* + * Adds NetBSD bootinfo bootdisk and bootwedge. The partition identified + * in these bootinfo fields is the root device. + */ +static void +grub_netbsd_add_boot_disk_and_wedge (void) +{ + grub_device_t dev; + grub_disk_t disk; + grub_partition_t part; + grub_uint32_t biosdev; + grub_uint32_t partmapsector; + struct grub_partition_bsd_disk_label *label; + grub_uint64_t buf[GRUB_DISK_SECTOR_SIZE / 8]; + grub_uint8_t *hash; + grub_uint64_t ctx[(GRUB_MD_MD5->contextsize + 7) / 8]; + + dev = grub_device_open (0); + if (! (dev && dev->disk && dev->disk->partition)) + goto fail; + + disk = dev->disk; + part = disk->partition; + + if (disk->dev && disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID) + biosdev = (grub_uint32_t) disk->id & 0xff; + else + biosdev = 0xff; + + /* Absolute sector of the partition map describing this partition. */ + partmapsector = grub_partition_get_start (part->parent) + part->offset; + + disk->partition = part->parent; + if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf) != GRUB_ERR_NONE) + goto fail; + disk->partition = part; + + /* Fill bootwedge. */ + { + struct grub_netbsd_btinfo_bootwedge biw; + + grub_memset (&biw, 0, sizeof (biw)); + biw.biosdev = biosdev; + biw.startblk = grub_partition_get_start (part); + biw.nblks = part->len; + biw.matchblk = partmapsector; + biw.matchnblks = 1; + + GRUB_MD_MD5->init (&ctx); + GRUB_MD_MD5->write (&ctx, buf, GRUB_DISK_SECTOR_SIZE); + GRUB_MD_MD5->final (&ctx); + hash = GRUB_MD_MD5->read (&ctx); + memcpy (biw.matchhash, hash, 16); + + grub_bsd_add_meta (NETBSD_BTINFO_BOOTWEDGE, &biw, sizeof (biw)); + } + + /* Fill bootdisk if this a NetBSD disk label. */ + label = (struct grub_partition_bsd_disk_label *) &buf; + if (part->partmap != NULL && + (grub_strcmp (part->partmap->name, "netbsd") == 0) && + label->magic == grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) + { + struct grub_netbsd_btinfo_bootdisk bid; + + grub_memset (&bid, 0, sizeof (bid)); + bid.labelsector = partmapsector; + bid.label.type = label->type; + bid.label.checksum = label->checksum; + memcpy (bid.label.packname, label->packname, 16); + bid.biosdev = biosdev; + bid.partition = part->number; + grub_bsd_add_meta (NETBSD_BTINFO_BOOTDISK, &bid, sizeof (bid)); + } + +fail: + if (dev) + grub_device_close (dev); +} + static grub_err_t grub_netbsd_boot (void) { @@ -1607,6 +1689,8 @@ grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &cons, sizeof (cons)); } + grub_netbsd_add_boot_disk_and_wedge (); + grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0); } diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h index 636bd41a1..b10336c01 100644 --- a/include/grub/bsdlabel.h +++ b/include/grub/bsdlabel.h @@ -80,7 +80,10 @@ struct grub_partition_bsd_entry struct grub_partition_bsd_disk_label { grub_uint32_t magic; - grub_uint8_t padding[128]; + grub_uint16_t type; + grub_uint8_t unused1[18]; + grub_uint8_t packname[16]; + grub_uint8_t unused2[92]; grub_uint32_t magic2; grub_uint16_t checksum; grub_uint16_t num_partitions; diff --git a/include/grub/i386/netbsd_bootinfo.h b/include/grub/i386/netbsd_bootinfo.h index fd429a251..228f26aaa 100644 --- a/include/grub/i386/netbsd_bootinfo.h +++ b/include/grub/i386/netbsd_bootinfo.h @@ -51,9 +51,11 @@ #define NETBSD_BTINFO_BOOTPATH 0 #define NETBSD_BTINFO_ROOTDEVICE 1 +#define NETBSD_BTINFO_BOOTDISK 3 #define NETBSD_BTINFO_CONSOLE 6 #define NETBSD_BTINFO_SYMTAB 8 #define NETBSD_BTINFO_MEMMAP 9 +#define NETBSD_BTINFO_BOOTWEDGE 10 #define NETBSD_BTINFO_MODULES 11 #define NETBSD_BTINFO_FRAMEBUF 12 @@ -83,6 +85,15 @@ struct grub_netbsd_btinfo_bootdisk grub_uint32_t partition; }; +struct grub_netbsd_btinfo_bootwedge { + grub_uint32_t biosdev; + grub_disk_addr_t startblk; + grub_uint64_t nblks; + grub_disk_addr_t matchblk; + grub_uint64_t matchnblks; + grub_uint8_t matchhash[16]; /* MD5 hash */ +} __packed; + struct grub_netbsd_btinfo_symtab { grub_uint32_t nsyms; From cca7ccd8ff3bd697110c8f55b9e30b78662235f8 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 29 Sep 2011 10:32:24 +0200 Subject: [PATCH 1225/1414] Remove extra declaration of sleep for mingw32. * util/misc.c (sleep) [__MINGW32__]: Removed. * include/grub/util/misc.h (sleep) [__MINGW32__]: Likewise. --- ChangeLog | 7 +++++++ include/grub/util/misc.h | 1 - util/misc.c | 5 ----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8cdd158cd..6e4aac746 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-09-29 Mario Limonciello + + Remove extra declaration of sleep for mingw32. + + * util/misc.c (sleep) [__MINGW32__]: Removed. + * include/grub/util/misc.h (sleep) [__MINGW32__]: Likewise. + 2011-09-28 GrĂ©goire Sutre * include/grub/bsdlabel.h (grub_partition_bsd_disk_label): Add fields diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 48dfbb868..419c8661c 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -47,7 +47,6 @@ void grub_util_write_image_at (const void *img, size_t size, off_t offset, void sync (void); int fsync (int fno); -void sleep(int s); grub_int64_t grub_util_get_disk_size (char *name); diff --git a/util/misc.c b/util/misc.c index cfbae609b..e4425358a 100644 --- a/util/misc.c +++ b/util/misc.c @@ -316,11 +316,6 @@ int fsync (int fno __attribute__ ((unused))) return 0; } -void sleep (int s) -{ - Sleep (s * 1000); -} - grub_int64_t grub_util_get_disk_size (char *name) { From c05de0329b198bed24e8b8e120877958d9a8cead Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 29 Sep 2011 10:36:55 +0200 Subject: [PATCH 1226/1414] * grub-core/kern/emu/misc.c (canonicalize_file_name) [__MINGW32__]: Use _fullpath. --- ChangeLog | 5 +++++ grub-core/kern/emu/misc.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6e4aac746..bc5508d32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-09-29 Mario Limonciello + + * grub-core/kern/emu/misc.c (canonicalize_file_name) [__MINGW32__]: Use + _fullpath. + 2011-09-29 Mario Limonciello Remove extra declaration of sleep for mingw32. diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 737f5f1a9..6f5ea9fb9 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -224,7 +224,11 @@ char * canonicalize_file_name (const char *path) { char *ret; -#ifdef PATH_MAX +#ifdef __MINGW32__ + ret = xmalloc (PATH_MAX); + if (!_fullpath (ret, path, PATH_MAX)) + return NULL; +#elif defined (PATH_MAX) ret = xmalloc (PATH_MAX); if (!realpath (path, ret)) return NULL; From d1ab689de800eb4a7d66306c96d9dd4f502cf4e5 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 29 Sep 2011 10:39:44 +0200 Subject: [PATCH 1227/1414] * util/misc.c (grub_util_get_disk_size) [__MINGW32__]: Strip trailing slashes on PHYSICALDRIVE%d paths when making Windows CreateFile calls. --- ChangeLog | 5 +++++ util/misc.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index bc5508d32..df31ef3e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-09-29 Mario Limonciello + + * util/misc.c (grub_util_get_disk_size) [__MINGW32__]: Strip trailing + slashes on PHYSICALDRIVE%d paths when making Windows CreateFile calls. + 2011-09-29 Mario Limonciello * grub-core/kern/emu/misc.c (canonicalize_file_name) [__MINGW32__]: Use diff --git a/util/misc.c b/util/misc.c index e4425358a..72bedde0c 100644 --- a/util/misc.c +++ b/util/misc.c @@ -55,6 +55,7 @@ #ifdef __MINGW32__ #include #include +#include "dirname.h" #endif #ifdef GRUB_UTIL @@ -322,6 +323,7 @@ grub_util_get_disk_size (char *name) HANDLE hd; grub_int64_t size = -1LL; + strip_trailing_slashes(name); hd = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); From fc5efcc08346469bb9f4bbb3c3f0b3f4b8c5b4b6 Mon Sep 17 00:00:00 2001 From: Mads Kiilerich Date: Thu, 29 Sep 2011 10:50:25 +0200 Subject: [PATCH 1228/1414] * grub-core/Makefile.core.def (kernel): Add kern/i386/int.S to extra_dist. --- ChangeLog | 5 +++++ grub-core/Makefile.core.def | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index df31ef3e3..db2e0b1f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-09-29 Mads Kiilerich + + * grub-core/Makefile.core.def (kernel): Add kern/i386/int.S to + extra_dist. + 2011-09-29 Mario Limonciello * util/misc.c (grub_util_get_disk_size) [__MINGW32__]: Strip trailing diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index e95d87d37..e9e4f06d8 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -219,6 +219,7 @@ kernel = { videoinkernel = commands/boot.c; + extra_dist = kern/i386/int.S; extra_dist = kern/i386/realmode.S; extra_dist = kern/i386/pc/lzma_decode.S; extra_dist = kern/mips/cache_flush.S; From 8667a314babe5f09580d06d86a3db6489cdcc31e Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 30 Sep 2011 18:49:37 -0700 Subject: [PATCH 1229/1414] * gentpl.py: Use Autogen macros so that the output template file (Makefile.tpl) size is reduced. --- ChangeLog | 5 +++ gentpl.py | 114 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 105 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index db2e0b1f6..ad0e6792f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-25 BVK Chaitanya + + * gentpl.py: Use Autogen macros so that the output template file + (Makefile.tpl) size is reduced. + 2011-09-29 Mads Kiilerich * grub-core/Makefile.core.def (kernel): Add kern/i386/int.S to diff --git a/gentpl.py b/gentpl.py index e431293eb..cb6b663d9 100644 --- a/gentpl.py +++ b/gentpl.py @@ -183,6 +183,17 @@ def foreach_platform_specific_value(platform, suffix, nonetag, closure): r += "[+ ELSE +][+ FOR " + nonetag + " +]" + closure("[+ ." + nonetag + " +]") + "[+ ENDFOR +][+ ENDIF +]" return r +# +# Returns autogen code that defines an autogen macro using the +# definition given in the 'snippet'. +# +def define_autogen_macro(name, snippet): + r = "" + r += "[+ DEFINE " + name + " +]" + r += snippet + r += "[+ ENDDEF +]\n" + return r + # # Template for handling values from sum of all groups for a platform, # for example: @@ -245,10 +256,18 @@ def foreach_enabled_platform(closure): # emu_condition = COND_GRUB_EMU_USB; # }; # +def define_macro_for_platform_conditionals_if_statement(p): + return define_autogen_macro( + "if_" + p + "_conditionals", + foreach_platform_specific_value(platform, "_condition", "condition", lambda cond: "if " + cond + "\n")) +def define_macro_for_platform_conditionals_endif_statement(p): + return define_autogen_macro( + "endif_" + p + "_conditionals", + foreach_platform_specific_value(platform, "_condition", "condition", lambda cond: "endif " + cond + "\n")) def under_platform_specific_conditionals(platform, snippet): - r = foreach_platform_specific_value(platform, "_condition", "condition", lambda cond: "if " + cond + "\n") + r = "[+ if_" + platform + "_conditionals +]" r += snippet - r += foreach_platform_specific_value(platform, "_condition", "condition", lambda cond: "endif " + cond + "\n") + r += "[+ endif_" + platform + "_conditionals +]" return r def platform_specific_values(platform, suffix, nonetag): @@ -261,18 +280,69 @@ def platform_values(platform, suffix): def extra_dist(): return foreach_value("extra_dist", lambda value: value + " ") -def platform_sources(p): return platform_values(p, "") -def platform_nodist_sources(p): return platform_values(p, "_nodist") -def platform_dependencies(p): return platform_values(p, "dependencies", "_dependencies") +def define_macro_for_platform_sources(p): + return define_autogen_macro( + "get_" + p + "_sources", + platform_values(p, "")) +def define_macro_for_platform_nodist_sources(p): + return define_autogen_macro( + "get_" + p + "_nodist_sources", + platform_values(p, "_nodist")) +def define_macro_for_platform_dependencies(p): + return define_autogen_macro( + "get_" + p + "_dependencies", + platform_values(p, "dependencies", "_dependencies")) +def platform_sources(p): return "[+ get_" + p + "_sources +]" +def platform_nodist_sources(p): return "[+ get_" + p + "_nodist_sources +]" +def platform_dependencies(p): return "[+ get_" + p + "_dependencies +]" -def platform_startup(p): return platform_specific_values(p, "_startup", "startup") -def platform_ldadd(p): return platform_specific_values(p, "_ldadd", "ldadd") -def platform_cflags(p): return platform_specific_values(p, "_cflags", "cflags") -def platform_ldflags(p): return platform_specific_values(p, "_ldflags", "ldflags") -def platform_cppflags(p): return platform_specific_values(p, "_cppflags", "cppflags") -def platform_ccasflags(p): return platform_specific_values(p, "_ccasflags", "ccasflags") -def platform_stripflags(p): return platform_specific_values(p, "_stripflags", "stripflags") -def platform_objcopyflags(p): return platform_specific_values(p, "_objcopyflags", "objcopyflags") +# +# Returns Autogen code which defines the autogen macros that collect +# platform specific values for cflags, ldflags, etc. tags. +# +def define_macro_for_platform_startup(p): + return define_autogen_macro( + "get_" + p + "_startup", + platform_specific_values(p, "_startup", "startup")) +def define_macro_for_platform_cflags(p): + return define_autogen_macro( + "get_" + p + "_cflags", + platform_specific_values(p, "_cflags", "cflags")) +def define_macro_for_platform_ldadd(p): + return define_autogen_macro( + "get_" + p + "_ldadd", + platform_specific_values(p, "_ldadd", "ldadd")) +def define_macro_for_platform_ldflags(p): + return define_autogen_macro( + "get_" + p + "_ldflags", + platform_specific_values(p, "_ldflags", "ldflags")) +def define_macro_for_platform_cppflags(p): + return define_autogen_macro( + "get_" + p + "_cppflags", + platform_specific_values(p, "_cppflags", "cppflags")) +def define_macro_for_platform_ccasflags(p): + return define_autogen_macro( + "get_" + p + "_ccasflags", + platform_specific_values(p, "_ccasflags", "ccasflags")) +def define_macro_for_platform_stripflags(p): + return define_autogen_macro( + "get_" + p + "_stripflags", + platform_specific_values(p, "_stripflags", "stripflags")) +def define_macro_for_platform_objcopyflags(p): + return define_autogen_macro( + "get_" + p + "_objcopyflags", + platform_specific_values(p, "_objcopyflags", "objcopyflags")) +# +# Autogen calls to invoke the above macros. +# +def platform_startup(p): return "[+ get_" + p + "_startup +]" +def platform_ldadd(p): return "[+ get_" + p + "_ldadd +]" +def platform_cflags(p): return "[+ get_" + p + "_cflags +]" +def platform_ldflags(p): return "[+ get_" + p + "_ldflags +]" +def platform_cppflags(p): return "[+ get_" + p + "_cppflags +]" +def platform_ccasflags(p): return "[+ get_" + p + "_ccasflags +]" +def platform_stripflags(p): return "[+ get_" + p + "_stripflags +]" +def platform_objcopyflags(p): return "[+ get_" + p + "_objcopyflags +]" # # Emit snippet only the first time through for the current name. @@ -489,7 +559,6 @@ def script_rules(): def data_rules(): return rules("data", data) -print "[+ AutoGen5 template +]\n" a = module_rules() b = kernel_rules() c = image_rules() @@ -499,6 +568,23 @@ f = script_rules() g = data_rules() z = global_variable_initializers() +print "[+ AutoGen5 template +]\n" +for p in GRUB_PLATFORMS: + print define_macro_for_platform_sources(p) + print define_macro_for_platform_nodist_sources(p) + # print define_macro_for_platform_dependencies(p) + + print define_macro_for_platform_startup(p) + print define_macro_for_platform_cflags(p) + print define_macro_for_platform_ldadd(p) + print define_macro_for_platform_ldflags(p) + print define_macro_for_platform_cppflags(p) + print define_macro_for_platform_ccasflags(p) + print define_macro_for_platform_stripflags(p) + print define_macro_for_platform_objcopyflags(p) + + print define_macro_for_platform_conditionals_if_statement(p) + print define_macro_for_platform_conditionals_endif_statement(p) # print z # initializer for all vars print a print b From ce79cc99d500a92c927a15647d0c86bde6d0448c Mon Sep 17 00:00:00 2001 From: starous Date: Sat, 1 Oct 2011 21:27:29 +0200 Subject: [PATCH 1230/1414] @Rock changes - fixed coreboot problem --- ChangeLog | 5 +++++ grub-core/bus/usb/uhci.c | 48 +++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad0e6792f..5d1fc0c69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-01 Ales Nesrsta + + * grub-core/bus/usb/uhci.c: Changes made by Rock Cui - thanks! + (fixed problem related to using UHCI with coreboot). + 2011-08-25 BVK Chaitanya * gentpl.py: Use Autogen macros so that the output template file diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 99e597f6d..260b7e876 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -36,11 +36,33 @@ GRUB_MOD_LICENSE ("GPLv3+"); typedef enum { GRUB_UHCI_REG_USBCMD = 0x00, + GRUB_UHCI_REG_USBINTR = 0x04, GRUB_UHCI_REG_FLBASEADD = 0x08, GRUB_UHCI_REG_PORTSC1 = 0x10, - GRUB_UHCI_REG_PORTSC2 = 0x12 + GRUB_UHCI_REG_PORTSC2 = 0x12, + GRUB_UHCI_REG_USBLEGSUP = 0xc0 } grub_uhci_reg_t; +/* R/WC legacy support bits */ +#define GRUB_UHCI_LEGSUP_END_A20GATE (1 << 15) +#define GRUB_UHCI_TRAP_BY_64H_WSTAT (1 << 11) +#define GRUB_UHCI_TRAP_BY_64H_RSTAT (1 << 10) +#define GRUB_UHCI_TRAP_BY_60H_WSTAT (1 << 9) +#define GRUB_UHCI_TRAP_BY_60H_RSTAT (1 << 8) + +/* Reset all legacy support - clear all R/WC bits and all R/W bits */ +#define GRUB_UHCI_RESET_LEGSUP_SMI ( GRUB_UHCI_LEGSUP_END_A20GATE \ + | GRUB_UHCI_TRAP_BY_64H_WSTAT \ + | GRUB_UHCI_TRAP_BY_64H_RSTAT \ + | GRUB_UHCI_TRAP_BY_60H_WSTAT \ + | GRUB_UHCI_TRAP_BY_60H_RSTAT ) + +/* Some UHCI commands */ +#define GRUB_UHCI_CMD_RUN_STOP (1 << 0) +#define GRUB_UHCI_CMD_HCRESET (1 << 1) +#define GRUB_UHCI_CMD_MAXP (1 << 7) + +/* Important bits in structures */ #define GRUB_UHCI_LINK_TERMINATE 1 #define GRUB_UHCI_LINK_QUEUE_HEAD 2 @@ -181,6 +203,11 @@ grub_uhci_pci_iter (grub_pci_device_t dev, if (class != 0x0c || subclass != 0x03 || interf != 0x00) return 0; + /* Set bus master - needed for coreboot or broken BIOSes */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word(addr, + GRUB_PCI_COMMAND_BUS_MASTER | grub_pci_read_word(addr)); + /* Determine IO base address. */ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4); base = grub_pci_read (addr); @@ -195,6 +222,19 @@ grub_uhci_pci_iter (grub_pci_device_t dev, u->iobase = base & GRUB_UHCI_IOMASK; + /* Reset PIRQ and SMI */ + addr = grub_pci_make_address (dev, GRUB_UHCI_REG_USBLEGSUP); + grub_pci_write_word(addr, GRUB_UHCI_RESET_LEGSUP_SMI); + /* Reset the HC */ + grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, GRUB_UHCI_CMD_HCRESET); + grub_millisleep(5); + /* Disable interrupts and commands (just to be safe) */ + grub_uhci_writereg16(u, GRUB_UHCI_REG_USBINTR, 0); + /* Finish HC reset, HC remains disabled */ + grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, 0); + /* Read back to be sure PCI write is done */ + grub_uhci_readreg16(u, GRUB_UHCI_REG_USBCMD); + /* Reserve a page for the frame list. */ u->framelist = grub_memalign (4096, 4096); if (! u->framelist) @@ -252,9 +292,6 @@ grub_uhci_pci_iter (grub_pci_device_t dev, u->td[N_TD - 2].linkptr = 0; u->tdfree = u->td; - /* Make sure UHCI is disabled! */ - grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0); - /* Setup the frame list pointers. Since no isochronous transfers are and will be supported, they all point to the (same!) queue head. */ @@ -285,7 +322,8 @@ grub_uhci_pci_iter (grub_pci_device_t dev, u->qh[N_QH - 1].linkptr = 1; /* Enable UHCI again. */ - grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7)); + grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, + GRUB_UHCI_CMD_RUN_STOP | GRUB_UHCI_CMD_MAXP); /* UHCI is initialized and ready for transfers. */ grub_dprintf ("uhci", "UHCI initialized\n"); From 139d67a82fb1738e642424e2d425916d97c8e098 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 21:50:32 +0200 Subject: [PATCH 1231/1414] * grub-core/fs/btrfs.c: Fix code style regressions. --- grub-core/fs/btrfs.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 534ce15de..5b8dca559 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -330,8 +330,8 @@ next (struct grub_btrfs_data *data, for (; desc->depth > 0; desc->depth--) { desc->data[desc->depth - 1].iter++; - if (desc->data[desc->depth - 1].iter < - desc->data[desc->depth - 1].maxiter) + if (desc->data[desc->depth - 1].iter + < desc->data[desc->depth - 1].maxiter) break; } if (desc->depth == 0) @@ -376,7 +376,7 @@ lower_bound (struct grub_btrfs_data *data, const struct grub_btrfs_key *key_in, struct grub_btrfs_key *key_out, grub_disk_addr_t root, - grub_disk_addr_t * outaddr, grub_size_t * outsize, + grub_disk_addr_t *outaddr, grub_size_t *outsize, struct grub_btrfs_leaf_descriptor *desc) { grub_disk_addr_t addr = root; @@ -626,8 +626,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_le_to_cpu64 (key->offset), grub_le_to_cpu64 (chunk->size)); if (grub_le_to_cpu64 (key->offset) <= addr - && addr < - grub_le_to_cpu64 (key->offset) + grub_le_to_cpu64 (chunk->size)) + && addr < grub_le_to_cpu64 (key->offset) + + grub_le_to_cpu64 (chunk->size)) goto chunk_found; ptr += sizeof (*key) + sizeof (*chunk) + sizeof (struct grub_btrfs_chunk_stripe) @@ -1007,8 +1007,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size); if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR - && (char *) &data->extent + elemsize >= - (char *) &data->extent->filled + sizeof (data->extent->filled)) + && (char *) &data->extent + elemsize + >= (char *) &data->extent->filled + sizeof (data->extent->filled)) data->extend = data->extstart + grub_le_to_cpu64 (data->extent->filled); @@ -1113,7 +1113,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, else ret = -1; - grub_free(tmp); + grub_free (tmp); if (ret != (grub_ssize_t) csize) return -1; @@ -1142,7 +1142,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, static grub_err_t find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, - grub_uint64_t * tree, grub_uint8_t * type) + grub_uint64_t *tree, grub_uint8_t *type) { const char *slash = path; grub_err_t err; @@ -1391,7 +1391,7 @@ find_path (struct grub_btrfs_data *data, static grub_err_t grub_btrfs_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, - const struct grub_dirhook_info * info)) + const struct grub_dirhook_info *info)) { struct grub_btrfs_data *data = grub_btrfs_mount (device); struct grub_btrfs_key key_in, key_out; From c5ed9266fc216a2c62781b87d6a4ff97315a70f0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 22:06:10 +0200 Subject: [PATCH 1232/1414] * grub-core/io/lzopio.c: Improve crypt context alignment. --- grub-core/io/lzopio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index e303b29a3..d804c31b0 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -166,7 +166,7 @@ read_block_data (struct grub_lzopio *lzopio) if (lzopio->ccheck_fun) { - grub_uint8_t context[lzopio->ccheck_fun->contextsize]; + grub_uint64_t context[(lzopio->ccheck_fun->contextsize + 7) / 8]; lzopio->ccheck_fun->init (context); lzopio->ccheck_fun->write (context, lzopio->block.cdata, @@ -212,7 +212,7 @@ uncompress_block (struct grub_lzopio *lzopio) if (lzopio->ucheck_fun) { - grub_uint8_t context[lzopio->ucheck_fun->contextsize]; + grub_uint64_t context[(lzopio->ccheck_fun->contextsize + 7) / 8]; lzopio->ucheck_fun->init (context); lzopio->ucheck_fun->write (context, lzopio->block.udata, From 0e2b7e39f2e2d9089efb307d9e58aedf3e5b1c57 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 22:25:06 +0200 Subject: [PATCH 1233/1414] * grub-core/fs/btrfs.c: Include instead of "minilzo.h". * grub-core/io/lzopio.c: Likewise. --- grub-core/fs/btrfs.c | 2 +- grub-core/io/lzopio.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 5b8dca559..93642f789 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -26,7 +26,7 @@ #include #include #include -#include "minilzo.h" +#include GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index d804c31b0..e2bbf79b7 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -23,7 +23,7 @@ #include #include #include -#include "minilzo.h" +#include GRUB_MOD_LICENSE ("GPLv3+"); From b871e8ebcca01098727b1bc324e490b8de5a5a1b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2011 23:01:14 +0200 Subject: [PATCH 1234/1414] * grub-core/Makefile.core.def (btrfs): Remove minilzo.c from common. --- grub-core/Makefile.core.def | 1 - 1 file changed, 1 deletion(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 77dc7ed4b..b58a75f67 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -980,7 +980,6 @@ module = { name = btrfs; common = fs/btrfs.c; common = lib/crc.c; - common = lib/minilzo/minilzo.c; cflags = '$(CFLAGS_POSIX) -Wno-undef'; cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; }; From bc4d3f4809353539891a04bc218ff7ef37cb2536 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Oct 2011 21:10:21 +0200 Subject: [PATCH 1235/1414] * grub-core/io/lzopio.c (calculate_uncompressed_size): Fix return code. --- grub-core/io/lzopio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index e2bbf79b7..02a70f4d8 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -256,7 +256,7 @@ calculate_uncompressed_size (grub_file_t file) grub_off_t usize_total = 0; if (read_block_header (lzopio) < 0) - return 0; + return -1; /* FIXME: Don't do this for not easily seekable files. */ while (lzopio->block.usize != 0) @@ -264,12 +264,12 @@ calculate_uncompressed_size (grub_file_t file) usize_total += lzopio->block.usize; if (jump_block (lzopio) < 0) - return 0; + return -1; } file->size = usize_total; - return 1; + return 0; } struct lzop_header From fe942b7dbb891a3f092acdb63a63ee0376cb5cba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Oct 2011 11:53:36 +0200 Subject: [PATCH 1236/1414] * grub-core/Makefile.core.def: Eliminate rarely used emu_condition. This in perspective decreases the complexity of build system and fixes compilation right now. --- grub-core/Makefile.core.def | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index e9e4f06d8..3b701633c 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -400,11 +400,15 @@ module = { module = { name = usb; common = bus/usb/usb.c; - noemu = bus/usb/usbtrans.c; - noemu = bus/usb/usbhub.c; - enable = emu; + common = bus/usb/usbtrans.c; + common = bus/usb/usbhub.c; enable = usb; - emu_condition = COND_GRUB_EMU_USB; +}; + +module = { + name = emuusb; + common = bus/usb/usb.c; + condition = COND_GRUB_EMU_USB; }; module = { @@ -439,18 +443,22 @@ module = { module = { name = pci; - noemu = bus/pci.c; - emu = bus/emu/pci.c; - emu = commands/lspci.c; + common = bus/pci.c; - enable = emu; enable = i386_pc; enable = i386_efi; enable = x86_64_efi; enable = i386_ieee1275; enable = i386_coreboot; enable = i386_multiboot; - emu_condition = COND_GRUB_EMU_PCI; +}; + +module = { + name = emupci; + common = bus/emu/pci.c; + common = commands/lspci.c; + + condition = COND_GRUB_EMU_PCI; }; module = { @@ -788,8 +796,6 @@ module = { name = usbtest; common = commands/usbtest.c; enable = usb; - enable = emu; - emu_condition = COND_GRUB_EMU_USB; }; module = { @@ -903,8 +909,6 @@ module = { name = usbms; common = disk/usbms.c; enable = usb; - enable = emu; - emu_condition = COND_GRUB_EMU_USB; }; module = { @@ -1446,9 +1450,7 @@ module = { common = term/serial.c; x86 = term/ns8250.c; - enable = emu; enable = x86; - emu_condition = COND_GRUB_EMU_USB; }; module = { From a98f4a0808308815c5580d3ac23b2442d02ced33 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 9 Oct 2011 21:13:00 +0200 Subject: [PATCH 1237/1414] 2011-10-09 Robert Millan LVM support for FreeBSD and GNU/kFreeBSD. * util/lvm.c (grub_util_lvm_isvolume): Enable on FreeBSD and GNU/kFreeBSD. (LVM_DEV_MAPPER_STRING): Move from here ... * include/grub/util/lvm.h (LVM_DEV_MAPPER_STRING): ... to here. * util/getroot.c: Include `'. (grub_util_get_dev_abstraction): Enable grub_util_biosdisk_is_present() on FreeBSD and GNU/kFreeBSD. Check for LVM abstraction on FreeBSD and GNU/kFreeBSD. (grub_util_get_grub_dev): Replace "/dev/mapper/" with `LVM_DEV_MAPPER_STRING'. Enable LVM and mdRAID only on platforms that support it. * util/grub-setup.c (main): Check for LVM also on FreeBSD and GNU/kFreeBSD. * util/grub.d/10_kfreebsd.in: Load `geom_linux_lvm' kernel module when LVM abstraction is required for ${GRUB_DEVICE}. --- ChangeLog | 20 ++++++++++++++++++++ include/grub/util/lvm.h | 9 ++++++++- util/getroot.c | 24 ++++++++++++++++-------- util/grub-setup.c | 6 ++++-- util/grub.d/10_kfreebsd.in | 8 +++++++- util/lvm.c | 9 +++------ 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6484cf826..19db47e04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-10-09 Robert Millan + + LVM support for FreeBSD and GNU/kFreeBSD. + + * util/lvm.c (grub_util_lvm_isvolume): Enable on FreeBSD and + GNU/kFreeBSD. + (LVM_DEV_MAPPER_STRING): Move from here ... + * include/grub/util/lvm.h (LVM_DEV_MAPPER_STRING): ... to here. + * util/getroot.c: Include `'. + (grub_util_get_dev_abstraction): Enable + grub_util_biosdisk_is_present() on FreeBSD and GNU/kFreeBSD. + Check for LVM abstraction on FreeBSD and GNU/kFreeBSD. + (grub_util_get_grub_dev): Replace "/dev/mapper/" with + `LVM_DEV_MAPPER_STRING'. Enable LVM and mdRAID only on platforms that + support it. + * util/grub-setup.c (main): Check for LVM also on FreeBSD and + GNU/kFreeBSD. + * util/grub.d/10_kfreebsd.in: Load `geom_linux_lvm' kernel module + when LVM abstraction is required for ${GRUB_DEVICE}. + 2011-10-06 Szymon Janc Add support for LZO compression in GRUB: diff --git a/include/grub/util/lvm.h b/include/grub/util/lvm.h index 7a4c76c6b..ff268f83f 100644 --- a/include/grub/util/lvm.h +++ b/include/grub/util/lvm.h @@ -1,7 +1,7 @@ /* lvm.h - LVM support for GRUB utils. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * Copyright (C) 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 @@ -20,7 +20,14 @@ #ifndef GRUB_LVM_UTIL_HEADER #define GRUB_LVM_UTIL_HEADER 1 +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + #ifdef __linux__ +#define LVM_DEV_MAPPER_STRING "/dev/mapper/" +#else +#define LVM_DEV_MAPPER_STRING "/dev/linux_lvm/" +#endif + int grub_util_lvm_isvolume (char *name); #endif diff --git a/util/getroot.c b/util/getroot.c index 71064583f..7c5602e71 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -1,7 +1,7 @@ /* getroot.c - Get root device */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,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 @@ -33,6 +33,7 @@ #include #include #include +#include #include #ifdef HAVE_DEVICE_MAPPER @@ -856,12 +857,14 @@ grub_util_get_geom_abstraction (const char *dev) int grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { -#ifdef __linux__ - enum grub_dev_abstraction_types ret; - +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* User explicitly claims that this drive is visible by BIOS. */ if (grub_util_biosdisk_is_present (os_dev)) return GRUB_DEV_ABSTRACTION_NONE; +#endif + +#ifdef __linux__ + enum grub_dev_abstraction_types ret; /* Check for LVM and LUKS. */ ret = grub_util_get_dm_abstraction (os_dev); @@ -880,6 +883,10 @@ grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) grub_util_info ("abstraction of %s is %s", os_dev, abs); if (abs && grub_strcasecmp (abs, "eli") == 0) return GRUB_DEV_ABSTRACTION_GELI; + + /* Check for LVM. */ + if (!strncmp (os_dev, LVM_DEV_MAPPER_STRING, sizeof(LVM_DEV_MAPPER_STRING)-1)) + return GRUB_DEV_ABSTRACTION_LVM; #endif /* No abstraction found. */ @@ -1111,11 +1118,12 @@ grub_util_get_grub_dev (const char *os_dev) switch (grub_util_get_dev_abstraction (os_dev)) { +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) case GRUB_DEV_ABSTRACTION_LVM: { unsigned short i, len; - grub_size_t offset = sizeof ("/dev/mapper/") - 1; + grub_size_t offset = sizeof (LVM_DEV_MAPPER_STRING) - 1; len = strlen (os_dev) - offset + 1; grub_dev = xmalloc (len + sizeof ("lvm/")); @@ -1191,7 +1199,9 @@ grub_util_get_grub_dev (const char *os_dev) } #endif break; +#endif +#ifdef __linux__ case GRUB_DEV_ABSTRACTION_RAID: if (os_dev[7] == '_' && os_dev[8] == 'd') @@ -1267,7 +1277,6 @@ grub_util_get_grub_dev (const char *os_dev) else grub_util_error ("unknown kind of RAID device `%s'", os_dev); -#ifdef __linux__ { char *mdadm_name = get_mdadm_uuid (os_dev); struct stat st; @@ -1292,9 +1301,8 @@ grub_util_get_grub_dev (const char *os_dev) free (mdadm_name); } } -#endif /* __linux__ */ - break; +#endif /* __linux__ */ default: /* GRUB_DEV_ABSTRACTION_NONE */ grub_dev = grub_util_biosdisk_get_grub_dev (os_dev); diff --git a/util/grub-setup.c b/util/grub-setup.c index 2505c03a4..b3a6c5c76 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -1,7 +1,7 @@ /* grub-setup.c - make GRUB usable */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,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 @@ -954,10 +954,12 @@ main (int argc, char *argv[]) arguments.dir ? : DEFAULT_DIRECTORY); } -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (grub_util_lvm_isvolume (root_dev)) must_embed = 1; +#endif +#ifdef __linux__ if (root_dev[0] == 'm' && root_dev[1] == 'd' && ((root_dev[2] >= '0' && root_dev[2] <= '9') || root_dev[2] == '/')) { diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 2ade4ea35..e4bfc06cb 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -2,7 +2,7 @@ set -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010,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 @@ -98,6 +98,12 @@ EOF load_kfreebsd_module acpi true + for abstraction in dummy $(grub-probe -t abstraction --device ${GRUB_DEVICE}) ; do + case $abstraction in + lvm) load_kfreebsd_module geom_linux_lvm false ;; + esac + done + case "${kfreebsd_fs}" in zfs) load_kfreebsd_module opensolaris false diff --git a/util/lvm.c b/util/lvm.c index bb2c19fe3..0bc271e46 100644 --- a/util/lvm.c +++ b/util/lvm.c @@ -1,7 +1,7 @@ /* lvm.c - LVM support for GRUB utils. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2008,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 @@ -17,8 +17,7 @@ * along with GRUB. If not, see . */ -/* We only support LVM on Linux. */ -#ifdef __linux__ +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include #include #include @@ -26,8 +25,6 @@ #include #include -#define LVM_DEV_MAPPER_STRING "/dev/mapper/" - int grub_util_lvm_isvolume (char *name) { @@ -49,4 +46,4 @@ grub_util_lvm_isvolume (char *name) return 1; } -#endif /* ! __linux__ */ +#endif From 0eb8ffb1f579d4507d78a822c843e334417f9ba1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Oct 2011 19:16:37 +0200 Subject: [PATCH 1238/1414] * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. * include/grub/misc.h (grub_isxdigit): New function. * grub-core/video/colors.c (my_isxdigit): Removed. All users switched to grub_isxdigit. * grub-core/term/serial.c (grub_serial_find): Fix in case of port number starting with a letter. --- ChangeLog | 15 +++++++++++++++ grub-core/lib/posix_wrap/ctype.h | 3 +-- grub-core/term/serial.c | 2 +- grub-core/video/colors.c | 10 +--------- include/grub/misc.h | 6 ++++++ 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19db47e04..44882054c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-14 Vladimir Serbinenko + + * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. + * include/grub/misc.h (grub_isxdigit): New function. + * grub-core/video/colors.c (my_isxdigit): Removed. All users + switched to grub_isxdigit. + * grub-core/term/serial.c (grub_serial_find): Fix in case of port + number starting with a letter. + 2011-10-09 Robert Millan LVM support for FreeBSD and GNU/kFreeBSD. @@ -63,6 +72,12 @@ (grub_get_unaligned64): Likewise. * util/import_gcry.py (cryptolist): Add adler32. +2011-10-05 Vladimir Serbinenko + + * grub-core/Makefile.core.def: Eliminate rarely used emu_condition. This + in perspective decreases the complexity of build system and fixes + compilation right now. + 2011-10-01 Ales Nesrsta * grub-core/bus/usb/uhci.c: Changes made by Rock Cui - thanks! diff --git a/grub-core/lib/posix_wrap/ctype.h b/grub-core/lib/posix_wrap/ctype.h index 2dc3e53e9..9589778b6 100644 --- a/grub-core/lib/posix_wrap/ctype.h +++ b/grub-core/lib/posix_wrap/ctype.h @@ -54,8 +54,7 @@ isupper (int c) static inline int isxdigit (int c) { - return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') - || (c >= '0' && c <= '9'); + return grub_isxdigit (c); } static inline int diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index b724a945a..306694192 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -136,7 +136,7 @@ grub_serial_find (char *name) #ifndef GRUB_MACHINE_EMU if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 - && grub_isdigit (name [sizeof ("port") - 1])) + && grub_isxdigit (name [sizeof ("port") - 1])) { name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1], 0, 16)); diff --git a/grub-core/video/colors.c b/grub-core/video/colors.c index 3119c0249..06625183e 100644 --- a/grub-core/video/colors.c +++ b/grub-core/video/colors.c @@ -211,14 +211,6 @@ grub_video_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) { @@ -267,7 +259,7 @@ grub_video_parse_color (const char *s, grub_video_rgba_color_t *color) /* Count the hexits to determine the format. */ int hexits = 0; const char *end = s; - while (my_isxdigit (*end)) + while (grub_isxdigit (*end)) { end++; hexits++; diff --git a/include/grub/misc.h b/include/grub/misc.h index da4bd4a7e..66e74d8a8 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -136,6 +136,12 @@ grub_isdigit (int c) return (c >= '0' && c <= '9'); } +static inline int +grub_isxdigit (int c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + static inline int grub_isalnum (int c) { From c81296b65fad1d9bb4e5e2bb433719e5644827f0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Oct 2011 19:20:44 +0200 Subject: [PATCH 1239/1414] * grub-core/kern/emu/hostdisk.c (convert_system_partition_to_system_disk): Don't assume that children of mapper nodes are mapper nodes. --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 44882054c..3be8005a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-14 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c + (convert_system_partition_to_system_disk): Don't assume that children + of mapper nodes are mapper nodes. + 2011-10-14 Vladimir Serbinenko * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index a9a8c066e..23417a64d 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1416,7 +1416,7 @@ 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 ("/dev/mapper", + char *ret = grub_find_device ("/dev", (major << 8) | minor); return ret; } From d891955241a5976694738b63c752bb9e35d248a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 14 Oct 2011 22:41:21 +0200 Subject: [PATCH 1240/1414] Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. * grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate types. (grub_hfsplus_btree_recoffset): Likewise. (grub_hfsplus_btree_recptr): Likewise. (grub_hfsplus_find_block): Likewise. (grub_hfsplus_btree_search): Likewise. (grub_hfsplus_read_block): Likewise. (grub_hfsplus_read_file): Likewise. (grub_hfsplus_mount): Likewise. (grub_hfsplus_btree_iterate_node): Likewise. (grub_hfsplus_btree_search): Likewise. (grub_hfsplus_iterate_dir): Likewise. (grub_hfsplus_read): A small code simplification. --- ChangeLog | 18 +++++++++++++++ grub-core/fs/hfsplus.c | 52 ++++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3be8005a7..9a8b38fd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2011-10-14 Vladimir Serbinenko + + Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. + + * grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate + types. + (grub_hfsplus_btree_recoffset): Likewise. + (grub_hfsplus_btree_recptr): Likewise. + (grub_hfsplus_find_block): Likewise. + (grub_hfsplus_btree_search): Likewise. + (grub_hfsplus_read_block): Likewise. + (grub_hfsplus_read_file): Likewise. + (grub_hfsplus_mount): Likewise. + (grub_hfsplus_btree_iterate_node): Likewise. + (grub_hfsplus_btree_search): Likewise. + (grub_hfsplus_iterate_dir): Likewise. + (grub_hfsplus_read): A small code simplification. + 2011-10-14 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 304b32126..245cd93a5 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -214,7 +214,7 @@ struct grub_fshelp_node struct grub_hfsplus_btree { grub_uint32_t root; - int nodesize; + grub_size_t nodesize; /* Catalog file node. */ struct grub_fshelp_node file; @@ -236,7 +236,7 @@ struct grub_hfsplus_data /* This is the offset into the physical disk for an embedded HFS+ filesystem (one inside a plain HFS wrapper). */ - int embedded_offset; + grub_disk_addr_t embedded_offset; int case_sensitive; }; @@ -245,7 +245,7 @@ static grub_dl_t my_mod; /* Return the offset of the record with the index INDEX, in the node NODE which is part of the B+ tree BTREE. */ -static inline unsigned int +static inline grub_off_t grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *node, int index) { @@ -263,7 +263,7 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *node, int index) { char *cnode = (char *) node; - unsigned int offset; + grub_off_t offset; offset = grub_hfsplus_btree_recoffset (btree, node, index); return (struct grub_hfsplus_key *) &cnode[offset]; } @@ -272,12 +272,12 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree, /* Find the extent that points to FILEBLOCK. If it is not in one of the 8 extents described by EXTENT, return -1. In that case set FILEBLOCK to the next block. */ -static int +static grub_disk_addr_t grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, - int *fileblock) + grub_disk_addr_t *fileblock) { int i; - grub_size_t blksleft = *fileblock; + grub_disk_addr_t blksleft = *fileblock; /* First lookup the file in the given extents. */ for (i = 0; i < 8; i++) @@ -288,7 +288,7 @@ grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, } *fileblock = blksleft; - return -1; + return 0xffffffffffffffffULL; } static grub_err_t @@ -296,7 +296,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, struct grub_hfsplus_key_internal *key, int (*compare_keys) (struct grub_hfsplus_key *keya, struct grub_hfsplus_key_internal *keyb), - struct grub_hfsplus_btnode **matchnode, int *keyoffset); + struct grub_hfsplus_btnode **matchnode, + grub_off_t *keyoffset); static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, struct grub_hfsplus_key_internal *keyb); @@ -307,15 +308,15 @@ static grub_disk_addr_t grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { struct grub_hfsplus_btnode *nnode = 0; - int blksleft = fileblock; + grub_disk_addr_t blksleft = fileblock; struct grub_hfsplus_extent *extents = &node->extents[0]; while (1) { struct grub_hfsplus_extkey *key; struct grub_hfsplus_extkey_internal extoverflow; - int blk; - int ptr; + grub_disk_addr_t blk; + grub_off_t ptr; /* Try to find this block in the current set of extents. */ blk = grub_hfsplus_find_block (extents, &blksleft); @@ -325,7 +326,7 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_free (nnode); nnode = 0; - if (blk != -1) + if (blk != 0xffffffffffffffffULL) return (blk + (node->data->embedded_offset >> (node->data->log2blksize - GRUB_DISK_SECTOR_BITS))); @@ -376,7 +377,7 @@ static grub_ssize_t grub_hfsplus_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_hfsplus_read_block, @@ -411,9 +412,9 @@ grub_hfsplus_mount (grub_disk_t disk) data->embedded_offset = 0; if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC) { - int extent_start; - int ablk_size; - int ablk_start; + grub_disk_addr_t extent_start; + grub_disk_addr_t ablk_size; + grub_disk_addr_t ablk_start; /* See if there's an embedded HFS+ filesystem. */ if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC) @@ -601,10 +602,10 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) static int grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *first_node, - int first_rec, + grub_disk_addr_t first_rec, int (*hook) (void *record)) { - int rec; + grub_disk_addr_t rec; for (;;) { @@ -642,12 +643,13 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, struct grub_hfsplus_key_internal *key, int (*compare_keys) (struct grub_hfsplus_key *keya, struct grub_hfsplus_key_internal *keyb), - struct grub_hfsplus_btnode **matchnode, int *keyoffset) + struct grub_hfsplus_btnode **matchnode, + grub_off_t *keyoffset) { grub_uint64_t currnode; char *node; struct grub_hfsplus_btnode *nodedesc; - int rec; + grub_disk_addr_t rec; node = grub_malloc (btree->nodesize); if (! node) @@ -825,7 +827,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, struct grub_hfsplus_key_internal intern; struct grub_hfsplus_btnode *node; - int ptr; + grub_disk_addr_t ptr; /* Create a key that points to the first entry in the directory. */ intern.catkey.parent = dir->fileid; @@ -894,7 +896,6 @@ grub_hfsplus_close (grub_file_t file) return GRUB_ERR_NONE; } - /* Read LEN bytes data from FILE into BUF. */ static grub_ssize_t grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) @@ -902,13 +903,10 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) struct grub_hfsplus_data *data = (struct grub_hfsplus_data *) file->data; - int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook, + return grub_hfsplus_read_file (&data->opened_file, file->read_hook, file->offset, len, buf); - - return size; } - static grub_err_t grub_hfsplus_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, From 0017e5ef84cb4c7ac135254a52256d700e1c7dcb Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 15 Oct 2011 13:33:41 +0200 Subject: [PATCH 1241/1414] 2011-10-15 Robert Millan Fix build problem on FreeBSD and GNU/kFreeBSD. * util/getroot.c [__FreeBSD_kernel__]: Include `'. --- ChangeLog | 6 ++++++ util/getroot.c | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9a8b38fd0..723531f5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-15 Robert Millan + + Fix build problem on FreeBSD and GNU/kFreeBSD. + + * util/getroot.c [__FreeBSD_kernel__]: Include `'. + 2011-10-14 Vladimir Serbinenko Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. diff --git a/util/getroot.c b/util/getroot.c index 7c5602e71..510049acb 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -52,6 +52,10 @@ # include #endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +# include +#endif + #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) # include # include From 8bcebcb8e4cb75b0b6deffeb735c9fe26eb437b1 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 15 Oct 2011 18:37:55 +0200 Subject: [PATCH 1242/1414] 2011-10-15 Robert Millan * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. --- ChangeLog | 4 ++++ util/getroot.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 723531f5c..11b14ec28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-15 Robert Millan + + * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. + 2011-10-15 Robert Millan Fix build problem on FreeBSD and GNU/kFreeBSD. diff --git a/util/getroot.c b/util/getroot.c index 510049acb..3d6f9370c 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -1137,7 +1137,9 @@ grub_util_get_grub_dev (const char *os_dev) } break; +#endif +#ifdef __linux__ case GRUB_DEV_ABSTRACTION_LUKS: { char *uuid, *dash; @@ -1152,9 +1154,10 @@ grub_util_get_grub_dev (const char *os_dev) grub_free (uuid); } break; +#endif - case GRUB_DEV_ABSTRACTION_GELI: #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) + case GRUB_DEV_ABSTRACTION_GELI: { char *whole; struct gmesh mesh; @@ -1201,7 +1204,6 @@ grub_util_get_grub_dev (const char *os_dev) } } } -#endif break; #endif From 3b619ae116833fa8624d72f4c83b9c8f266ab5a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 11:48:54 +0200 Subject: [PATCH 1243/1414] * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. (GRUB_XFS_INO_AGBITS): Make into inline function. (GRUB_XFS_INO_INOINAG): Likewise. (GRUB_XFS_INO_AG): Likewise. (GRUB_XFS_FSB_TO_BLOCK): Likewise. (GRUB_XFS_EXTENT_OFFSET): Likewise. (GRUB_XFS_EXTENT_BLOCK): Likewise. (GRUB_XFS_EXTENT_SIZE): Likewise. (GRUB_XFS_ROUND_TO_DIRENT): Likewise. (GRUB_XFS_NEXT_DIRENT): Likewise. (grub_xfs_read_block): Rewrite the btree parsing. Fixes invalid BMAP. (grub_xfs_read_file): Fix offset type. --- ChangeLog | 15 ++++++ grub-core/fs/xfs.c | 111 ++++++++++++++++++++++++++++++++------------- 2 files changed, 94 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 11b14ec28..abe19dc78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-10-16 Vladimir Serbinenko + + * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. + (GRUB_XFS_INO_AGBITS): Make into inline function. + (GRUB_XFS_INO_INOINAG): Likewise. + (GRUB_XFS_INO_AG): Likewise. + (GRUB_XFS_FSB_TO_BLOCK): Likewise. + (GRUB_XFS_EXTENT_OFFSET): Likewise. + (GRUB_XFS_EXTENT_BLOCK): Likewise. + (GRUB_XFS_EXTENT_SIZE): Likewise. + (GRUB_XFS_ROUND_TO_DIRENT): Likewise. + (GRUB_XFS_NEXT_DIRENT): Likewise. + (grub_xfs_read_block): Rewrite the btree parsing. Fixes invalid BMAP. + (grub_xfs_read_file): Fix offset type. + 2011-10-15 Robert Millan * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index eb0783407..3dc5e0af0 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -120,7 +120,9 @@ struct grub_xfs_inode grub_uint64_t nblocks; grub_uint32_t extsize; grub_uint32_t nextents; - grub_uint8_t unused3[20]; + grub_uint16_t unused3; + grub_uint8_t fork_offset; + grub_uint8_t unused4[17]; union { char raw[156]; @@ -154,7 +156,7 @@ struct grub_xfs_data grub_disk_t disk; int pos; int bsize; - int agsize; + grub_uint32_t agsize; struct grub_fshelp_node diropen; }; @@ -168,33 +170,67 @@ static grub_dl_t my_mod; #define FILETYPE_INO_DIRECTORY 0040000 #define FILETYPE_INO_SYMLINK 0120000 -#define GRUB_XFS_INO_AGBITS(data) \ - ((data)->sblock.log2_agblk + (data)->sblock.log2_inop) -#define GRUB_XFS_INO_INOINAG(data, ino) \ - (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)) -#define GRUB_XFS_INO_AG(data,ino) \ - (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)) +static inline int +GRUB_XFS_INO_AGBITS(struct grub_xfs_data *data) +{ + return ((data)->sblock.log2_agblk + (data)->sblock.log2_inop); +} -#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \ - (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \ - + ((fsb) & ((1LL << (data)->sblock.log2_agblk) - 1))) +static inline grub_uint64_t +GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); +} -#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \ - ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \ - | grub_be_to_cpu32 (exts[ex][1]) >> 9) +static inline grub_uint64_t +GRUB_XFS_INO_AG (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)); +} -#define GRUB_XFS_EXTENT_BLOCK(exts,ex) \ - ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \ - & (0x1ff)) << 43 \ - | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \ - | grub_be_to_cpu32 (exts[ex][3]) >> 21) +static inline grub_disk_addr_t +GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb) +{ + return ((fsb >> data->sblock.log2_agblk) * data->agsize + + (fsb & ((1LL << data->sblock.log2_agblk) - 1))); +} -#define GRUB_XFS_EXTENT_SIZE(exts,ex) \ - (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1)) +static inline grub_uint64_t +GRUB_XFS_EXTENT_OFFSET (grub_xfs_extent *exts, int ex) +{ + return ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 + | grub_be_to_cpu32 (exts[ex][1]) >> 9); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_BLOCK (grub_xfs_extent *exts, int ex) +{ + return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) + & (0x1ff)) << 43 + | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 + | grub_be_to_cpu32 (exts[ex][3]) >> 21); +} + +static inline grub_uint64_t +GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *exts, int ex) +{ + return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1)); +} + +static inline int +GRUB_XFS_ROUND_TO_DIRENT (int pos) +{ + return ((((pos) + 8 - 1) / 8) * 8); +} + +static inline int +GRUB_XFS_NEXT_DIRENT (int pos, int len) +{ + return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2); +} -#define GRUB_XFS_ROUND_TO_DIRENT(pos) ((((pos) + 8 - 1) / 8) * 8) -#define GRUB_XFS_NEXT_DIRENT(pos,len) \ - (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2) static inline grub_uint64_t grub_xfs_inode_block (struct grub_xfs_data *data, @@ -250,13 +286,23 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) if (node->inode.format == XFS_INODE_FORMAT_BTREE) { grub_uint64_t *keys; + int recoffset; - leaf = grub_malloc (node->data->sblock.bsize); + leaf = grub_malloc (node->data->bsize); if (leaf == 0) return 0; nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); keys = &node->inode.data.btree.keys[0]; + if (node->inode.fork_offset) + recoffset = (node->inode.fork_offset + - ((char *) &node->inode.data.btree.keys - (char *) &node->inode)) + / (2 * sizeof (grub_uint64_t)); + else + recoffset = ((1 << node->data->sblock.log2_inode) + - ((char *) &node->inode.data.btree.keys + - (char *) &node->inode)) + / (2 * sizeof (grub_uint64_t)); do { int i; @@ -273,12 +319,9 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_free (leaf); return 0; } - if (grub_disk_read (node->data->disk, - grub_be_to_cpu64 (keys[i - 1 + nrec]) - << (node->data->sblock.log2_bsize - - GRUB_DISK_SECTOR_BITS), - 0, node->data->sblock.bsize, leaf)) + GRUB_XFS_FSB_TO_BLOCK (node->data, grub_be_to_cpu64 (keys[i - 1 + recoffset])) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), + 0, node->data->bsize, leaf)) return 0; if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) @@ -290,7 +333,11 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) nrec = grub_be_to_cpu16 (leaf->numrecs); keys = &leaf->keys[0]; - } while (leaf->level); + recoffset = ((node->data->bsize - ((char *) &leaf->keys + - (char *) leaf)) + / (2 * sizeof (grub_uint64_t))); + } + while (leaf->level); exts = (grub_xfs_extent *) keys; } else if (node->inode.format == XFS_INODE_FORMAT_EXT) @@ -336,7 +383,7 @@ static grub_ssize_t grub_xfs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_xfs_read_block, From 177b960ea44f146bb6b9e3c7be87bd3669b0d823 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 11:53:27 +0200 Subject: [PATCH 1244/1414] Fix python 3.x incompatibilities. * gentpl.py: Put brackets around print strings. * util/import_gcry.py: Open explicitly as utf-8. Use in instead of has_key. --- ChangeLog | 8 ++++++++ gentpl.py | 40 ++++++++++++++++++++-------------------- util/import_gcry.py | 28 +++++++++++++++------------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index abe19dc78..d5fbffcd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-16 Vladimir Serbinenko + + Fix python 3.x incompatibilities. + + * gentpl.py: Put brackets around print strings. + * util/import_gcry.py: Open explicitly as utf-8. + Use in instead of has_key. + 2011-10-16 Vladimir Serbinenko * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. diff --git a/gentpl.py b/gentpl.py index cb6b663d9..af210a040 100644 --- a/gentpl.py +++ b/gentpl.py @@ -568,28 +568,28 @@ f = script_rules() g = data_rules() z = global_variable_initializers() -print "[+ AutoGen5 template +]\n" +print ("[+ AutoGen5 template +]\n") for p in GRUB_PLATFORMS: - print define_macro_for_platform_sources(p) - print define_macro_for_platform_nodist_sources(p) + print (define_macro_for_platform_sources(p)) + print (define_macro_for_platform_nodist_sources(p)) # print define_macro_for_platform_dependencies(p) - print define_macro_for_platform_startup(p) - print define_macro_for_platform_cflags(p) - print define_macro_for_platform_ldadd(p) - print define_macro_for_platform_ldflags(p) - print define_macro_for_platform_cppflags(p) - print define_macro_for_platform_ccasflags(p) - print define_macro_for_platform_stripflags(p) - print define_macro_for_platform_objcopyflags(p) + print (define_macro_for_platform_startup(p)) + print (define_macro_for_platform_cflags(p)) + print (define_macro_for_platform_ldadd(p)) + print (define_macro_for_platform_ldflags(p)) + print (define_macro_for_platform_cppflags(p)) + print (define_macro_for_platform_ccasflags(p)) + print (define_macro_for_platform_stripflags(p)) + print (define_macro_for_platform_objcopyflags(p)) - print define_macro_for_platform_conditionals_if_statement(p) - print define_macro_for_platform_conditionals_endif_statement(p) + print (define_macro_for_platform_conditionals_if_statement(p)) + print (define_macro_for_platform_conditionals_endif_statement(p)) # print z # initializer for all vars -print a -print b -print c -print d -print e -print f -print g +print (a) +print (b) +print (c) +print (d) +print (e) +print (f) +print (g) diff --git a/util/import_gcry.py b/util/import_gcry.py index ee75b1b8e..720f19303 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -20,6 +20,7 @@ import re import sys import os import datetime +import codecs if len (sys.argv) < 3: print ("Usage: %s SOURCE DESTINATION" % sys.argv[0]) @@ -40,9 +41,9 @@ except: print ("WARNING: %s already exists" % cipher_dir_out) cipher_files = os.listdir (cipher_dir_in) -conf = open (os.path.join ("grub-core", "Makefile.gcry.def"), "w") +conf = codecs.open (os.path.join ("grub-core", "Makefile.gcry.def"), "w", "utf-8") conf.write ("AutoGen definitions Makefile.tpl;\n\n") -confutil = open ("Makefile.utilgcry.def", "w") +confutil = codecs.open ("Makefile.utilgcry.def", "w", "utf-8") confutil.write ("AutoGen definitions Makefile.tpl;\n\n") confutil.write ("library = {\n"); confutil.write (" name = libgrubgcry.a;\n"); @@ -69,7 +70,7 @@ mdblocksizes = {"_gcry_digest_spec_crc32" : 64, "_gcry_digest_spec_tiger" : 64, "_gcry_digest_spec_whirlpool" : 64} -cryptolist = open (os.path.join (cipher_dir_out, "crypto.lst"), "w") +cryptolist = codecs.open (os.path.join (cipher_dir_out, "crypto.lst"), "w", "utf-8") # rijndael is the only cipher using aliases. So no need for mangling, just # hardcode it @@ -98,8 +99,8 @@ for cipher_file in cipher_files: nch = False if re.match (".*\.[ch]$", cipher_file): isc = re.match (".*\.c$", cipher_file) - f = open (infile, "r") - fw = open (outfile, "w") + f = codecs.open (infile, "r", "utf-8") + fw = codecs.open (outfile, "w", "utf-8") fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n") fw.write ("#include \n") @@ -125,6 +126,7 @@ for cipher_file in cipher_files: isglue = True modname = "gcry_%s" % modname for line in f: + line = line if skip_statement: if not re.search (";", line) is None: skip_statement = False @@ -151,7 +153,7 @@ for cipher_file in cipher_files: fw.write (" .modname = \"%s\",\n" % modname); fw.write ("#endif\n"); if ismd: - if not mdblocksizes.has_key (mdname): + if not (mdname in mdblocksizes): print ("ERROR: Unknown digest blocksize: %s\n" % mdname) exit (1) @@ -324,28 +326,28 @@ cryptolist.close () chlog = "%s * crypto.lst: New file.\n" % chlog outfile = os.path.join (cipher_dir_out, "types.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") fw.write ("#include \n") chlog = "%s * types.h: New file.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "memory.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") chlog = "%s * memory.h: New file.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "cipher.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") fw.write ("#include \n") chlog = "%s * cipher.h: Likewise.\n" % chlog fw.close () outfile = os.path.join (cipher_dir_out, "g10lib.h") -fw=open (outfile, "w") +fw=codecs.open (outfile, "w", "utf-8") fw.write ("#include \n") chlog = "%s * g10lib.h: Likewise.\n" % chlog fw.close () @@ -355,7 +357,7 @@ outfile = os.path.join (cipher_dir_out, "ChangeLog") conf.close (); -initfile = open (os.path.join (cipher_dir_out, "init.c"), "w") +initfile = codecs.open (os.path.join (cipher_dir_out, "init.c"), "w", "utf-8") for module in modules: initfile.write ("extern void grub_%s_init (void);\n" % module) initfile.write ("extern void grub_%s_fini (void);\n" % module) @@ -380,8 +382,8 @@ confutil.write ("};\n"); confutil.close (); -f=open (infile, "r") -fw=open (outfile, "w") +f=codecs.open (infile, "r", "utf-8") +fw=codecs.open (outfile, "w", "utf-8") dt = datetime.date.today () fw.write ("%04d-%02d-%02d Automatic import tool\n" % \ (dt.year,dt.month, dt.day)) From 366e34fa5a49d022f3f01861c7d6ee6d7268a8a1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 11:57:48 +0200 Subject: [PATCH 1245/1414] Fix few obvious type discrepancies. * grub-core/fs/affs.c (grub_affs_read_file): Use grub_off_t for offset. * grub-core/fs/afs.c (grub_afs_read_file): Likewise. * grub-core/fs/fshelp.c (grub_fshelp_find_file): Remove leftover variable. * grub-core/fs/hfs.c (grub_hfs_read_file): Use grub_off_t for offset and connected types. * grub-core/fs/nilfs2.c (grub_nilfs2_read_file): Use grub_off_t for offset. (grub_nilfs2_iterate_dir): Use grub_off_t for fpos. * grub-core/fs/sfs.c (grub_sfs_read_file): Use grub_off_t for offset. * grub-core/fs/ufs.c (grub_ufs_read_file): Use grub_off_t for offset and connected types. --- ChangeLog | 17 +++++++++++++++++ grub-core/fs/affs.c | 2 +- grub-core/fs/afs.c | 2 +- grub-core/fs/fshelp.c | 1 - grub-core/fs/hfs.c | 24 +++++++++++++----------- grub-core/fs/nilfs2.c | 4 ++-- grub-core/fs/sfs.c | 2 +- grub-core/fs/ufs.c | 23 +++++++++++++---------- 8 files changed, 48 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5fbffcd4..2e44b4c26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-10-16 Vladimir Serbinenko + + Fix few obvious type discrepancies. + + * grub-core/fs/affs.c (grub_affs_read_file): Use grub_off_t for offset. + * grub-core/fs/afs.c (grub_afs_read_file): Likewise. + * grub-core/fs/fshelp.c (grub_fshelp_find_file): Remove leftover + variable. + * grub-core/fs/hfs.c (grub_hfs_read_file): Use grub_off_t for offset + and connected types. + * grub-core/fs/nilfs2.c (grub_nilfs2_read_file): Use grub_off_t for + offset. + (grub_nilfs2_iterate_dir): Use grub_off_t for fpos. + * grub-core/fs/sfs.c (grub_sfs_read_file): Use grub_off_t for offset. + * grub-core/fs/ufs.c (grub_ufs_read_file): Use grub_off_t for offset + and connected types. + 2011-10-16 Vladimir Serbinenko Fix python 3.x incompatibilities. diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index e17540e2f..adf2932bd 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -160,7 +160,7 @@ static grub_ssize_t grub_affs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_affs_read_block, diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index 35ef49937..b64ebb52c 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -336,7 +336,7 @@ static grub_ssize_t grub_afs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_afs_read_block, diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c index 2ff78c423..275cb9e1b 100644 --- a/grub-core/fs/fshelp.c +++ b/grub-core/fs/fshelp.c @@ -61,7 +61,6 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, char fpath[grub_strlen (currpath) + 1]; char *name = fpath; char *next; - // unsigned int pos = 0; enum grub_fshelp_filetype type = GRUB_FSHELP_DIR; grub_fshelp_node_t currnode = currroot; grub_fshelp_node_t oldnode = currroot; diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index 6f27c69c4..973a2d2ef 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -244,22 +244,24 @@ static grub_ssize_t grub_hfs_read_file (struct grub_hfs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { - int i; - int blockcnt; + grub_off_t i; + grub_off_t blockcnt; - blockcnt = ((len + pos) - + data->blksz - 1) / data->blksz; + blockcnt = grub_divmod64 (((len + pos) + + data->blksz - 1), data->blksz, 0); - for (i = pos / data->blksz; i < blockcnt; i++) + for (i = grub_divmod64 (pos, data->blksz, 0); i < blockcnt; i++) { - int blknr; - int blockoff = pos % data->blksz; - int blockend = data->blksz; + grub_disk_addr_t blknr; + grub_off_t blockoff; + grub_off_t blockend = data->blksz; int skipfirst = 0; + grub_divmod64 (pos, data->blksz, &blockoff); + blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1); if (grub_errno) return -1; @@ -267,7 +269,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % data->blksz; + grub_divmod64 ((len + pos), data->blksz, &blockend); /* The last portion is exactly EXT2_BLOCK_SIZE (data). */ if (! blockend) @@ -275,7 +277,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, } /* First block. */ - if (i == pos / data->blksz) + if (i == grub_divmod64 (pos, data->blksz, 0)) { skipfirst = blockoff; blockend -= skipfirst; diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 44fb213bd..62cf167c7 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -628,7 +628,7 @@ grub_nilfs2_read_file (grub_fshelp_node_t node, sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_nilfs2_read_block, @@ -866,7 +866,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, enum grub_fshelp_filetype filetype, grub_fshelp_node_t node)) { - unsigned int fpos = 0; + grub_off_t fpos = 0; struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; if (!diro->inode_read) diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 19ae90715..f1e09ccbd 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -250,7 +250,7 @@ static grub_ssize_t grub_sfs_read_file (grub_fshelp_node_t node, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_sfs_read_block, diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 0f4ea0019..435fec6a5 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -285,26 +285,29 @@ static grub_ssize_t grub_ufs_read_file (struct grub_ufs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - int pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { struct grub_ufs_sblock *sblock = &data->sblock; - int i; - int blockcnt; + grub_off_t i; + grub_off_t blockcnt; /* Adjust len so it we can't read past the end of the file. */ if (len + pos > INODE_SIZE (data)) len = INODE_SIZE (data) - pos; - blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock); + blockcnt = grub_divmod64 ((len + pos + UFS_BLKSZ (sblock) - 1), + UFS_BLKSZ (sblock), 0); - for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++) + for (i = grub_divmod64 (pos, UFS_BLKSZ (sblock), 0); i < blockcnt; i++) { - int blknr; - int blockoff = pos % UFS_BLKSZ (sblock); - int blockend = UFS_BLKSZ (sblock); + grub_disk_addr_t blknr; + grub_off_t blockoff; + grub_off_t blockend = UFS_BLKSZ (sblock); int skipfirst = 0; + grub_divmod64 (pos, UFS_BLKSZ (sblock), &blockoff); + blknr = grub_ufs_get_file_block (data, i); if (grub_errno) return -1; @@ -312,14 +315,14 @@ grub_ufs_read_file (struct grub_ufs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) % UFS_BLKSZ (sblock); + grub_divmod64 (len + pos, UFS_BLKSZ (sblock), &blockend); if (!blockend) blockend = UFS_BLKSZ (sblock); } /* First block. */ - if (i == (pos / (int) UFS_BLKSZ (sblock))) + if (i == grub_divmod64 (pos, UFS_BLKSZ (sblock), 0)) { skipfirst = blockoff; blockend -= skipfirst; From 2afb7f6cbf5ca5c49750c70b07f67d4733f66061 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 15:15:35 +0200 Subject: [PATCH 1246/1414] * configure.ac: Check for __ctzdi2 and __ctzsi2. * include/grub/libgcc.h: Include __ctzdi2 and __ctzsi2 if present. --- ChangeLog | 5 +++++ configure.ac | 2 +- include/grub/libgcc.h | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2e44b4c26..0592459c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-16 Vladimir Serbinenko + + * configure.ac: Check for __ctzdi2 and __ctzsi2. + * include/grub/libgcc.h: Include __ctzdi2 and __ctzsi2 if present. + 2011-10-16 Vladimir Serbinenko Fix few obvious type discrepancies. diff --git a/configure.ac b/configure.ac index 9cfbd2340..6aafdf13d 100644 --- a/configure.ac +++ b/configure.ac @@ -587,7 +587,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 __moddi3 __divdi3) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2) 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 19723fd23..7a433dc68 100644 --- a/include/grub/libgcc.h +++ b/include/grub/libgcc.h @@ -63,6 +63,12 @@ void EXPORT_FUNC (__divsi3) (void); # ifdef HAVE___MODSI3 void EXPORT_FUNC (__modsi3) (void); # endif +# ifdef HAVE___CTZDI2 +void EXPORT_FUNC (__ctzdi2) (void); +# endif +# ifdef HAVE___CTZSI2 +void EXPORT_FUNC (__ctzsi2) (void); +# endif #endif # ifdef HAVE___IA64_TRAMPOLINE From 39705fadd7ed2d4f78df6f48abc13150464a5698 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 16 Oct 2011 15:23:29 +0200 Subject: [PATCH 1247/1414] Replace grub_module_iterate with FOR_MODULES. * grub-core/disk/memdisk.c (GRUB_MOD_INIT): Switched to new interface. * grub-core/kern/efi/efi.c (grub_arch_modules_addr): Renamed to... (grub_efi_modules_addr): ...this. * grub-core/kern/efi/init.c (grub_modbase): New variable. (grub_efi_init): Set grub_modbase. * grub-core/kern/emu/main.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. * grub-core/kern/i386/coreboot/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/i386/pc/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/ieee1275/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/main.c (grub_module_iterate): Remove. (grub_modules_get_end): Use grub_modbase. (grub_load_modules): Use FOR_MODULES. (grub_load_config): Likewise. * grub-core/kern/mips/arc/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): Removed. (grub_modbase): New variable. (grub_machine_init): Set grub_modbase. * include/grub/efi/efi.h (grub_efi_modules_addr): New declaration. * include/grub/kernel.h (grub_arch_modules_addr): Removed. (grub_module_iterate): Likewise. (grub_modbase): New variable declaration. (FOR_MODULES): New macro. --- ChangeLog | 40 ++++++++++++++ grub-core/disk/memdisk.c | 34 +++++------- grub-core/kern/efi/efi.c | 2 +- grub-core/kern/efi/init.c | 3 + grub-core/kern/emu/main.c | 6 +- grub-core/kern/i386/coreboot/init.c | 19 +++---- grub-core/kern/i386/pc/init.c | 13 ++--- grub-core/kern/ieee1275/init.c | 11 ++-- grub-core/kern/main.c | 83 +++++++++------------------- grub-core/kern/mips/arc/init.c | 8 +-- grub-core/kern/mips/loongson/init.c | 6 +- grub-core/kern/mips/qemu_mips/init.c | 6 +- include/grub/efi/efi.h | 2 + include/grub/kernel.h | 10 +++- 14 files changed, 117 insertions(+), 126 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0592459c3..2ce132a14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2011-10-16 Vladimir Serbinenko + + Replace grub_module_iterate with FOR_MODULES. + + * grub-core/disk/memdisk.c (GRUB_MOD_INIT): Switched to new interface. + * grub-core/kern/efi/efi.c (grub_arch_modules_addr): Renamed to... + (grub_efi_modules_addr): ...this. + * grub-core/kern/efi/init.c (grub_modbase): New variable. + (grub_efi_init): Set grub_modbase. + * grub-core/kern/emu/main.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + * grub-core/kern/i386/coreboot/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/i386/pc/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/ieee1275/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/main.c (grub_module_iterate): Remove. + (grub_modules_get_end): Use grub_modbase. + (grub_load_modules): Use FOR_MODULES. + (grub_load_config): Likewise. + * grub-core/kern/mips/arc/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): + Removed. + (grub_modbase): New variable. + (grub_machine_init): Set grub_modbase. + * include/grub/efi/efi.h (grub_efi_modules_addr): New declaration. + * include/grub/kernel.h (grub_arch_modules_addr): Removed. + (grub_module_iterate): Likewise. + (grub_modbase): New variable declaration. + (FOR_MODULES): New macro. + 2011-10-16 Vladimir Serbinenko * configure.ac: Check for __ctzdi2 and __ctzsi2. diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index ed570c6a0..4de0971ae 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -86,30 +86,24 @@ static struct grub_disk_dev grub_memdisk_dev = GRUB_MOD_INIT(memdisk) { - auto int hook (struct grub_module_header *); - int hook (struct grub_module_header *header) - { - if (header->type == OBJ_TYPE_MEMDISK) - { - char *memdisk_orig_addr; - memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header); + struct grub_module_header *header; + FOR_MODULES (header) + if (header->type == OBJ_TYPE_MEMDISK) + { + char *memdisk_orig_addr; + memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header); - grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); + grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); - memdisk_size = header->size - sizeof (struct grub_module_header); - memdisk_addr = grub_malloc (memdisk_size); + memdisk_size = header->size - sizeof (struct grub_module_header); + memdisk_addr = grub_malloc (memdisk_size); - grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); - grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); + grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); + grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); - grub_disk_dev_register (&grub_memdisk_dev); - return 1; - } - - return 0; - } - - grub_module_iterate (hook); + grub_disk_dev_register (&grub_memdisk_dev); + break; + } } GRUB_MOD_FINI(memdisk) diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index d0994a940..e27dd1ad0 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -218,7 +218,7 @@ grub_get_rtc (void) /* Search the mods section from the PE32/PE32+ image. This code uses a PE32 header, but should work with PE32+ as well. */ grub_addr_t -grub_arch_modules_addr (void) +grub_efi_modules_addr (void) { grub_efi_loaded_image_t *image; struct grub_pe32_header *header; diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 4dfb06284..942ab0256 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -26,9 +26,12 @@ #include #include +grub_addr_t grub_modbase; + void grub_efi_init (void) { + grub_modbase = grub_efi_modules_addr (); /* First of all, initialize the console so that GRUB can display messages. */ grub_console_init (); diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 9a58acd9e..d5c09ad47 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -53,11 +53,7 @@ static char *root_dev = NULL, *dir = NULL; int grub_no_autoload; -grub_addr_t -grub_arch_modules_addr (void) -{ - return 0; -} +grub_addr_t grub_modbase = 0; void grub_reboot (void) diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index ebbea2523..b7510ff98 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -56,10 +56,18 @@ grub_exit (void) grub_cpu_idle (); } +#ifdef GRUB_MACHINE_QEMU +grub_addr_t grub_modbase; +#else +grub_addr_t grub_modbase = ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); +#endif + void grub_machine_init (void) { #ifdef GRUB_MACHINE_QEMU + grub_modbase = grub_core_entry_addr + grub_kernel_image_size; + grub_qemu_init_cirrus (); #endif /* Initialize the console as early as possible. */ @@ -118,14 +126,3 @@ grub_machine_fini (void) grub_vga_text_fini (); grub_stop_floppy (); } - -/* Return the end of the core image. */ -grub_addr_t -grub_arch_modules_addr (void) -{ -#ifdef GRUB_MACHINE_QEMU - return grub_core_entry_addr + grub_kernel_image_size; -#else - return ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); -#endif -} diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 24fe8fed9..62269de78 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -129,6 +129,8 @@ compact_mem_regions (void) } } +grub_addr_t grub_modbase; + void grub_machine_init (void) { @@ -137,6 +139,9 @@ grub_machine_init (void) int grub_lower_mem; #endif + grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); + /* Initialize the console as early as possible. */ grub_console_init (); @@ -206,11 +211,3 @@ grub_machine_fini (void) grub_console_fini (); grub_stop_floppy (); } - -/* Return the end of the core image. */ -grub_addr_t -grub_arch_modules_addr (void) -{ - return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR - + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -} diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 81b06c88e..76f932d09 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -256,9 +256,14 @@ grub_parse_cmdline (void) static grub_uint64_t ieee1275_get_time_ms (void); +grub_addr_t grub_modbase; + void grub_machine_init (void) { + grub_modbase = ALIGN_UP((grub_addr_t) _end + + GRUB_KERNEL_MACHINE_MOD_GAP, + GRUB_KERNEL_MACHINE_MOD_ALIGN); grub_ieee1275_init (); grub_console_init_early (); @@ -293,9 +298,3 @@ grub_get_rtc (void) { return ieee1275_get_time_ms (); } - -grub_addr_t -grub_arch_modules_addr (void) -{ - return ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); -} diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 0cec93d89..9e1971773 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -30,45 +30,20 @@ #include #include -void -grub_module_iterate (int (*hook) (struct grub_module_header *header)) -{ - struct grub_module_info *modinfo; - struct grub_module_header *header; - grub_addr_t modbase; - - modbase = grub_arch_modules_addr (); - modinfo = (struct grub_module_info *) modbase; - - /* Check if there are any modules. */ - if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) - return; - - for (header = (struct grub_module_header *) (modbase + modinfo->offset); - header < (struct grub_module_header *) (modbase + modinfo->size); - header = (struct grub_module_header *) ((char *) header + header->size)) - { - if (hook (header)) - break; - } -} - /* This is actualy platform-independant but used only on loongson and sparc. */ #if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) grub_addr_t grub_modules_get_end (void) { struct grub_module_info *modinfo; - grub_addr_t modbase; - modbase = grub_arch_modules_addr (); - modinfo = (struct grub_module_info *) modbase; + modinfo = (struct grub_module_info *) grub_modbase; /* Check if there are any modules. */ if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) - return modbase; + return grub_modbase; - return modbase + modinfo->size; + return grub_modbase + modinfo->size; } #endif @@ -76,42 +51,36 @@ grub_modules_get_end (void) static void grub_load_modules (void) { - auto int hook (struct grub_module_header *); - int hook (struct grub_module_header *header) - { - /* Not an ELF module, skip. */ - if (header->type != OBJ_TYPE_ELF) - return 0; + struct grub_module_header *header; + FOR_MODULES (header) + { + /* Not an ELF module, skip. */ + if (header->type != OBJ_TYPE_ELF) + continue; - if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), - (header->size - sizeof (struct grub_module_header)))) - grub_fatal ("%s", grub_errmsg); + if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), + (header->size - sizeof (struct grub_module_header)))) + grub_fatal ("%s", grub_errmsg); - if (grub_errno) - grub_print_error (); - - return 0; - } - - grub_module_iterate (hook); + if (grub_errno) + grub_print_error (); + } } static void grub_load_config (void) { - auto int hook (struct grub_module_header *); - int hook (struct grub_module_header *header) - { - /* Not an embedded config, skip. */ - if (header->type != OBJ_TYPE_CONFIG) - return 0; - - grub_parser_execute ((char *) header + - sizeof (struct grub_module_header)); - return 1; - } - - grub_module_iterate (hook); + struct grub_module_header *header; + FOR_MODULES (header) + { + /* Not an embedded config, skip. */ + if (header->type != OBJ_TYPE_CONFIG) + continue; + + grub_parser_execute ((char *) header + + sizeof (struct grub_module_header)); + break; + } } /* Write hook for the environment variables of root. Remove surrounding diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 514b481f6..2e25335ca 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -125,12 +125,14 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) } extern grub_uint32_t grub_total_modules_size; +grub_addr_t grub_modbase; void grub_machine_init (void) { struct grub_arc_memory_descriptor *cur = NULL; + grub_modbase = GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size; grub_console_init_early (); /* FIXME: measure this. */ @@ -164,12 +166,6 @@ 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/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 2d1a0653e..8acfb0767 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -298,9 +298,5 @@ grub_reboot (void) } extern char _end[]; +grub_addr_t grub_modbase = (grub_addr_t) _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 db9cc796a..4921c42bf 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -113,9 +113,5 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) } extern char _end[]; +grub_addr_t grub_modbase = (grub_addr_t) _end; -grub_addr_t -grub_arch_modules_addr (void) -{ - return (grub_addr_t) _end; -} diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index e98f99507..7ecda58ab 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -70,6 +70,8 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, char **device, char **path); +grub_addr_t grub_efi_modules_addr (void); + void grub_efi_mm_init (void); void grub_efi_mm_fini (void); void grub_efi_init (void); diff --git a/include/grub/kernel.h b/include/grub/kernel.h index aef585668..d8c0fed33 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -68,9 +68,15 @@ struct grub_module_info64 #define grub_module_info grub_module_info32 #endif -extern grub_addr_t grub_arch_modules_addr (void); +extern grub_addr_t EXPORT_VAR (grub_modbase); -extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); +#define FOR_MODULES(var) for (\ + var = grub_modbase ? (struct grub_module_header *) \ + (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ + var && (grub_addr_t) var \ + < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ + var = (struct grub_module_header *) \ + ((char *) var + ((struct grub_module_header *) var)->size)) grub_addr_t grub_modules_get_end (void); From a97501d2389d524323293395636b43aec73f1761 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 Oct 2011 15:21:51 +0200 Subject: [PATCH 1248/1414] Make grub_prefix into module to fix the arbitrary limit and save some space. * grub-core/kern/emu/main.c (grub_prefix): Removed. * grub-core/kern/i386/coreboot/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/efi/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/ieee1275/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/pc/startup.S (grub_prefix): Likewise. * grub-core/kern/i386/qemu/startup.S (grub_prefix): Likewise. * grub-core/kern/ia64/efi/startup.S (grub_prefix): Likewise. * grub-core/kern/mips/startup.S (grub_prefix): Likewise. * grub-core/kern/powerpc/ieee1275/startup.S (grub_prefix): Likewise. * grub-core/kern/sparc64/ieee1275/crt0.S (grub_prefix): Likewise. * grub-core/kern/x86_64/efi/startup.S (grub_prefix): Likewise. * include/grub/ia64/efi/kernel.h: Removed. * include/grub/kernel.h: New module type OBJ_TYPE_PREFIX. (grub_prefix): Removed. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_PREFIX): Removed. (GRUB_KERNEL_I386_PC_PREFIX_END): Likewise. (GRUB_KERNEL_I386_QEMU_PREFIX): Likewise. (GRUB_KERNEL_I386_QEMU_PREFIX_END): Likewise. (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX): Likewise. (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END): Likewise. (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX): Likewise. (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END): Likewise. (GRUB_KERNEL_MIPS_LOONGSON_PREFIX): Likewise. (GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END): Likewise. (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise. (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise. (GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise. (GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise. (GRUB_KERNEL_I386_EFI_PREFIX): Likewise. (GRUB_KERNEL_I386_EFI_PREFIX_END): Likewise. (GRUB_KERNEL_IA64_EFI_PREFIX): Likewise. (GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise. (GRUB_KERNEL_X86_64_EFI_PREFIX): Likewise. (GRUB_KERNEL_X86_64_EFI_PREFIX_END): Likewise. (GRUB_KERNEL_I386_COREBOOT_PREFIX): Likewise. (GRUB_KERNEL_I386_COREBOOT_PREFIX_END): Likewise. (GRUB_KERNEL_I386_MULTIBOOT_PREFIX): Likewise. (GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END): Likewise. (GRUB_KERNEL_I386_IEEE1275_PREFIX): Likewise. (GRUB_KERNEL_I386_IEEE1275_PREFIX_END): Likewise. (GRUB_KERNEL_MACHINE_PREFIX): Likewise. (GRUB_KERNEL_MACHINE_PREFIX_END): Likewise. * grub-core/kern/main.c (grub_set_prefix_and_root): Retrieve grub_prefix from module. * util/grub-mkimage.c (image_target_desc): Removed prefix and prefix_end. (image_targets): Likewise. (generate_image): Put prefix as a module. --- ChangeLog | 54 ++++++++++++++++++ grub-core/kern/emu/main.c | 2 - grub-core/kern/i386/coreboot/startup.S | 15 ----- grub-core/kern/i386/efi/startup.S | 11 ---- grub-core/kern/i386/ieee1275/startup.S | 18 ------ grub-core/kern/i386/pc/startup.S | 11 ---- grub-core/kern/i386/qemu/startup.S | 8 --- grub-core/kern/ia64/efi/startup.S | 10 ---- grub-core/kern/main.c | 49 +++++++++------- grub-core/kern/mips/startup.S | 11 ---- grub-core/kern/powerpc/ieee1275/startup.S | 14 ----- grub-core/kern/sparc64/ieee1275/crt0.S | 8 --- grub-core/kern/x86_64/efi/startup.S | 15 ----- include/grub/ia64/efi/kernel.h | 34 ------------ include/grub/kernel.h | 8 +-- include/grub/offsets.h | 53 ------------------ util/grub-mkimage.c | 68 ++++++++--------------- 17 files changed, 106 insertions(+), 283 deletions(-) delete mode 100644 include/grub/ia64/efi/kernel.h diff --git a/ChangeLog b/ChangeLog index 2ce132a14..a758fc275 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +2011-10-18 Vladimir Serbinenko + + Make grub_prefix into module to fix the arbitrary limit and save + some space. + + * grub-core/kern/emu/main.c (grub_prefix): Removed. + * grub-core/kern/i386/coreboot/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/efi/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/ieee1275/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/pc/startup.S (grub_prefix): Likewise. + * grub-core/kern/i386/qemu/startup.S (grub_prefix): Likewise. + * grub-core/kern/ia64/efi/startup.S (grub_prefix): Likewise. + * grub-core/kern/mips/startup.S (grub_prefix): Likewise. + * grub-core/kern/powerpc/ieee1275/startup.S (grub_prefix): Likewise. + * grub-core/kern/sparc64/ieee1275/crt0.S (grub_prefix): Likewise. + * grub-core/kern/x86_64/efi/startup.S (grub_prefix): Likewise. + * include/grub/ia64/efi/kernel.h: Removed. + * include/grub/kernel.h: New module type OBJ_TYPE_PREFIX. + (grub_prefix): Removed. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_PREFIX): Removed. + (GRUB_KERNEL_I386_PC_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_QEMU_PREFIX): Likewise. + (GRUB_KERNEL_I386_QEMU_PREFIX_END): Likewise. + (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX): Likewise. + (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END): Likewise. + (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX): Likewise. + (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END): Likewise. + (GRUB_KERNEL_MIPS_LOONGSON_PREFIX): Likewise. + (GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END): Likewise. + (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise. + (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise. + (GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise. + (GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_EFI_PREFIX): Likewise. + (GRUB_KERNEL_I386_EFI_PREFIX_END): Likewise. + (GRUB_KERNEL_IA64_EFI_PREFIX): Likewise. + (GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise. + (GRUB_KERNEL_X86_64_EFI_PREFIX): Likewise. + (GRUB_KERNEL_X86_64_EFI_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_COREBOOT_PREFIX): Likewise. + (GRUB_KERNEL_I386_COREBOOT_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_MULTIBOOT_PREFIX): Likewise. + (GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END): Likewise. + (GRUB_KERNEL_I386_IEEE1275_PREFIX): Likewise. + (GRUB_KERNEL_I386_IEEE1275_PREFIX_END): Likewise. + (GRUB_KERNEL_MACHINE_PREFIX): Likewise. + (GRUB_KERNEL_MACHINE_PREFIX_END): Likewise. + * grub-core/kern/main.c (grub_set_prefix_and_root): Retrieve grub_prefix + from module. + * util/grub-mkimage.c (image_target_desc): Removed prefix and + prefix_end. + (image_targets): Likewise. + (generate_image): Put prefix as a module. + 2011-10-16 Vladimir Serbinenko Replace grub_module_iterate with FOR_MODULES. diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index d5c09ad47..8d15f17c5 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -79,8 +79,6 @@ grub_machine_fini (void) grub_console_fini (); } -char grub_prefix[64] = ""; - static struct option options[] = diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index 07c5437c0..5e7767bb9 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -40,21 +40,6 @@ start: _start: jmp codestart - /* - * This is a special data area at a fixed offset from the beginning. - */ - - . = _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 - /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). */ diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S index 5b464ab83..49b05c1e6 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/grub-core/kern/i386/efi/startup.S @@ -41,17 +41,6 @@ _start: * This is a special data area 8 bytes from the beginning. */ - . = _start + 0x8 - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + 0x50 - codestart: /* * EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack. diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 82087323b..6b39f5f3a 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -36,24 +36,6 @@ start: _start: - jmp codestart - - /* - * This is a special data area at a fixed offset from the beginning. - */ - - . = _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 - -codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) jmp EXT_C(grub_main) diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 0fe114add..3bbe34753 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -455,17 +455,6 @@ gate_a20_check_state: */ . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE - . = _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 - - - /* * grub_exit() * diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 7834d1df5..6500de620 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -34,14 +34,6 @@ VARIABLE(grub_core_entry_addr) .long 0 VARIABLE(grub_kernel_image_size) .long 0 -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Relocate to low memory. First we figure out our location. diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S index b5e26a204..d75c6d7cc 100644 --- a/grub-core/kern/ia64/efi/startup.S +++ b/grub-core/kern/ia64/efi/startup.S @@ -42,13 +42,3 @@ _start: br.ret.sptk.few rp .endp _start - - . = _start + GRUB_KERNEL_MACHINE_PREFIX -VARIABLE(grub_prefix) - .byte 0 - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - . = _start + GRUB_KERNEL_MACHINE_PREFIX_END diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 9e1971773..77be11422 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -105,25 +105,32 @@ grub_set_prefix_and_root (void) char *path = NULL; char *fwdevice = NULL; char *fwpath = NULL; + char *prefix; + struct grub_module_header *header; + + FOR_MODULES (header) + if (header->type == OBJ_TYPE_PREFIX) + prefix = (char *) header + sizeof (struct grub_module_header); grub_register_variable_hook ("root", 0, grub_env_write_root); - { - char *pptr = NULL; - if (grub_prefix[0] == '(') - { - pptr = grub_strrchr (grub_prefix, ')'); - if (pptr) - { - device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); - pptr++; - } - } - if (!pptr) - pptr = grub_prefix; - if (pptr[0]) - path = grub_strdup (pptr); - } + if (prefix) + { + char *pptr = NULL; + if (prefix[0] == '(') + { + pptr = grub_strrchr (prefix, ')'); + if (pptr) + { + device = grub_strndup (prefix + 1, pptr - prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } if ((!device || device[0] == ',' || !device[0]) || !path) grub_machine_get_bootlocation (&fwdevice, &fwpath); @@ -152,13 +159,13 @@ grub_set_prefix_and_root (void) path = fwpath; if (device) { - char *prefix; + char *prefix_set; - prefix = grub_xasprintf ("(%s)%s", device, path ? : ""); - if (prefix) + prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); + if (prefix_set) { - grub_env_set ("prefix", prefix); - grub_free (prefix); + grub_env_set ("prefix", prefix_set); + grub_free (prefix_set); } grub_env_set ("root", device); } diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index da6450237..2476038bc 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -40,17 +40,6 @@ start: VARIABLE(grub_total_modules_size) .long 0 - . = _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 VARIABLE (grub_arch_busclock) .long 0 VARIABLE (grub_arch_cpuclock) diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S index 0b1c23346..b26c47edb 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/grub-core/kern/powerpc/ieee1275/startup.S @@ -28,20 +28,6 @@ .globl start, _start start: _start: - b codestart - - . = _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 - -codestart: li 2, 0 li 13, 0 diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index cebdca2b6..1466a56f8 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -35,14 +35,6 @@ VARIABLE(grub_kernel_image_size) .word 0 VARIABLE(grub_compressed_size) .word 0 -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = EXT_C(_start) + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Copy the modules past the end of the kernel image. diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index fb4fc7b64..37efde7fc 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -39,21 +39,6 @@ _start: . = _start + 0x6 .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - /* - * This is a special data area 8 bytes from the beginning. - */ - - . = _start + 0x8 - -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + 0x50 - codestart: movq %rcx, EXT_C(grub_efi_image_handle)(%rip) movq %rdx, EXT_C(grub_efi_system_table)(%rip) diff --git a/include/grub/ia64/efi/kernel.h b/include/grub/ia64/efi/kernel.h deleted file mode 100644 index ae75380f0..000000000 --- a/include/grub/ia64/efi/kernel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * 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 - * 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 offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - -#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/kernel.h b/include/grub/kernel.h index d8c0fed33..2ff6b2469 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -26,7 +26,8 @@ enum { OBJ_TYPE_ELF, OBJ_TYPE_MEMDISK, - OBJ_TYPE_CONFIG + OBJ_TYPE_CONFIG, + OBJ_TYPE_PREFIX }; /* The module header. */ @@ -98,9 +99,4 @@ void grub_register_exported_symbols (void); extern void (*EXPORT_VAR(grub_net_poll_cards_idle)) (void); - -#if ! defined (ASM_FILE) -extern char grub_prefix[]; -#endif - #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index e8170fcbe..526cfee68 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -42,12 +42,6 @@ #define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x730 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE - -/* End of the data section. */ -#define GRUB_KERNEL_I386_PC_PREFIX_END (GRUB_KERNEL_I386_PC_PREFIX + 0x40) - /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 @@ -66,12 +60,6 @@ /* The offset of GRUB_KERNEL_IMAGE_SIZE. */ #define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 - -/* End of the data section. */ -#define GRUB_KERNEL_I386_QEMU_PREFIX_END 0x50 - #define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 /* The offset of GRUB_TOTAL_MODULE_SIZE. */ @@ -83,20 +71,12 @@ /* The offset of GRUB_COMPRESSED_SIZE. */ #define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 - -/* End of the data section. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END 0x114 - #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 #define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 -#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 -#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 @@ -109,8 +89,6 @@ #define GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_MIPS_LOONGSON_PREFIX 0x0c -#define GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END 0x54 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR 0x80200000 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN 32 @@ -118,8 +96,6 @@ #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 0x8bd00000 @@ -130,36 +106,9 @@ #define GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 #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 - -/* 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 - -/* End of the data section. */ -#define GRUB_KERNEL_X86_64_EFI_PREFIX_END 0x50 - -#define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 -#define GRUB_KERNEL_I386_COREBOOT_PREFIX_END 0x42 #define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 -#define GRUB_KERNEL_I386_MULTIBOOT_PREFIX GRUB_KERNEL_I386_COREBOOT_PREFIX -#define GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END GRUB_KERNEL_I386_COREBOOT_PREFIX_END - -#define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 -#define GRUB_KERNEL_I386_IEEE1275_PREFIX_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 #define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 @@ -194,8 +143,6 @@ #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) #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) #define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _RAW_SIZE) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 420690923..4440fdd12 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -77,8 +77,6 @@ struct image_target_desc PLATFORM_FLAGS_DECOMPRESSORS = 2, PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4, } flags; - unsigned prefix; - unsigned prefix_end; unsigned raw_size; unsigned total_module_size; unsigned kernel_image_size; @@ -110,8 +108,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, - .prefix_end = GRUB_KERNEL_I386_COREBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -133,8 +129,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_MULTIBOOT_PREFIX, - .prefix_end = GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -156,8 +150,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_PC, .flags = PLATFORM_FLAGS_LZMA, - .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -175,8 +167,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_PC_PXE, .flags = PLATFORM_FLAGS_LZMA, - .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -194,8 +184,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_EFI_PREFIX, - .prefix_end = GRUB_KERNEL_I386_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -219,8 +207,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_I386_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -242,8 +228,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, - .prefix_end = GRUB_KERNEL_I386_QEMU_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, @@ -261,8 +245,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, - .prefix_end = GRUB_KERNEL_X86_64_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -281,8 +263,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -303,8 +283,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -327,8 +305,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .prefix = GRUB_KERNEL_MIPS_LOONGSON_PREFIX, - .prefix_end = GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END, .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -349,8 +325,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -372,8 +346,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_RAW, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -391,8 +363,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_AOUT, .flags = PLATFORM_FLAGS_NONE, - .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -410,8 +380,6 @@ struct image_target_desc image_targets[] = .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, @@ -431,8 +399,6 @@ struct image_target_desc image_targets[] = .id = IMAGE_MIPS_ARC, .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, .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, .compressed_size = TARGET_NO_FIELD, @@ -453,8 +419,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .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, @@ -475,8 +439,6 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_QEMU_MIPS_FLASH, .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, @@ -497,8 +459,6 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU_MIPS_FLASH, .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, @@ -519,8 +479,6 @@ struct image_target_desc image_targets[] = .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, @@ -797,6 +755,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; size_t memdisk_size = 0, config_size = 0, config_size_pure = 0; + size_t prefix_size = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; @@ -833,6 +792,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size += config_size + sizeof (struct grub_module_header); } + if (prefix) + { + prefix_size = ALIGN_ADDR (strlen (prefix) + 1); + total_module_size += prefix_size + sizeof (struct grub_module_header); + } + for (p = path_list; p; p = p->next) total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + sizeof (struct grub_module_header)); @@ -848,10 +813,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size, &start_address, &rel_section, &reloc_size, &align, image_target); - if (image_target->prefix + strlen (prefix) + 1 > image_target->prefix_end) - 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)) @@ -943,6 +904,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], offset += config_size; } + if (prefix) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX); + header->size = grub_host_to_target32 (prefix_size + sizeof (*header)); + offset += sizeof (*header); + + grub_memset (kernel_img + offset, 0, prefix_size); + grub_strcpy (kernel_img + offset, prefix); + offset += prefix_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); From 544c24876e2f20e217c615e10cb802aa1d8295be Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 16:53:18 +0200 Subject: [PATCH 1249/1414] Move grub_reboot out of the kernel. * grub-core/Makefile.core.def (reboot): Add platform-specific files. * grub-core/kern/efi/efi.c (grub_reboot): Moved to ... * grub-core/lib/efi/reboot.c: ... here. * grub-core/kern/i386/efi/startup.S: Remove including of realmode.S. * grub-core/kern/i386/ieee1275/startup.S: Likewise. * grub-core/kern/i386/pc/startup.S (grub_exit): Inline cold_reboot. * grub-core/kern/i386/realmode.S (grub_reboot): Moved to... * grub-core/lib/i386/reboot_trampoline.S: ... here. * grub-core/kern/ieee1275/openfw.c (grub_reboot): Moved to... * grub-core/lib/ieee1275/reboot.c: ... here. * grub-core/kern/mips/arc/init.c (grub_reboot): Moved to... * grub-core/lib/mips/arc/reboot.c: ... here. * grub-core/kern/mips/loongson/init.c (grub_reboot): Moved to... * grub-core/lib/mips/loongson/reboot.c: ...here. * grub-core/kern/mips/qemu_mips/init.c (grub_reboot): Moved to... * grub-core/lib/mips/qemu_mips/reboot.c: ... here. * include/grub/emu/misc.h (grub_reboot): New function declaration. * include/grub/i386/reboot.h: New file. * include/grub/mips/loongson/ec.h: Fix includes. * include/grub/mips/qemu_mips/kernel.h (grub_reboot): Removed. * include/grub/misc.h (grub_reboot): Don't mark as kernel function. * grub-core/lib/i386/reboot.c: New file. --- ChangeLog | 27 ++++++++++++ grub-core/Makefile.core.def | 19 ++++++--- grub-core/kern/efi/efi.c | 12 ------ grub-core/kern/i386/efi/startup.S | 2 - grub-core/kern/i386/ieee1275/startup.S | 6 --- grub-core/kern/i386/pc/startup.S | 5 ++- grub-core/kern/i386/realmode.S | 15 ------- grub-core/kern/ieee1275/openfw.c | 10 ----- grub-core/kern/mips/arc/init.c | 12 ------ grub-core/kern/mips/loongson/init.c | 32 -------------- grub-core/kern/mips/qemu_mips/init.c | 6 --- grub-core/lib/efi/reboot.c | 32 ++++++++++++++ grub-core/lib/i386/reboot.c | 59 ++++++++++++++++++++++++++ grub-core/lib/i386/reboot_trampoline.S | 33 ++++++++++++++ grub-core/lib/ieee1275/reboot.c | 27 ++++++++++++ grub-core/lib/mips/arc/reboot.c | 34 +++++++++++++++ grub-core/lib/mips/loongson/reboot.c | 57 +++++++++++++++++++++++++ grub-core/lib/mips/qemu_mips/reboot.c | 25 +++++++++++ include/grub/emu/misc.h | 3 ++ include/grub/i386/reboot.h | 28 ++++++++++++ include/grub/mips/loongson/ec.h | 4 ++ include/grub/mips/qemu_mips/kernel.h | 1 - include/grub/misc.h | 2 +- 23 files changed, 348 insertions(+), 103 deletions(-) create mode 100644 grub-core/lib/efi/reboot.c create mode 100644 grub-core/lib/i386/reboot.c create mode 100644 grub-core/lib/i386/reboot_trampoline.S create mode 100644 grub-core/lib/ieee1275/reboot.c create mode 100644 grub-core/lib/mips/arc/reboot.c create mode 100644 grub-core/lib/mips/loongson/reboot.c create mode 100644 grub-core/lib/mips/qemu_mips/reboot.c create mode 100644 include/grub/i386/reboot.h diff --git a/ChangeLog b/ChangeLog index a758fc275..9bea2dc0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2011-10-19 Vladimir Serbinenko + + Move grub_reboot out of the kernel. + + * grub-core/Makefile.core.def (reboot): Add platform-specific files. + * grub-core/kern/efi/efi.c (grub_reboot): Moved to ... + * grub-core/lib/efi/reboot.c: ... here. + * grub-core/kern/i386/efi/startup.S: Remove including of realmode.S. + * grub-core/kern/i386/ieee1275/startup.S: Likewise. + * grub-core/kern/i386/pc/startup.S (grub_exit): Inline cold_reboot. + * grub-core/kern/i386/realmode.S (grub_reboot): Moved to... + * grub-core/lib/i386/reboot_trampoline.S: ... here. + * grub-core/kern/ieee1275/openfw.c (grub_reboot): Moved to... + * grub-core/lib/ieee1275/reboot.c: ... here. + * grub-core/kern/mips/arc/init.c (grub_reboot): Moved to... + * grub-core/lib/mips/arc/reboot.c: ... here. + * grub-core/kern/mips/loongson/init.c (grub_reboot): Moved to... + * grub-core/lib/mips/loongson/reboot.c: ...here. + * grub-core/kern/mips/qemu_mips/init.c (grub_reboot): Moved to... + * grub-core/lib/mips/qemu_mips/reboot.c: ... here. + * include/grub/emu/misc.h (grub_reboot): New function declaration. + * include/grub/i386/reboot.h: New file. + * include/grub/mips/loongson/ec.h: Fix includes. + * include/grub/mips/qemu_mips/kernel.h (grub_reboot): Removed. + * include/grub/misc.h (grub_reboot): Don't mark as kernel function. + * grub-core/lib/i386/reboot.c: New file. + 2011-10-18 Vladimir Serbinenko Make grub_prefix into module to fix the arbitrary limit and save diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 84739e8fa..396f73b44 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -633,6 +633,20 @@ module = { emu = lib/emu/halt.c; }; +module = { + name = reboot; + i386 = lib/i386/reboot.c; + i386 = lib/i386/reboot_trampoline.S; + ia64_efi = lib/efi/reboot.c; + x86_64_efi = lib/efi/reboot.c; + powerpc_ieee1275 = lib/ieee1275/reboot.c; + sparc64_ieee1275 = lib/ieee1275/reboot.c; + mips_arc = lib/mips/arc/reboot.c; + mips_loongson = lib/mips/loongson/reboot.c; + mips_qemu_mips = lib/mips/qemu_mips/reboot.c; + common = commands/reboot.c; +}; + module = { name = hashsum; common = commands/hashsum.c; @@ -733,11 +747,6 @@ module = { common = commands/read.c; }; -module = { - name = reboot; - common = commands/reboot.c; -}; - module = { name = search; common = commands/search_wrap.c; diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index e27dd1ad0..9a2c5e64d 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -163,18 +163,6 @@ grub_exit (void) for (;;) ; } -/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */ -#ifndef __i386__ -void -grub_reboot (void) -{ - grub_efi_fini (); - efi_call_4 (grub_efi_system_table->runtime_services->reset_system, - GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); - for (;;) ; -} -#endif - grub_err_t grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, grub_efi_uintn_t descriptor_size, diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S index 49b05c1e6..0f904d7b3 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/grub-core/kern/i386/efi/startup.S @@ -51,5 +51,3 @@ codestart: movl %eax, EXT_C(grub_efi_system_table) call EXT_C(grub_main) ret - -#include "../realmode.S" diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 6b39f5f3a..245583bdb 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -39,9 +39,3 @@ _start: movl %eax, EXT_C(grub_ieee1275_entry_fn) jmp EXT_C(grub_main) -/* - * prot_to_real and associated structures (but NOT real_to_prot, that is - * only needed for BIOS gates). - */ -#include "../realmode.S" - diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 3bbe34753..a70a2a7db 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -465,7 +465,10 @@ FUNCTION(grub_exit) .code16 /* Tell the BIOS a boot failure. If this does not work, reboot. */ int $0x18 - jmp cold_reboot + /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xf000, $0xfff0 .code32 /* diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 578c8d2a8..3e8a13892 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -225,18 +225,3 @@ realcseg: DATA32 ret .code32 - -/* - * grub_reboot() - * - * Reboot the system. At the moment, rely on BIOS. - */ -FUNCTION(grub_reboot) - call prot_to_real - .code16 -cold_reboot: - /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ - movw $0x0472, %di - movw %ax, (%di) - ljmp $0xf000, $0xfff0 - .code32 diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 4e705a4d8..23065e3e3 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -456,16 +456,6 @@ grub_ieee1275_encode_devname (const char *path) return encoding; } -/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */ -#ifndef __i386__ -void -grub_reboot (void) -{ - grub_ieee1275_interpret ("reset-all", 0); - for (;;) ; -} -#endif - /* Resolve aliases. */ char * grub_ieee1275_canonicalise_devname (const char *path) diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 2e25335ca..ec0fa521a 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -195,15 +195,3 @@ grub_exit (void) 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/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 8acfb0767..6ddf151f2 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -30,7 +30,6 @@ #include #include #include -#include #include extern void grub_video_sm712_init (void); @@ -266,37 +265,6 @@ grub_exit (void) grub_halt (); } -void -grub_reboot (void) -{ - switch (grub_arch_machine) - { - case GRUB_ARCH_MACHINE_FULOONG2E: - grub_outb (grub_inb (0xbfe00104) & ~4, 0xbfe00104); - grub_outb (grub_inb (0xbfe00104) | 4, 0xbfe00104); - break; - case GRUB_ARCH_MACHINE_FULOONG2F: - { - grub_pci_device_t dev; - if (!grub_cs5536_find (&dev)) - break; - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET, - grub_cs5536_read_msr (dev, - GRUB_CS5536_MSR_DIVIL_RESET) - | 1); - break; - } - case GRUB_ARCH_MACHINE_YEELOONG: - grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); - break; - } - grub_millisleep (1500); - - grub_printf ("Reboot failed\n"); - grub_refresh (); - while (1); -} - extern char _end[]; grub_addr_t grub_modbase = (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 4921c42bf..d331e1b24 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -99,12 +99,6 @@ grub_halt (void) while (1); } -void -grub_reboot (void) -{ - while (1); -} - grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook) { diff --git a/grub-core/lib/efi/reboot.c b/grub-core/lib/efi/reboot.c new file mode 100644 index 000000000..9382370f7 --- /dev/null +++ b/grub-core/lib/efi/reboot.c @@ -0,0 +1,32 @@ +/* + * 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 + +void +grub_reboot (void) +{ + grub_machine_fini (); + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); + for (;;) ; +} diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c new file mode 100644 index 000000000..ef28f7f65 --- /dev/null +++ b/grub-core/lib/i386/reboot.c @@ -0,0 +1,59 @@ +/* + * 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 +#include + +void +grub_reboot (void) +{ + struct grub_relocator *relocator = NULL; + grub_relocator_chunk_t ch; + grub_err_t err; + void *buf; + struct grub_relocator16_state state; + grub_uint16_t segment; + + relocator = grub_relocator_new (); + if (!relocator) + while (1); + err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000, + grub_reboot_end - grub_reboot_start, + 16, GRUB_RELOCATOR_PREFERENCE_NONE); + if (err) + while (1); + buf = get_virtual_current_address (ch); + grub_memcpy (buf, grub_reboot_start, grub_reboot_end - grub_reboot_start); + + segment = ((grub_addr_t) get_physical_target_address (ch)) >> 4; + state.gs = state.fs = state.es = state.ds = state.ss = segment; + state.sp = 0; + state.cs = segment; + state.ip = 0; + + grub_stop_floppy (); + + err = grub_relocator16_boot (relocator, state); + + while (1); +} + diff --git a/grub-core/lib/i386/reboot_trampoline.S b/grub-core/lib/i386/reboot_trampoline.S new file mode 100644 index 000000000..18bcfb287 --- /dev/null +++ b/grub-core/lib/i386/reboot_trampoline.S @@ -0,0 +1,33 @@ +/* + * 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 + + .p2align 4 + +VARIABLE(grub_reboot_start) + .code16 + + /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xf000, $0xfff0 + + .code32 +VARIABLE(grub_reboot_end) diff --git a/grub-core/lib/ieee1275/reboot.c b/grub-core/lib/ieee1275/reboot.c new file mode 100644 index 000000000..91c8779f2 --- /dev/null +++ b/grub-core/lib/ieee1275/reboot.c @@ -0,0 +1,27 @@ +/* + * 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 + +void +grub_reboot (void) +{ + grub_ieee1275_interpret ("reset-all", 0); + for (;;) ; +} diff --git a/grub-core/lib/mips/arc/reboot.c b/grub-core/lib/mips/arc/reboot.c new file mode 100644 index 000000000..f0d085765 --- /dev/null +++ b/grub-core/lib/mips/arc/reboot.c @@ -0,0 +1,34 @@ +/* + * 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 + +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/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c new file mode 100644 index 000000000..f099ba250 --- /dev/null +++ b/grub-core/lib/mips/loongson/reboot.c @@ -0,0 +1,57 @@ +/* + * 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 +#include +#include +#include + +void +grub_reboot (void) +{ + switch (grub_arch_machine) + { + case GRUB_ARCH_MACHINE_FULOONG2E: + grub_outb (grub_inb (0xbfe00104) & ~4, 0xbfe00104); + grub_outb (grub_inb (0xbfe00104) | 4, 0xbfe00104); + break; + case GRUB_ARCH_MACHINE_FULOONG2F: + { + grub_pci_device_t dev; + if (!grub_cs5536_find (&dev)) + break; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET, + grub_cs5536_read_msr (dev, + GRUB_CS5536_MSR_DIVIL_RESET) + | 1); + break; + } + case GRUB_ARCH_MACHINE_YEELOONG: + grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); + break; + } + grub_millisleep (1500); + + grub_printf ("Reboot failed\n"); + grub_refresh (); + while (1); +} diff --git a/grub-core/lib/mips/qemu_mips/reboot.c b/grub-core/lib/mips/qemu_mips/reboot.c new file mode 100644 index 000000000..a5c41ee78 --- /dev/null +++ b/grub-core/lib/mips/qemu_mips/reboot.c @@ -0,0 +1,25 @@ +/* + * 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 + +void +grub_reboot (void) +{ + while (1); +} diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index fcf9da473..b4b8f7d28 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -82,4 +82,7 @@ int grub_device_mapper_supported (void); char *grub_find_root_device_from_mountinfo (const char *dir, char **relroot); +void EXPORT_FUNC(grub_reboot) (void); + + #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/i386/reboot.h b/include/grub/i386/reboot.h new file mode 100644 index 000000000..c2716f3fa --- /dev/null +++ b/include/grub/i386/reboot.h @@ -0,0 +1,28 @@ +/* + * 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_REBOOT_H +#define GRUB_REBOOT_H 1 + +#ifndef ASM_FILE + +extern grub_uint8_t grub_reboot_end[], grub_reboot_start[]; + +#endif + +#endif diff --git a/include/grub/mips/loongson/ec.h b/include/grub/mips/loongson/ec.h index 62d1d33d9..3f8ff9931 100644 --- a/include/grub/mips/loongson/ec.h +++ b/include/grub/mips/loongson/ec.h @@ -19,6 +19,10 @@ #ifndef GRUB_EC_MACHINE_HEADER #define GRUB_EC_MACHINE_HEADER 1 +#include +#include +#include + #define GRUB_MACHINE_EC_MAGIC_PORT1 0x381 #define GRUB_MACHINE_EC_MAGIC_PORT2 0x382 #define GRUB_MACHINE_EC_DATA_PORT 0x383 diff --git a/include/grub/mips/qemu_mips/kernel.h b/include/grub/mips/qemu_mips/kernel.h index 66add4b2e..1e7e32401 100644 --- a/include/grub/mips/qemu_mips/kernel.h +++ b/include/grub/mips/qemu_mips/kernel.h @@ -23,7 +23,6 @@ #ifndef ASM_FILE -void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); void grub_qemu_init_cirrus (void); diff --git a/include/grub/misc.h b/include/grub/misc.h index 66e74d8a8..0a0a4135e 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -343,7 +343,7 @@ grub_div_roundup (unsigned int x, unsigned int y) } /* Reboot the machine. */ -void EXPORT_FUNC (grub_reboot) (void) __attribute__ ((noreturn)); +void grub_reboot (void) __attribute__ ((noreturn)); #ifdef GRUB_MACHINE_PCBIOS /* Halt the system, using APM if possible. If NO_APM is true, don't From f8f72eb890273c7dc6cae48420d21a3d4e437213 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 20:28:09 +0200 Subject: [PATCH 1250/1414] * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): Don't add the bogus brackets. --- ChangeLog | 5 +++++ grub-core/kern/ieee1275/openfw.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d66419216..ee678a9e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-19 Vladimir Serbinenko + + * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): + Don't add the bogus brackets. + 2011-10-19 Vladimir Serbinenko ExFAT support. diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 23065e3e3..57252d96b 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -445,10 +445,10 @@ grub_ieee1275_encode_devname (const char *path) /* GRUB partition 1 is OF partition 0. */ partno++; - encoding = grub_xasprintf ("(%s,%d)", device, partno); + encoding = grub_xasprintf ("%s,%d", device, partno); } else - encoding = grub_xasprintf ("(%s)", device); + encoding = grub_strdup (device); grub_free (partition); grub_free (device); From 36dd20ad0bc2bd9b46ce48cc0425512018cac21f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 20:30:06 +0200 Subject: [PATCH 1251/1414] * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. --- ChangeLog | 4 ++++ grub-core/kern/main.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee678a9e3..6210a4eab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-19 Vladimir Serbinenko + + * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. + 2011-10-19 Vladimir Serbinenko * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 77be11422..bf2789860 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -105,7 +105,7 @@ grub_set_prefix_and_root (void) char *path = NULL; char *fwdevice = NULL; char *fwpath = NULL; - char *prefix; + char *prefix = NULL; struct grub_module_header *header; FOR_MODULES (header) From e55599dcbf2f4773674995703cbf1a71cba3e355 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 20:35:41 +0200 Subject: [PATCH 1252/1414] * util/grub-install.in: Declare IEEE1275 as able to find out the disk name. --- ChangeLog | 5 +++++ util/grub-install.in | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6210a4eab..afbc8aec7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-19 Vladimir Serbinenko + + * util/grub-install.in: Declare IEEE1275 as able to find out the disk + name. + 2011-10-19 Vladimir Serbinenko * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. diff --git a/util/grub-install.in b/util/grub-install.in index d11d24421..e1255f4f7 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -544,11 +544,11 @@ if [ "x${devabstraction_module}" = "x" ] ; then # Strip partition number grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`" grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`" - if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]); then + if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then # generic method (used on coreboot and ata mod) uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`" if [ "x${uuid}" = "x" ] ; then - if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${target_cpu}-${platform}" != x"sparc64-ieee1275" ]; then + if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 elif [ "$disk_module" = ata ]; then echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 @@ -563,7 +563,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" - elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ]; then + elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ] || [ "x$platform" = xieee1275 ]; then # we need to hardcode the partition number in the core image's prefix. if [ x"$grub_partition" = x ]; then prefix_drive="()" From de9c615e5c5b9d692ac00be91b16a0576a371e25 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 19 Oct 2011 23:01:44 +0200 Subject: [PATCH 1253/1414] Removed unused GRUB_BOOT_VERSION. Check for kernel version is better done with a dedicated section. * grub-core/boot/sparc64/ieee1275/boot.S: Remove GRUB_BOOT_VERSION. Ensure the correct position of boot_path. * grub-core/kern/i386/efi/startup.S: Remove GRUB_BOOT_VERSION. * grub-core/kern/i386/pc/startup.S: Likewise. Ensure correct position of other fields. * grub-core/kern/x86_64/efi/startup.S: Remove GRUB_BOOT_VERSION. * include/grub/boot.h: Removed. All references removed. * include/grub/sparc64/ieee1275/boot.h (GRUB_BOOT_MACHINE_VER_MAJ): Removed. (GRUB_BOOT_MACHINE_BOOT_DEVPATH): Make it lower. --- ChangeLog | 16 +++++++++++++ grub-core/Makefile.am | 1 - grub-core/boot/i386/pc/boot.S | 1 - grub-core/boot/i386/pc/cdboot.S | 1 - grub-core/boot/i386/pc/lnxboot.S | 1 - grub-core/boot/sparc64/ieee1275/boot.S | 5 +--- grub-core/boot/sparc64/ieee1275/diskboot.S | 1 - grub-core/kern/i386/efi/startup.S | 17 -------------- grub-core/kern/i386/pc/startup.S | 19 ++++++--------- grub-core/kern/x86_64/efi/callwrap.S | 1 - grub-core/kern/x86_64/efi/startup.S | 13 ----------- include/grub/boot.h | 27 ---------------------- include/grub/sparc64/ieee1275/boot.h | 4 +--- 13 files changed, 25 insertions(+), 82 deletions(-) delete mode 100644 include/grub/boot.h diff --git a/ChangeLog b/ChangeLog index afbc8aec7..1159d32a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-10-19 Vladimir Serbinenko + + Removed unused GRUB_BOOT_VERSION. Check for kernel version is better + done with a dedicated section. + + * grub-core/boot/sparc64/ieee1275/boot.S: Remove GRUB_BOOT_VERSION. + Ensure the correct position of boot_path. + * grub-core/kern/i386/efi/startup.S: Remove GRUB_BOOT_VERSION. + * grub-core/kern/i386/pc/startup.S: Likewise. Ensure correct position of + other fields. + * grub-core/kern/x86_64/efi/startup.S: Remove GRUB_BOOT_VERSION. + * include/grub/boot.h: Removed. All references removed. + * include/grub/sparc64/ieee1275/boot.h (GRUB_BOOT_MACHINE_VER_MAJ): + Removed. + (GRUB_BOOT_MACHINE_BOOT_DEVPATH): Make it lower. + 2011-10-19 Vladimir Serbinenko * util/grub-install.in: Declare IEEE1275 as able to find out the disk diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index f30014635..3bd192602 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -78,7 +78,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h 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/net.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index 635599a24..314f14016 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -18,7 +18,6 @@ */ #include -#include #include /* diff --git a/grub-core/boot/i386/pc/cdboot.S b/grub-core/boot/i386/pc/cdboot.S index 33569ce9d..d939835a9 100644 --- a/grub-core/boot/i386/pc/cdboot.S +++ b/grub-core/boot/i386/pc/cdboot.S @@ -18,7 +18,6 @@ */ #include -#include #include #include #include diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index 2c7596026..bb43ed73c 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S index f08258f47..f79699502 100644 --- a/grub-core/boot/sparc64/ieee1275/boot.S +++ b/grub-core/boot/sparc64/ieee1275/boot.S @@ -17,7 +17,6 @@ * along with GRUB. If not, see . */ -#include #include .text @@ -29,9 +28,6 @@ pic_base: call boot_continue mov %o4, CIF_REG - . = _start + GRUB_BOOT_MACHINE_VER_MAJ -boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - /* The offsets to these locations are defined by the * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h, * and grub-setup uses this to patch these next three values as needed. @@ -44,6 +40,7 @@ boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR * After loading in that block we will execute it by jumping to the * load address plus the size of the prepended A.OUT header (32 bytes). */ + . = _start + GRUB_BOOT_MACHINE_BOOT_DEVPATH boot_path: . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE boot_path_end: diff --git a/grub-core/boot/sparc64/ieee1275/diskboot.S b/grub-core/boot/sparc64/ieee1275/diskboot.S index 83dfee098..e020f6221 100644 --- a/grub-core/boot/sparc64/ieee1275/diskboot.S +++ b/grub-core/boot/sparc64/ieee1275/diskboot.S @@ -17,7 +17,6 @@ * along with GRUB. If not, see . */ -#include #include #include diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S index 0f904d7b3..fc5ea3dac 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/grub-core/kern/i386/efi/startup.S @@ -19,29 +19,12 @@ #include #include -#include .file "startup.S" .text .globl start, _start start: _start: - jmp codestart - - /* - * Compatibility version number - * - * These MUST be at byte offset 6 and 7 of the executable - * DO NOT MOVE !!! - */ - . = _start + 0x6 - .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - - /* - * This is a special data area 8 bytes from the beginning. - */ - -codestart: /* * EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack. */ diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index a70a2a7db..0350431d9 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -75,31 +74,27 @@ LOCAL (base): #else ljmp $0, $ABS(LOCAL (codestart)) #endif - /* - * Compatibility version number - * - * These MUST be at byte offset 6 and 7 of the executable - * DO NOT MOVE !!! - */ - . = _start + 0x6 - .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR /* - * This is a special data area 8 bytes from the beginning. + * This is a special data area. */ - . = _start + 0x8 - + . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE VARIABLE(grub_total_module_size) .long 0 + . = _start + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE VARIABLE(grub_kernel_image_size) .long 0 + . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE VARIABLE(grub_compressed_size) .long 0 + . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART VARIABLE(grub_install_dos_part) .long 0xFFFFFFFF + . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF + . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY reed_solomon_redundancy: .long 0 diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S index cc2c8aa05..dced859ac 100644 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ b/grub-core/kern/x86_64/efi/callwrap.S @@ -19,7 +19,6 @@ #include #include -#include /* * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index 37efde7fc..f86f01969 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -19,7 +19,6 @@ #include #include -#include .file "startup.S" .text @@ -28,18 +27,6 @@ start: _start: - jmp codestart - - /* - * Compatibility version number - * - * These MUST be at byte offset 6 and 7 of the executable - * DO NOT MOVE !!! - */ - . = _start + 0x6 - .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR - -codestart: movq %rcx, EXT_C(grub_efi_image_handle)(%rip) movq %rdx, EXT_C(grub_efi_system_table)(%rip) diff --git a/include/grub/boot.h b/include/grub/boot.h deleted file mode 100644 index 235774863..000000000 --- a/include/grub/boot.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,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_BOOT_HEADER -#define GRUB_BOOT_HEADER 1 - -#define GRUB_BOOT_VERSION_MAJOR 4 -#define GRUB_BOOT_VERSION_MINOR 0 -#define GRUB_BOOT_VERSION ((GRUB_BOOT_VERSION_MINOR << 8) \ - | GRUB_BOOT_VERSION_MAJOR) - -#endif /* ! GRUB_BOOT_HEADER */ diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 112d19bc7..60edc712e 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -39,9 +39,7 @@ #define GRUB_BOOT_MACHINE_SIGNATURE 0xbb44aa55 -#define GRUB_BOOT_MACHINE_VER_MAJ 0x08 - -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x08 #define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 From fcf1d67219695832a42525d3f9c9dc0730e72bf5 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 19 Oct 2011 23:11:48 +0200 Subject: [PATCH 1254/1414] * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible NULL pointer dereference. --- ChangeLog | 5 +++++ grub-core/bus/usb/uhci.c | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1159d32a5..96abe1229 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-19 Szymon Janc + + * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible + NULL pointer dereference. + 2011-10-19 Vladimir Serbinenko Removed unused GRUB_BOOT_VERSION. Check for kernel version is better diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 260b7e876..a9a4c45a2 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -544,8 +544,11 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev, { grub_size_t actual = 0; /* Terminate and free. */ - td_prev->linkptr2 = 0; - td_prev->linkptr = 1; + if (td_prev) + { + td_prev->linkptr2 = 0; + td_prev->linkptr = 1; + } if (cdata->td_first) grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual); From 766f7d08092a0904cb00af1b419fb8b8edcdb51b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 20 Oct 2011 08:13:00 +0200 Subject: [PATCH 1255/1414] Remove redundant grub_kernel_image_size. * grub-core/kern/i386/coreboot/init.c (grub_machine_init): Use _edata and _start. * grub-core/kern/i386/coreboot/startup.S: Move multiboot header after the small code. It moves it only by few bytes but simplifies the code. * grub-core/kern/i386/pc/init.c (grub_machine_init): Use _edata and _start. * grub-core/kern/i386/pc/startup.S: Use _edata and _start. (grub_kernel_image_size): Removed. * grub-core/kern/i386/qemu/startup.S: Use _edata and _start. (grub_kernel_image_size): Removed. [APPLE_CC]: Remove apple compiler support. i386-qemu port can't be compiled with Apple toolchain. * grub-core/kern/sparc64/ieee1275/crt0.S: Remove leftover fields. * include/grub/i386/pc/kernel.h (grub_kernel_image_size): Removed. * include/grub/i386/qemu/kernel.h (grub_kernel_image_size): Removed. (grub_total_module_size): Likewise. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE): Removed. (GRUB_KERNEL_I386_PC_COMPRESSED_SIZE): Put it lower. (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Likewise. (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Likewise. (GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE): Removed. (GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE): Likewise. (GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE): Likewise. * include/grub/sparc64/ieee1275/kernel.h (grub_kernel_image_size): Removed. (grub_total_module_size): Removed. * util/grub-mkimage.c (image_target_desc): Remove image_size. (image_targets): Likewise. Set .compressed_size to no field on sparc. (generate_image): Remove kernel_image_size handling. --- ChangeLog | 37 ++++++++++++++++++++++++++ grub-core/kern/i386/coreboot/init.c | 7 ++--- grub-core/kern/i386/coreboot/startup.S | 27 +++++++++---------- grub-core/kern/i386/pc/init.c | 3 ++- grub-core/kern/i386/pc/startup.S | 5 +--- grub-core/kern/i386/qemu/startup.S | 20 +------------- grub-core/kern/sparc64/ieee1275/crt0.S | 4 --- include/grub/i386/pc/kernel.h | 3 --- include/grub/i386/qemu/kernel.h | 6 ----- include/grub/offsets.h | 20 +++----------- include/grub/sparc64/ieee1275/kernel.h | 6 ----- util/grub-mkimage.c | 28 ++----------------- 12 files changed, 63 insertions(+), 103 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96abe1229..bf96dc095 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2011-10-20 Vladimir Serbinenko + + Remove redundant grub_kernel_image_size. + + * grub-core/kern/i386/coreboot/init.c (grub_machine_init): Use + _edata and _start. + * grub-core/kern/i386/coreboot/startup.S: Move multiboot header after + the small code. It moves it only by few bytes but simplifies the code. + * grub-core/kern/i386/pc/init.c (grub_machine_init): Use _edata and + _start. + * grub-core/kern/i386/pc/startup.S: Use _edata and _start. + (grub_kernel_image_size): Removed. + * grub-core/kern/i386/qemu/startup.S: Use _edata and _start. + (grub_kernel_image_size): Removed. + [APPLE_CC]: Remove apple compiler support. i386-qemu port can't be + compiled with Apple toolchain. + * grub-core/kern/sparc64/ieee1275/crt0.S: Remove leftover fields. + * include/grub/i386/pc/kernel.h (grub_kernel_image_size): Removed. + * include/grub/i386/qemu/kernel.h (grub_kernel_image_size): Removed. + (grub_total_module_size): Likewise. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE): + Removed. + (GRUB_KERNEL_I386_PC_COMPRESSED_SIZE): Put it lower. + (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Likewise. + (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. + (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Likewise. + (GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE): Removed. + (GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE): Likewise. + (GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE): Likewise. + * include/grub/sparc64/ieee1275/kernel.h (grub_kernel_image_size): + Removed. + (grub_total_module_size): Removed. + * util/grub-mkimage.c (image_target_desc): Remove image_size. + (image_targets): Likewise. + Set .compressed_size to no field on sparc. + (generate_image): Remove kernel_image_size handling. + 2011-10-19 Szymon Janc * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index b7510ff98..95209bb70 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -38,8 +38,9 @@ #include #endif -extern char _start[]; -extern char _end[]; +extern grub_uint8_t _start[]; +extern grub_uint8_t _end[]; +extern grub_uint8_t _edata[]; grub_uint32_t grub_get_rtc (void) @@ -66,7 +67,7 @@ void grub_machine_init (void) { #ifdef GRUB_MACHINE_QEMU - grub_modbase = grub_core_entry_addr + grub_kernel_image_size; + grub_modbase = grub_core_entry_addr + (_edata - _start); grub_qemu_init_cirrus (); #endif diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index 5e7767bb9..dc2c62a25 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -38,21 +38,6 @@ .globl start, _start start: _start: - jmp codestart - -/* - * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). - */ - .p2align 2 /* force 4-byte alignment */ -multiboot_header: - /* magic */ - .long 0x1BADB002 - /* flags */ - .long MULTIBOOT_MEMORY_INFO - /* checksum */ - .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO - -codestart: #ifdef GRUB_MACHINE_MULTIBOOT cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax jne 0f @@ -66,6 +51,18 @@ codestart: /* jump to the main body of C code */ jmp EXT_C(grub_main) +/* + * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). + */ + .p2align 2 /* force 4-byte alignment */ +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long MULTIBOOT_MEMORY_INFO + /* checksum */ + .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO + /* * prot_to_real and associated structures (but NOT real_to_prot, that is * only needed for BIOS gates). diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 62269de78..be26fdea1 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -130,6 +130,7 @@ compact_mem_regions (void) } grub_addr_t grub_modbase; +extern grub_uint8_t _start[], _edata[]; void grub_machine_init (void) @@ -140,7 +141,7 @@ grub_machine_init (void) #endif grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR - + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); + + ((_edata - _start) - GRUB_KERNEL_MACHINE_RAW_SIZE); /* Initialize the console as early as possible. */ grub_console_init (); diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 0350431d9..a0ef71f90 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -81,9 +81,6 @@ LOCAL (base): . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE VARIABLE(grub_total_module_size) - .long 0 - . = _start + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE -VARIABLE(grub_kernel_image_size) .long 0 . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE VARIABLE(grub_compressed_size) @@ -226,7 +223,7 @@ post_reed_solomon: movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi pushl %edi pushl %esi - movl EXT_C(grub_kernel_image_size), %ecx + movl $(BSS_START_SYMBOL - _start), %ecx addl EXT_C(grub_total_module_size), %ecx subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx pushl %ecx diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 6500de620..0761807ed 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -32,8 +32,6 @@ _start: . = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 -VARIABLE(grub_kernel_image_size) - .long 0 codestart: /* Relocate to low memory. First we figure out our location. @@ -45,11 +43,7 @@ codestart: value of `grub_core_entry_addr' in %esi. */ xorw %si, %si - /* ... which allows us to access `grub_kernel_image_size' - before relocation. */ - movl (grub_kernel_image_size - _start)(%esi), %ecx - - + movl $(_edata - _start), %ecx movl $_start, %edi cld rep @@ -57,24 +51,12 @@ codestart: ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f 1: -#ifdef APPLE_CC - /* clean out the bss */ - bss_start_abs = ABS (bss_start) - bss_end_abs = ABS (bss_end) - - movl bss_start_abs, %edi - - /* compute the bss length */ - movl bss_end_abs, %ecx - subl %edi, %ecx -#else /* clean out the bss */ movl $BSS_START_SYMBOL, %edi /* compute the bss length */ movl $END_SYMBOL, %ecx subl %edi, %ecx -#endif /* clean out */ xorl %eax, %eax diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index 1466a56f8..9d91fba48 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -31,10 +31,6 @@ _start: VARIABLE(grub_total_module_size) .word 0 -VARIABLE(grub_kernel_image_size) - .word 0 -VARIABLE(grub_compressed_size) - .word 0 codestart: /* Copy the modules past the end of the kernel image. diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index dd50aa833..2dcdbb7a6 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -29,9 +29,6 @@ #include #include -/* The size of kernel image. */ -extern grub_int32_t grub_kernel_image_size; - /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index df06e6731..f34206b3a 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -28,12 +28,6 @@ extern grub_addr_t grub_core_entry_addr; -/* The size of kernel image. */ -extern grub_int32_t grub_kernel_image_size; - -/* The total size of module images following the kernel. */ -extern grub_int32_t grub_total_module_size; - void grub_qemu_init_cirrus (void); #endif /* ! ASM_FILE */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 526cfee68..aa65cd5cc 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -22,20 +22,17 @@ /* The offset of GRUB_TOTAL_MODULE_SIZE. */ #define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE 0xc - /* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x10 +#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x0c /* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x14 +#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10 /* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 +#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x14 /* Offset of reed_solomon_redundancy. */ -#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x1c +#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 /* The size of the first region which won't be compressed. */ #define GRUB_KERNEL_I386_PC_RAW_SIZE 0xcd0 @@ -57,20 +54,11 @@ /* The offset of GRUB_CORE_ENTRY_ADDR. */ #define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc - #define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 /* The offset of GRUB_TOTAL_MODULE_SIZE. */ #define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 - #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 5aa50b852..9a00bea61 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -26,12 +26,6 @@ #include #include -/* The size of kernel image. */ -extern grub_int32_t grub_kernel_image_size; - -/* The total size of module images following the kernel. */ -extern grub_int32_t grub_total_module_size; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4440fdd12..fb1c5babe 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -79,7 +79,6 @@ struct image_target_desc } flags; unsigned raw_size; unsigned total_module_size; - unsigned kernel_image_size; unsigned compressed_size; unsigned link_align; grub_uint16_t elf_target; @@ -110,7 +109,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -131,7 +129,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -152,7 +149,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_LZMA, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, .section_align = 1, .vaddr_offset = 0, @@ -169,7 +165,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_LZMA, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, .section_align = 1, .vaddr_offset = 0, @@ -186,7 +181,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .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 @@ -209,7 +203,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -231,7 +224,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, - .kernel_image_size = GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -247,7 +239,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .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 = EFI64_HEADER_SIZE, @@ -266,7 +257,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .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, @@ -286,7 +276,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .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, @@ -308,7 +297,6 @@ struct image_target_desc image_targets[] = .raw_size = 0, .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, @@ -327,7 +315,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .kernel_image_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, @@ -348,8 +335,7 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, - .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -365,8 +351,7 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, - .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -382,7 +367,6 @@ struct image_target_desc image_targets[] = .flags = PLATFORM_FLAGS_NONE, .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 = EFI64_HEADER_SIZE, @@ -402,7 +386,6 @@ struct image_target_desc image_targets[] = .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, @@ -422,7 +405,6 @@ struct image_target_desc image_targets[] = .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, @@ -442,7 +424,6 @@ struct image_target_desc image_targets[] = .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, @@ -462,7 +443,6 @@ struct image_target_desc image_targets[] = .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, @@ -482,7 +462,6 @@ struct image_target_desc image_targets[] = .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, @@ -935,9 +914,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], && 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->kernel_image_size != TARGET_NO_FIELD) - *((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 *) (kernel_img + image_target->compressed_size)) = grub_host_to_target32 (core_size - image_target->raw_size); From db1326f5fbdbe15651dafb5ee628118018f1d53c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 Oct 2011 00:16:59 +0200 Subject: [PATCH 1256/1414] Move chainloader_real_boot out of the kernel --- grub-core/Makefile.am | 1 - grub-core/kern/i386/pc/startup.S | 25 -------- grub-core/lib/i386/reboot.c | 1 + grub-core/lib/i386/relocator.c | 9 ++- grub-core/lib/i386/relocator16.S | 85 ++++++++++++++++++++++++++ grub-core/loader/i386/pc/chainloader.c | 59 ++++++++++++++---- grub-core/loader/i386/pc/freedos.c | 3 +- grub-core/loader/i386/pc/linux.c | 2 +- grub-core/loader/i386/pc/ntldr.c | 3 +- include/grub/i386/pc/loader.h | 27 -------- include/grub/i386/relocator.h | 2 + 11 files changed, 148 insertions(+), 69 deletions(-) delete mode 100644 include/grub/i386/pc/loader.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 3bd192602..4a46e1d9c 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -83,7 +83,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h if COND_i386_pc -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index a0ef71f90..e75f3ab90 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -463,31 +463,6 @@ FUNCTION(grub_exit) ljmp $0xf000, $0xfff0 .code32 -/* - * void grub_chainloader_real_boot (int drive, void *part_addr) - * - * This starts another boot loader. - */ - -FUNCTION(grub_chainloader_real_boot) - pushl %edx - pushl %eax - - /* Turn off Gate A20 */ - xorl %eax, %eax - call grub_gate_a20 - - /* set up to pass boot drive */ - popl %edx - - /* ESI must point to a partition table entry */ - popl %esi - - call prot_to_real - .code16 - ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR - .code32 - /* * void grub_console_putchar (int c) * diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c index ef28f7f65..45a2259cf 100644 --- a/grub-core/lib/i386/reboot.c +++ b/grub-core/lib/i386/reboot.c @@ -49,6 +49,7 @@ grub_reboot (void) state.sp = 0; state.cs = segment; state.ip = 0; + state.a20 = 0; grub_stop_floppy (); diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index 2f10feb5e..1f0aa0dd1 100644 --- a/grub-core/lib/i386/relocator.c +++ b/grub-core/lib/i386/relocator.c @@ -51,6 +51,9 @@ 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_uint32_t grub_relocator16_esi; + +extern grub_uint16_t grub_relocator16_keep_a20_enabled; extern grub_uint8_t grub_relocator32_start; extern grub_uint8_t grub_relocator32_end; @@ -195,7 +198,8 @@ grub_relocator16_boot (struct grub_relocator *rel, void *relst; grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, + /* Put it higher than the byte it checks for A20 check. */ + err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010, 0xa0000 - RELOCATOR_SIZEOF (16), RELOCATOR_SIZEOF (16), 16, GRUB_RELOCATOR_PREFERENCE_NONE); @@ -215,6 +219,9 @@ grub_relocator16_boot (struct grub_relocator *rel, grub_relocator16_ebx = state.ebx; grub_relocator16_edx = state.edx; + grub_relocator16_esi = state.esi; + + grub_relocator16_keep_a20_enabled = state.a20; grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start, RELOCATOR_SIZEOF (16)); diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index d6673fade..babe69e1d 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -93,6 +93,85 @@ LOCAL(segment): .word 0 LOCAL(cont3): + + /* movw imm16, %ax. */ + .byte 0xb8 +VARIABLE(grub_relocator16_keep_a20_enabled) + .word 0 + test %ax, %ax + jnz LOCAL(gate_a20_done) + + /* first of all, test if already in a good state */ + call LOCAL(gate_a20_check_state) + testb %al, %al + jz LOCAL(gate_a20_done) + + /* second, try a BIOS call */ + movw $0x2400, %ax + int $0x15 + + call LOCAL(gate_a20_check_state) + testb %al, %al + jz LOCAL(gate_a20_done) + + /* + * In macbook, the keyboard test would hang the machine, so we move + * this forward. + */ + /* fourth, try the system control port A */ + inb $0x92 + andb $(~0x03), %al + outb $0x92 + + /* When turning off Gate A20, do not check the state strictly, + because a failure is not fatal usually, and Gate A20 is always + on some modern machines. */ + jmp LOCAL(gate_a20_done) + +LOCAL(gate_a20_check_state): + /* iterate the checking for a while */ + movw $100, %cx +1: + call 3f + testb %al, %al + jz 2f + loop 1b +2: + ret + +3: + xorw %ax, %ax + movw %ax, %ds + decw %ax + movw %ax, %es + xorw %ax, %ax + + movw $0x8000, %ax + /* compare the byte at ADDR with that at 0x100000 + ADDR */ + movw %ax, %si + addw $0x10, %ax + movw %ax, %di + + /* save the original byte in DL */ + movb %ds:(%si), %dl + movb %es:(%di), %al + /* try to set one less value at ADDR */ + movb %al, %dh + decb %dh + movb %dh, %ds:(%si) + /* serialize */ + outb %al, $0x80 + outb %al, $0x80 + /* obtain the value at 0x100000 + ADDR in CH */ + movb %es:(%di), %dh + /* this result is 1 if A20 is on or 0 if it is off */ + subb %dh, %al + xorb $1, %al + /* restore the original */ + movb %dl, %es:(%di) + ret + +LOCAL(gate_a20_done): /* we are in real mode now * set up the real mode segment registers : DS, SS, ES */ @@ -132,6 +211,12 @@ VARIABLE(grub_relocator16_sp) .word 0 movzwl %ax, %esp + /* movw imm32, %eax. */ + .byte 0x66, 0xb8 +VARIABLE(grub_relocator16_esi) + .long 0 + movl %eax, %esi + /* movw imm32, %edx. */ .byte 0x66, 0xba VARIABLE(grub_relocator16_edx) diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index 8d6ec8f20..929569921 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -39,12 +38,14 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; static int boot_drive; -static void *boot_part_addr; +static grub_addr_t boot_part_addr; +static struct grub_relocator *rel; typedef enum { @@ -55,16 +56,29 @@ typedef enum static grub_err_t grub_chainloader_boot (void) { + struct grub_relocator16_state state = { + .edx = boot_drive, + .esi = boot_part_addr, + .ds = 0, + .es = 0, + .fs = 0, + .gs = 0, + .ss = 0, + .cs = 0, + .sp = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR, + .ip = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR, + .a20 = 0 + }; grub_video_set_mode ("text", 0, 0); - grub_chainloader_real_boot (boot_drive, boot_part_addr); - /* Never reach here. */ - return GRUB_ERR_NONE; + return grub_relocator16_boot (rel, state); } static grub_err_t grub_chainloader_unload (void) { + grub_relocator_unload (rel); + rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; } @@ -133,7 +147,12 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) grub_uint16_t signature; grub_device_t dev; int drive = -1; - void *part_addr = 0; + grub_addr_t part_addr = 0; + grub_uint8_t *bs, *ptable; + + rel = grub_relocator_new (); + if (!rel) + goto fail; grub_dl_ref (my_mod); @@ -142,8 +161,25 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) if (! file) goto fail; + { + grub_relocator_chunk_t ch; + grub_err_t err; + + err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00, + GRUB_DISK_SECTOR_SIZE); + if (err) + goto fail; + bs = get_virtual_current_address (ch); + err = grub_relocator_alloc_chunk_addr (rel, &ch, + GRUB_MEMORY_MACHINE_PART_TABLE_ADDR, + 64); + if (err) + goto fail; + ptable = get_virtual_current_address (ch); + } + /* Read the first block. */ - if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE) + if (grub_file_read (file, bs, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) { if (grub_errno == GRUB_ERR_NONE) @@ -153,7 +189,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) } /* Check the signature. */ - signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2)); + signature = *((grub_uint16_t *) (bs + GRUB_DISK_SECTOR_SIZE - 2)); if (signature != grub_le_to_cpu16 (0xaa55) && ! (flags & GRUB_CHAINLOADER_FORCE)) { @@ -177,10 +213,9 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) if (p && grub_strcmp (p->partmap->name, "msdos") == 0) { disk->partition = p->parent; - grub_disk_read (disk, p->offset, 446, 64, - (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); - part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR - + (p->index << 4)); + grub_disk_read (disk, p->offset, 446, 64, ptable); + part_addr = (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR + + (p->index << 4)); disk->partition = p; } } diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c index f796e08f4..1f088e2b5 100644 --- a/grub-core/loader/i386/pc/freedos.c +++ b/grub-core/loader/i386/pc/freedos.c @@ -56,7 +56,8 @@ grub_freedos_boot (void) .ss = GRUB_FREEDOS_STACK_SEGMENT, .sp = GRUB_FREEDOS_STACK_POINTER, .ebx = ebx, - .edx = 0 + .edx = 0, + .a20 = 1 }; grub_video_set_mode ("text", 0, 0); diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index adc6e8b99..c7c099174 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -61,6 +60,7 @@ grub_linux16_boot (void) state.sp = GRUB_LINUX_SETUP_STACK; state.cs = segment + 0x20; state.ip = 0; + state.a20 = 1; grub_video_set_mode ("text", 0, 0); diff --git a/grub-core/loader/i386/pc/ntldr.c b/grub-core/loader/i386/pc/ntldr.c index b2909c191..153b605ed 100644 --- a/grub-core/loader/i386/pc/ntldr.c +++ b/grub-core/loader/i386/pc/ntldr.c @@ -54,7 +54,8 @@ grub_ntldr_boot (void) .gs = 0, .ss = 0, .sp = 0x7c00, - .edx = edx + .edx = edx, + .a20 = 1 }; grub_video_set_mode ("text", 0, 0); diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h deleted file mode 100644 index bfbcaac5a..000000000 --- a/include/grub/i386/pc/loader.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,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_LOADER_MACHINE_HEADER -#define GRUB_LOADER_MACHINE_HEADER 1 - -#include - -/* This is an asm part of the chainloader. */ -void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn)); - -#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h index 778049eef..b2fe900b6 100644 --- a/include/grub/i386/relocator.h +++ b/include/grub/i386/relocator.h @@ -48,6 +48,8 @@ struct grub_relocator16_state grub_uint16_t ip; grub_uint32_t ebx; grub_uint32_t edx; + grub_uint32_t esi; + int a20; }; struct grub_relocator64_state From 7bec1053db4da195301d418bd82dd5316b28002e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 22:40:26 +0200 Subject: [PATCH 1257/1414] * util/grub.d/10_hurd.in: Add datarootdir as per automake manual suggestion. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. * util/grub.d/10_netbsd.in: Likewise. * util/grub.d/10_windows.in: Likewise. * util/grub.d/20_linux_xen.in: Likewise. --- ChangeLog | 10 ++++++++++ util/grub.d/10_hurd.in | 1 + util/grub.d/10_kfreebsd.in | 1 + util/grub.d/10_linux.in | 1 + util/grub.d/10_netbsd.in | 1 + util/grub.d/10_windows.in | 1 + util/grub.d/20_linux_xen.in | 1 + 7 files changed, 16 insertions(+) diff --git a/ChangeLog b/ChangeLog index bf96dc095..0b179811c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-20 Vladimir Serbinenko + + * util/grub.d/10_hurd.in: Add datarootdir as per automake manual + suggestion. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/10_netbsd.in: Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/20_linux_xen.in: Likewise. + 2011-10-20 Vladimir Serbinenko Remove redundant grub_kernel_image_size. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 9ca01f0a8..d04b0a4fe 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -20,6 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib CLASS="--class gnu --class os" diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index e4bfc06cb..e668f3fd9 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 97e7c6523..c3565096b 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index c257aeb3c..8c232b01b 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 941267a9f..0a848880d 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -20,6 +20,7 @@ set -e prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib case "`uname 2>/dev/null`" in diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index c0b255598..2f1b4af88 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -21,6 +21,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ +datarootdir=@datarootdir@ . ${libdir}/@PACKAGE@/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ From 7a5c54a437d148d3f8de45b3adaa9a77d6e5de44 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 22:53:21 +0200 Subject: [PATCH 1258/1414] * util/grub-install.in: Add datarootdir as per automake manual suggestion. * util/grub-mknetdir.in: Likewise. --- ChangeLog | 8 +++++++- util/grub-install.in | 1 + util/grub-mknetdir.in | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0b179811c..17db9da19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ -2011-10-20 Vladimir Serbinenko +2011-10-23 Vladimir Serbinenko + + * util/grub-install.in: Add datarootdir as per automake manual + suggestion. + * util/grub-mknetdir.in: Likewise. + +2011-10-23 Vladimir Serbinenko * util/grub.d/10_hurd.in: Add datarootdir as per automake manual suggestion. diff --git a/util/grub-install.in b/util/grub-install.in index e1255f4f7..fdbe10e76 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -31,6 +31,7 @@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ platform=@platform@ host_os=@host_os@ +datarootdir=@datarootdir@ pkglibdir="${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`" localedir="@datadir@/locale" diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in index 52598a8c9..e5a2172fd 100644 --- a/util/grub-mknetdir.in +++ b/util/grub-mknetdir.in @@ -29,6 +29,7 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ host_os=@host_os@ localedir=@datadir@/locale +datarootdir=@datarootdir@ pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" self=`basename $0` From d1e293bbfac2f1890d6d8ab4fbc72adb43536adf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 22:55:32 +0200 Subject: [PATCH 1259/1414] * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of grub_memcmp usage. --- ChangeLog | 5 +++++ grub-core/io/lzopio.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 17db9da19..5899c1e95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of + grub_memcmp usage. + 2011-10-23 Vladimir Serbinenko * util/grub-install.in: Add datarootdir as per automake manual diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index 02a70f4d8..bd6f8e738 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -397,7 +397,7 @@ test_header (grub_file_t file) if (hcheck) { checksum = grub_cpu_to_be32(checksum); - if (memcmp(&checksum, hcheck->read(context), sizeof(checksum)) != 0) + if (grub_memcmp (&checksum, hcheck->read(context), sizeof(checksum)) != 0) goto CORRUPTED; } From 3ce69fc90f62b3ca01239bdc826d4960df15ce83 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:04:57 +0200 Subject: [PATCH 1260/1414] * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. * grub-core/lib/i386/reboot_trampoline.S (grub_reboot_start): Likewise. --- ChangeLog | 6 ++++++ grub-core/kern/i386/pc/startup.S | 1 + grub-core/lib/i386/reboot_trampoline.S | 1 + 3 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5899c1e95..f5b846ddd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. + * grub-core/lib/i386/reboot_trampoline.S (grub_reboot_start): + Likewise. + 2011-10-23 Vladimir Serbinenko * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index a0ef71f90..5277695b1 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -458,6 +458,7 @@ FUNCTION(grub_exit) /* Tell the BIOS a boot failure. If this does not work, reboot. */ int $0x18 /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ + xorw %ax, %ax movw $0x0472, %di movw %ax, (%di) ljmp $0xf000, $0xfff0 diff --git a/grub-core/lib/i386/reboot_trampoline.S b/grub-core/lib/i386/reboot_trampoline.S index 18bcfb287..c088cd081 100644 --- a/grub-core/lib/i386/reboot_trampoline.S +++ b/grub-core/lib/i386/reboot_trampoline.S @@ -26,6 +26,7 @@ VARIABLE(grub_reboot_start) /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ movw $0x0472, %di + xorw %ax, %ax movw %ax, (%di) ljmp $0xf000, $0xfff0 From f8bc22a832e290cd5fa80572e248762f71a7274f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:20:11 +0200 Subject: [PATCH 1261/1414] * util/ieee1275/grub-ofpathname.c: Add missing include. --- ChangeLog | 4 ++++ util/ieee1275/grub-ofpathname.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index f5b846ddd..39a85696e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/ieee1275/grub-ofpathname.c: Add missing include. + 2011-10-23 Vladimir Serbinenko * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. diff --git a/util/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c index a9bc2cfda..ee81457b3 100644 --- a/util/ieee1275/grub-ofpathname.c +++ b/util/ieee1275/grub-ofpathname.c @@ -24,6 +24,8 @@ #include "progname.h" +#include + int main(int argc, char **argv) { char *of_path; From 18c575e5c5c4a1df3aadb602244e31677bb8631d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:22:38 +0200 Subject: [PATCH 1262/1414] * util/grub-setup.c: Add missing include. --- ChangeLog | 4 ++++ util/grub-setup.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 39a85696e..7eb57b134 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/grub-setup.c: Add missing include. + 2011-10-23 Vladimir Serbinenko * util/ieee1275/grub-ofpathname.c: Add missing include. diff --git a/util/grub-setup.c b/util/grub-setup.c index b3a6c5c76..99de26f76 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -49,6 +49,7 @@ #include "progname.h" #include #include +#include #define _GNU_SOURCE 1 #include From 4e94ae657595a0b13656ebf16e65fbd071783663 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:25:06 +0200 Subject: [PATCH 1263/1414] * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static inline function rather than a define. --- ChangeLog | 5 +++++ include/grub/misc.h | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7eb57b134..782da923e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-23 Vladimir Serbinenko + + * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static + inline function rather than a define. + 2011-10-23 Vladimir Serbinenko * util/grub-setup.c: Add missing include. diff --git a/include/grub/misc.h b/include/grub/misc.h index 0a0a4135e..5bc159e7d 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -49,14 +49,19 @@ #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } #define grub_dprintf(condition, fmt, args...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, fmt, ## args) -/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ -#define grub_memcpy(d,s,n) grub_memmove ((d), (s), (n)) void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c); char *EXPORT_FUNC(grub_stpcpy) (char *dest, const char *src); +/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ +static inline void * +grub_memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memmove (dest, src, n); +} + static inline char * grub_strcat (char *dest, const char *src) { From 4defb8d59b16c713460ea0929b4439ace3dc2705 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:28:23 +0200 Subject: [PATCH 1264/1414] * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: New inline function. * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (memcpy) [GRUB_UTIL]: Likewise. (memset) [GRUB_UTIL]: Likewise. (memcmp) [GRUB_UTIL]: Likewise. --- ChangeLog | 9 +++++++++ grub-core/lib/libgcrypt_wrap/cipher_wrap.h | 21 ++++++++++++++++++++- grub-core/lib/posix_wrap/string.h | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 782da923e..579f510b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: + New inline function. + * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (memcpy) [GRUB_UTIL]: + Likewise. + (memset) [GRUB_UTIL]: Likewise. + (memcmp) [GRUB_UTIL]: Likewise. + 2011-10-23 Vladimir Serbinenko * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h index 59febaeb5..0141400fc 100644 --- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h @@ -87,6 +87,25 @@ fips_mode (void) return 0; } -#define memset grub_memset +#ifdef GRUB_UTIL +static inline void * +memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memcpy (dest, src, n); +} + +static inline void * +memset (void *s, int c, grub_size_t n) +{ + return grub_memset (s, c, n); +} + +static inline int +memcmp (const void *s1, const void *s2, grub_size_t n) +{ + return grub_memcmp (s1, s2, n); +} +#endif + #endif diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h index 4224836e2..f38c97ba4 100644 --- a/grub-core/lib/posix_wrap/string.h +++ b/grub-core/lib/posix_wrap/string.h @@ -39,4 +39,12 @@ strcasecmp (const char *s1, const char *s2) return grub_strcasecmp (s1, s2); } +#ifdef GRUB_UTIL +static inline void * +memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memcpy (dest, src, n); +} +#endif + #endif From 124df5f6caabf6be40434c75b4c945f908d01904 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:32:06 +0200 Subject: [PATCH 1265/1414] Fine grainely disable warnings on lexer. Remove Wno-error on it. * grub-core/Makefile.core.def (normal): Remove -Wno-error. * grub-core/script/lexer.c: Declare yytext_ptr to avoid having yylex_strncpy. * grub-core/script/yylex.l: Add fine-grained #pragma. --- ChangeLog | 9 +++++++++ grub-core/Makefile.core.def | 2 +- grub-core/script/lexer.c | 1 + grub-core/script/yylex.l | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 579f510b0..637fa622b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-23 Vladimir Serbinenko + + Fine grainely disable warnings on lexer. Remove Wno-error on it. + + * grub-core/Makefile.core.def (normal): Remove -Wno-error. + * grub-core/script/lexer.c: Declare yytext_ptr to avoid having + yylex_strncpy. + * grub-core/script/yylex.l: Add fine-grained #pragma. + 2011-10-23 Vladimir Serbinenko * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 7cb83924c..6d3c31ea6 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1395,7 +1395,7 @@ module = { extra_dist = script/yylex.l; extra_dist = script/parser.y; - cflags = '$(CFLAGS_POSIX) -Wno-error'; + cflags = '$(CFLAGS_POSIX)'; cppflags = '$(CPPFLAGS_POSIX)'; }; diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c index 98279079f..53697c734 100644 --- a/grub-core/script/lexer.c +++ b/grub-core/script/lexer.c @@ -24,6 +24,7 @@ #include #include +#define yytext_ptr char * #include "grub_script.tab.h" #include "grub_script.yy.h" diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 7195a880d..012d88dbc 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -24,6 +24,9 @@ #include #include "grub_script.tab.h" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + #define yyfree grub_lexer_yyfree #define yyalloc grub_lexer_yyalloc #define yyrealloc grub_lexer_yyrealloc From 3471ecdfd9c08e59f37f8ec8fd530aef26e9f1e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:34:30 +0200 Subject: [PATCH 1266/1414] * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. --- ChangeLog | 4 ++++ grub-core/lib/setjmp.S | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 637fa622b..6daca7214 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. + 2011-10-23 Vladimir Serbinenko Fine grainely disable warnings on lexer. Remove Wno-error on it. diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index b04fd7439..fb7f94767 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -10,6 +10,7 @@ #include "./powerpc/setjmp.S" #elif defined(__ia64__) #include "./ia64/setjmp.S" +#include "./ia64/longjmp.S" #else #error "Unknown target cpu type" #endif From e084ba18957266042721af925a58d744daf8b842 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:39:00 +0200 Subject: [PATCH 1267/1414] * util/import_gcry.py: Accept space between # and include. --- ChangeLog | 4 ++++ util/import_gcry.py | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6daca7214..fc5ab9806 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/import_gcry.py: Accept space between # and include. + 2011-10-23 Vladimir Serbinenko * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. diff --git a/util/import_gcry.py b/util/import_gcry.py index 720f19303..befa5ef5f 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -189,10 +189,9 @@ for cipher_file in cipher_files: continue else: fw.write (holdline) - m = re.match ("#include <.*>", line) + m = re.match ("# *include <(.*)>", line) if not m is None: - chmsg = "Removed including of %s" % \ - m.group () [len ("#include <"):len (m.group ()) - 1] + chmsg = "Removed including of %s" % m.groups ()[0] if nch: chlognew = "%s\n %s" % (chlognew, chmsg) else: From 534d769e579ad77100d11a397387ebff68fb90cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:40:53 +0200 Subject: [PATCH 1268/1414] * util/import_gcry.py: Automatically fix camellia.c and camellia.h. --- ChangeLog | 4 ++++ util/import_gcry.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index fc5ab9806..0198ba4ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-23 Vladimir Serbinenko + + * util/import_gcry.py: Automatically fix camellia.c and camellia.h. + 2011-10-23 Vladimir Serbinenko * util/import_gcry.py: Accept space between # and include. diff --git a/util/import_gcry.py b/util/import_gcry.py index befa5ef5f..7591d8f0e 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -104,6 +104,20 @@ for cipher_file in cipher_files: fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n") fw.write ("#include \n") + if cipher_file == "camellia.c": + fw.write ("#include \"camellia.h\"\n") + if cipher_file == "camellia.h": + fw.write ("#include \n") + fw.write ("void camellia_setup128(const unsigned char *key, grub_uint32_t *subkey);\n") + fw.write ("void camellia_setup192(const unsigned char *key, grub_uint32_t *subkey);\n") + fw.write ("void camellia_setup256(const unsigned char *key, grub_uint32_t *subkey);\n") + fw.write ("void camellia_encrypt128(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_encrypt192(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_encrypt256(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_decrypt128(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_decrypt192(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("void camellia_decrypt256(const grub_uint32_t *subkey, grub_uint32_t *io);\n") + fw.write ("#define memcpy grub_memcpy\n") # Whole libgcrypt is distributed under GPLv3+ or compatible if isc: fw.write ("GRUB_MOD_LICENSE (\"GPLv3+\");\n") From f646e143090e26fc8087f3395fc2c1e03190c584 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 Oct 2011 23:55:38 +0200 Subject: [PATCH 1269/1414] * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and save some space. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. --- ChangeLog | 7 +++++++ grub-core/lib/reed_solomon.c | 4 ++-- include/grub/offsets.h | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0198ba4ee..ea8804bd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and + save some space. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. + (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. + 2011-10-23 Vladimir Serbinenko * util/import_gcry.py: Automatically fix camellia.c and camellia.h. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 365b76003..78d249c2f 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -57,13 +57,13 @@ typedef grub_uint16_t gf_double_t; #define GF_POLYNOMIAL 0x1d #define GF_INVERT2 0x8e #if defined (STANDALONE) && !defined (TEST) -static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; +static gf_single_t * const gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; #else #if defined (STANDALONE) static char *scratch; #endif -static grub_uint8_t gf_invert[256]; +static gf_single_t gf_invert[256]; #endif #define SECTOR_SIZE 512 diff --git a/include/grub/offsets.h b/include/grub/offsets.h index aa65cd5cc..92354f700 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -35,9 +35,9 @@ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xcd0 +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc70 -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x730 +#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 From 89481cabbdbbf8dfd937f06f6195bc4135fb86d0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 01:31:06 +0200 Subject: [PATCH 1270/1414] * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 if no label is found. (grub_fat_iterate_dir): Fix file size type. (grub_fat_iterate_dir): Likewise. --- ChangeLog | 7 +++++++ grub-core/fs/fat.c | 8 +++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea8804bd1..306358faa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-23 Vladimir Serbinenko + + * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 + if no label is found. + (grub_fat_iterate_dir): Fix file size type. + (grub_fat_iterate_dir): Likewise. + 2011-10-23 Vladimir Serbinenko * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index ae705bcfb..36a43fca0 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -485,7 +485,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, + data->logical_sector_bits + GRUB_DISK_SECTOR_BITS); logical_cluster = offset >> logical_cluster_bits; - offset &= (1 << logical_cluster_bits) - 1; + offset &= (1ULL << logical_cluster_bits) - 1; if (logical_cluster < data->cur_cluster_num) { @@ -631,9 +631,9 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, case 0xc0: node.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster); node.valid_size - = grub_cpu_to_le32 (sec.type_specific.stream_extension.valid_size); + = grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size); node.file_size - = grub_cpu_to_le32 (sec.type_specific.stream_extension.file_size); + = grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size); node.have_stream = 1; break; case 0xc1: @@ -1026,6 +1026,8 @@ grub_fat_label (grub_device_t device, char **label) if (! data) return grub_errno; + *label = NULL; + while (1) { offset += sizeof (dir); From e0864e7ab7b79f2f08ab749e6be84dadfa0119e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 10:45:47 +0200 Subject: [PATCH 1271/1414] Minix FS fixes. * grub-core/fs/minix.c (GRUB_MINIX_INODE_SIZE): Size is always 32-bit. (grub_minix_inode) [!MODE_MINIX2 && !MODE_MINIX3]: Make size 32-bit. Rename ctime to mtime. All users updated. (grub_minix_get_file_block): Fix types and double indirect computations. --- ChangeLog | 9 +++++++++ grub-core/fs/minix.c | 34 ++++++++++++++++------------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 306358faa..9065162fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-24 Vladimir Serbinenko + + Minix FS fixes. + + * grub-core/fs/minix.c (GRUB_MINIX_INODE_SIZE): Size is always 32-bit. + (grub_minix_inode) [!MODE_MINIX2 && !MODE_MINIX3]: Make size 32-bit. + Rename ctime to mtime. All users updated. + (grub_minix_get_file_block): Fix types and double indirect computations. + 2011-10-23 Vladimir Serbinenko * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 055f89095..1db2883cd 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -63,7 +63,7 @@ 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_SIZE(data) (grub_le_to_cpu32 (data->inode.size)) #define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode)) #define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \ (data->inode.dir_zones[blk])) @@ -133,15 +133,14 @@ struct grub_minix_inode grub_uint32_t indir_zone; grub_uint32_t double_indir_zone; 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_uint32_t size; + grub_uint32_t mtime; grub_uint8_t gid; grub_uint8_t nlinks; grub_uint16_t dir_zones[7]; @@ -168,15 +167,19 @@ static grub_dl_t my_mod; static grub_err_t grub_minix_find_file (struct grub_minix_data *data, const char *path); -static int +static grub_minix_uintn_t grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) { - int indir; + grub_minix_uintn_t indir; + const grub_uint32_t block_per_zone = (GRUB_MINIX_ZONESZ + / GRUB_MINIX_INODE_BLKSZ (data)); - auto int grub_get_indir (int, int); + auto grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t, + grub_minix_uintn_t); /* Read the block pointer in ZONE, on the offset NUM. */ - int grub_get_indir (int zone, int num) + grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t zone, + grub_minix_uintn_t num) { grub_minix_uintn_t indirn; grub_disk_read (data->disk, @@ -192,21 +195,20 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) /* Indirect block. */ blk -= GRUB_MINIX_INODE_DIR_BLOCKS; - if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) + if (blk < block_per_zone) { indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk); return indir; } /* Double indirect block. */ - blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data); - if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) - * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))) + blk -= block_per_zone; + if (blk < block_per_zone * block_per_zone) { indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data), - blk / GRUB_MINIX_ZONESZ); + blk / block_per_zone); - indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ); + indir = grub_get_indir (indir, blk % block_per_zone); return indir; } @@ -536,11 +538,7 @@ grub_minix_dir (grub_device_t device, const char *path, 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 6e536dc8ad96e3ca1ae878a4250ec87d6bdccb71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 16:16:28 +0200 Subject: [PATCH 1272/1414] Support triple indirect on minix2 and minix3. * grub-core/fs/minix.c (grub_minix_inode) [MODE_MINIX2 || MODE_MINIX3]: Declare triple_indir_zone. (grub_minix_get_file_block) [MODE_MINIX2 || MODE_MINIX3]: Handle triple indirect. --- ChangeLog | 9 +++++++++ grub-core/fs/minix.c | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9065162fe..12117d6a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-24 Vladimir Serbinenko + + Support triple indirect on minix2 and minix3. + + * grub-core/fs/minix.c (grub_minix_inode) [MODE_MINIX2 || MODE_MINIX3]: + Declare triple_indir_zone. + (grub_minix_get_file_block) [MODE_MINIX2 || MODE_MINIX3]: Handle triple + indirect. + 2011-10-24 Vladimir Serbinenko Minix FS fixes. diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 1db2883cd..43785b657 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -132,7 +132,7 @@ struct grub_minix_inode grub_uint32_t dir_zones[7]; grub_uint32_t indir_zone; grub_uint32_t double_indir_zone; - grub_uint32_t unused; + grub_uint32_t triple_indir_zone; }; #else struct grub_minix_inode @@ -213,6 +213,20 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) return indir; } +#if defined (MODE_MINIX3) || defined (MODE_MINIX2) + blk -= block_per_zone * block_per_zone; + if (blk < ((grub_uint64_t) block_per_zone * (grub_uint64_t) block_per_zone + * (grub_uint64_t) block_per_zone)) + { + indir = grub_get_indir (grub_minix_le_to_cpu_n (data->inode.triple_indir_zone), + (blk / block_per_zone) / block_per_zone); + indir = grub_get_indir (indir, (blk / block_per_zone) % block_per_zone); + indir = grub_get_indir (indir, blk % block_per_zone); + + return indir; + } +#endif + /* This should never happen. */ grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size"); From 68c72069d927f5f7c907de32d4d9fa43d453c78c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 17:02:02 +0200 Subject: [PATCH 1273/1414] * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. (grub_jfs_blkno): Fix incorrect shift. (grub_jfs_read_file): Use more appropriate types. --- ChangeLog | 6 ++++++ grub-core/fs/jfs.c | 18 +++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12117d6a0..7d216e1d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-24 Vladimir Serbinenko + + * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. + (grub_jfs_blkno): Fix incorrect shift. + (grub_jfs_read_file): Use more appropriate types. + 2011-10-24 Vladimir Serbinenko Support triple indirect on minix2 and minix3. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index ebc2c688a..4a7bb0214 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -253,11 +253,11 @@ static grub_int64_t grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, grub_uint64_t blk) { - auto int getblk (struct grub_jfs_treehead *treehead, - struct grub_jfs_tree_extent *extents); + auto grub_int64_t getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents); - int getblk (struct grub_jfs_treehead *treehead, - struct grub_jfs_tree_extent *extents) + grub_int64_t getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents) { int found = -1; int i; @@ -269,7 +269,7 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, /* Read the leafnode. */ if (grub_le_to_cpu32 (extents[i].offset2) <= blk && ((grub_le_to_cpu16 (extents[i].extent.length)) - + (extents[i].extent.length2 << 8) + + (extents[i].extent.length2 << 16) + grub_le_to_cpu32 (extents[i].offset2)) > blk) return (blk - grub_le_to_cpu32 (extents[i].offset2) + grub_le_to_cpu32 (extents[i].extent.blk2)); @@ -288,7 +288,7 @@ grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, } tree; if (grub_disk_read (data->disk, - grub_le_to_cpu32 (extents[found].extent.blk2) + ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2)) << (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS), 0, sizeof (tree), (char *) &tree)) @@ -558,10 +558,10 @@ static grub_ssize_t grub_jfs_read_file (struct grub_jfs_data *data, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, unsigned offset, unsigned length), - grub_uint64_t pos, grub_size_t len, char *buf) + grub_off_t pos, grub_size_t len, char *buf) { - grub_uint64_t i; - grub_uint64_t blockcnt; + grub_off_t i; + grub_off_t blockcnt; blockcnt = (len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) >> grub_le_to_cpu16 (data->sblock.log2_blksz); From 5bbd28b8cebbb365faebccf25119a2e6712731ad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 24 Oct 2011 21:33:35 +0200 Subject: [PATCH 1274/1414] Fix 2G limit on ZFS. * grub-core/fs/zfs/zfs.c (zio_checksum_verify): Use more appropriate types. (uberblock_verify): Likewise. (dmu_read): Likewise. (grub_zfs_read): Likewise. Remove invalid cast. --- ChangeLog | 10 ++++++++++ grub-core/fs/zfs/zfs.c | 11 ++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d216e1d7..e8cd7ea77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-24 Vladimir Serbinenko + + Fix 2G limit on ZFS. + + * grub-core/fs/zfs/zfs.c (zio_checksum_verify): Use more appropriate + types. + (uberblock_verify): Likewise. + (dmu_read): Likewise. + (grub_zfs_read): Likewise. Remove invalid cast. + 2011-10-24 Vladimir Serbinenko * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1eea13b26..9d6ad7055 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -242,7 +242,7 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { */ static grub_err_t zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, - grub_zfs_endian_t endian, char *buf, int size) + grub_zfs_endian_t endian, char *buf, grub_size_t size) { zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; @@ -337,7 +337,7 @@ vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) * */ static grub_err_t -uberblock_verify (uberblock_phys_t * ub, int offset) +uberblock_verify (uberblock_phys_t * ub, grub_uint64_t offset) { uberblock_t *uber = &ub->ubp_uberblock; grub_err_t err; @@ -620,7 +620,8 @@ static grub_err_t dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, grub_zfs_endian_t *endian_out, struct grub_zfs_data *data) { - int idx, level; + int level; + grub_off_t idx; blkptr_t *bp_array = dn->dn.dn_blkptr; int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT; blkptr_t *bp; @@ -2266,7 +2267,7 @@ static grub_ssize_t grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_zfs_data *data = (struct grub_zfs_data *) file->data; - int blksz, movesize; + grub_size_t blksz, movesize; grub_size_t length; grub_size_t read; grub_err_t err; @@ -2320,7 +2321,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) data->file_start = blkid * blksz; data->file_end = data->file_start + blksz; - movesize = MIN (length, data->file_end - (int) file->offset - read); + movesize = MIN (length, data->file_end - file->offset - read); grub_memmove (buf, data->file_buf + file->offset + read - data->file_start, movesize); From f4d9b64bba4e748922056437f0408071376c66b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 17:38:22 +0200 Subject: [PATCH 1275/1414] * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. --- ChangeLog | 4 ++++ grub-core/fs/romfs.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index e8cd7ea77..1b1975215 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. + 2011-10-24 Vladimir Serbinenko Fix 2G limit on ZFS. diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 58dc98f34..713e8293f 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -367,6 +367,7 @@ grub_romfs_open (struct grub_file *file, const char *name) file->size = grub_be_to_cpu32 (fdiro->file.size); file->data = fdiro; + return GRUB_ERR_NONE; fail: grub_free (data); From 9f326fba96eb04658e7720585e8ad9c643631ced Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:01:57 +0200 Subject: [PATCH 1276/1414] * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. --- ChangeLog | 4 ++++ grub-core/kern/disk.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1b1975215..7eef0f796 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index f296b9d0f..460d8778f 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -442,6 +442,7 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, } } + grub_free (tmp_buf); grub_errno = GRUB_ERR_NONE; { @@ -468,9 +469,11 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, grub_error_push (); grub_dprintf ("disk", "%s read failed\n", disk->name); grub_error_pop (); + grub_free (tmp_buf); return grub_errno; } grub_memcpy (buf, tmp_buf + offset, size); + grub_free (tmp_buf); return GRUB_ERR_NONE; } } From 9f12e664cc1b815cc01000cf87559a3c303de2e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:09:00 +0200 Subject: [PATCH 1277/1414] Fix handling of uncompressed blocks on squashfs and break 4G limit. * grub-core/fs/squash4.c (grub_squash_super): Add block_size. Remove unused flags. (grub_squash_inode): Add long_file and block_size. (grub_squash_cache_inode): New struct. (grub_squash_dirent): Make types into enum. (SQUASH_TYPE_LONG_REGULAR): New type. (grub_squash_frag_desc): Add field size. (SQUASH_BLOCK_FLAGS): New enum. (grub_squash_data): Use grub_squash_cache_inode. (grub_fshelp_node): Make ino_chunk 64-bit. (read_chunk): Minor argument change. All users updated. (squash_mount): Use correct le_to_cpu. (grub_squash_open): Handle LONG_REGULAR. (direct_read): New function. (grub_squash_read_data): Handle blocks correctly. --- ChangeLog | 20 ++++ grub-core/fs/squash4.c | 254 ++++++++++++++++++++++++++++++++--------- 2 files changed, 223 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7eef0f796..586de218f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-10-25 Vladimir Serbinenko + + Fix handling of uncompressed blocks on squashfs and break 4G limit. + + * grub-core/fs/squash4.c (grub_squash_super): Add block_size. Remove + unused flags. + (grub_squash_inode): Add long_file and block_size. + (grub_squash_cache_inode): New struct. + (grub_squash_dirent): Make types into enum. + (SQUASH_TYPE_LONG_REGULAR): New type. + (grub_squash_frag_desc): Add field size. + (SQUASH_BLOCK_FLAGS): New enum. + (grub_squash_data): Use grub_squash_cache_inode. + (grub_fshelp_node): Make ino_chunk 64-bit. + (read_chunk): Minor argument change. All users updated. + (squash_mount): Use correct le_to_cpu. + (grub_squash_open): Handle LONG_REGULAR. + (direct_read): New function. + (grub_squash_read_data): Handle blocks correctly. + 2011-10-25 Vladimir Serbinenko * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 4f1265582..d45732c16 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -42,7 +42,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); exttblptr RAW superblock UID/GID table is the array ot uint32_t - unk1 contains pointer to unk3 followed by some chunk. + unk1 contains pointer to fragment table followed by some chunk. unk2 containts one uint64_t */ @@ -52,13 +52,9 @@ struct grub_squash_super #define SQUASH_MAGIC 0x73717368 grub_uint32_t dummy1; grub_uint32_t creation_time; - grub_uint32_t dummy2; + grub_uint32_t block_size; 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_uint64_t dummy4; grub_uint16_t root_ino_offset; grub_uint32_t root_ino_chunk; grub_uint16_t dummy5; @@ -71,7 +67,6 @@ struct grub_squash_super grub_uint64_t unk2offset; } __attribute__ ((packed)); - /* Chunk-based */ struct grub_squash_inode { @@ -87,7 +82,18 @@ struct grub_squash_inode grub_uint32_t fragment; grub_uint32_t offset; grub_uint32_t size; + grub_uint32_t block_size[0]; } __attribute__ ((packed)) file; + struct { + grub_uint32_t dummy; + grub_uint64_t chunk; + grub_uint64_t size; + grub_uint32_t dummy2[3]; + grub_uint32_t fragment; + grub_uint32_t offset; + grub_uint32_t dummy3; + grub_uint32_t block_size[0]; + } __attribute__ ((packed)) long_file; struct { grub_uint32_t dummy1; grub_uint32_t chunk; @@ -104,6 +110,15 @@ struct grub_squash_inode } __attribute__ ((packed)); } __attribute__ ((packed)); +struct grub_squash_cache_inode +{ + struct grub_squash_inode ino; + grub_disk_addr_t ino_chunk; + grub_uint16_t ino_offset; + grub_uint32_t *block_sizes; + grub_disk_addr_t *cumulated_block_sizes; +}; + /* Chunk-based. */ struct grub_squash_dirent_header { @@ -117,29 +132,46 @@ struct grub_squash_dirent grub_uint16_t ino_offset; grub_uint16_t dummy; 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]; } __attribute__ ((packed)); +enum + { + SQUASH_TYPE_DIR = 1, + SQUASH_TYPE_REGULAR = 2, + SQUASH_TYPE_SYMLINK = 3, + SQUASH_TYPE_LONG_REGULAR = 9, + }; + + struct grub_squash_frag_desc { grub_uint64_t offset; - grub_uint64_t dummy; + grub_uint32_t size; + grub_uint32_t dummy; } __attribute__ ((packed)); +enum + { + SQUASH_CHUNK_FLAGS = 0x8000, + SQUASH_CHUNK_UNCOMPRESSED = 0x8000 + }; + +enum + { + SQUASH_BLOCK_FLAGS = 0x1000000, + SQUASH_BLOCK_UNCOMPRESSED = 0x1000000 + }; + #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; + struct grub_squash_cache_inode ino; grub_uint64_t fragments; }; @@ -147,12 +179,12 @@ struct grub_fshelp_node { struct grub_squash_data *data; struct grub_squash_inode ino; - grub_uint32_t ino_chunk; + grub_disk_addr_t ino_chunk; grub_uint16_t ino_offset; }; static grub_err_t -read_chunk (grub_disk_t disk, void *buf, grub_size_t len, +read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, grub_uint64_t chunk, grub_off_t offset) { grub_uint64_t chunk_start; @@ -164,7 +196,8 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, grub_err_t err; while (1) { - err = grub_disk_read (disk, chunk_start >> GRUB_DISK_SECTOR_BITS, + err = grub_disk_read (data->disk, + chunk_start >> GRUB_DISK_SECTOR_BITS, chunk_start & (GRUB_DISK_SECTOR_SIZE - 1), sizeof (d), &d); if (err) @@ -182,7 +215,7 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t 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), + err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), a & (GRUB_DISK_SECTOR_SIZE - 1), csize, buf); if (err) @@ -197,7 +230,7 @@ read_chunk (grub_disk_t disk, void *buf, grub_size_t len, if (!tmp) return grub_errno; /* FIXME: buffer uncompressed data. */ - err = grub_disk_read (disk, (a >> GRUB_DISK_SECTOR_BITS), + err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), a & (GRUB_DISK_SECTOR_SIZE - 1), bsize, tmp); if (err) @@ -240,9 +273,10 @@ squash_mount (grub_disk_t disk) return NULL; } - err = grub_disk_read (disk, grub_le_to_cpu32 (sb.unk1offset) + err = grub_disk_read (disk, + grub_le_to_cpu64 (sb.unk1offset) >> GRUB_DISK_SECTOR_BITS, - grub_le_to_cpu32 (sb.unk1offset) + grub_le_to_cpu64 (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"); @@ -254,7 +288,7 @@ squash_mount (grub_disk_t disk) return NULL; data->sb = sb; data->disk = disk; - data->fragments = frag; + data->fragments = grub_le_to_cpu64 (frag); return data; } @@ -266,7 +300,7 @@ grub_squash_read_symlink (grub_fshelp_node_t node) grub_err_t err; ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); - err = read_chunk (node->data->disk, ret, + err = read_chunk (node->data, ret, grub_le_to_cpu32 (node->ino.symlink.namelen), grub_le_to_cpu64 (node->data->sb.inodeoffset) + node->ino_chunk, @@ -300,7 +334,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, struct grub_squash_dirent_header dh; grub_err_t err; - err = read_chunk (dir->data->disk, &dh, sizeof (dh), + err = read_chunk (dir->data, &dh, sizeof (dh), grub_le_to_cpu64 (dir->data->sb.diroffset) + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) @@ -315,14 +349,14 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, struct grub_squash_dirent di; struct grub_squash_inode ino; - err = read_chunk (dir->data->disk, &di, sizeof (di), + err = read_chunk (dir->data, &di, sizeof (di), grub_le_to_cpu64 (dir->data->sb.diroffset) + grub_le_to_cpu32 (dir->ino.dir.chunk), off); if (err) return 0; off += sizeof (di); - err = read_chunk (dir->data->disk, &ino, sizeof (ino), + err = read_chunk (dir->data, &ino, sizeof (ino), grub_le_to_cpu64 (dir->data->sb.inodeoffset) + grub_le_to_cpu32 (dh.ino_chunk), grub_cpu_to_le16 (di.ino_offset)); @@ -332,7 +366,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2); if (!buf) return 0; - err = read_chunk (dir->data->disk, buf, + err = read_chunk (dir->data, buf, grub_le_to_cpu16 (di.namelen) + 1, grub_le_to_cpu64 (dir->data->sb.diroffset) + grub_le_to_cpu32 (dir->ino.dir.chunk), off); @@ -370,7 +404,7 @@ 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), + return read_chunk (data, &root->ino, sizeof (root->ino), 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)); @@ -445,48 +479,166 @@ 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.file.size); + data->ino.ino = fdiro->ino; + data->ino.block_sizes = NULL; + data->ino.cumulated_block_sizes = NULL; + data->ino.ino_chunk = fdiro->ino_chunk; + data->ino.ino_offset = fdiro->ino_offset; + + if (fdiro->ino.type + == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + file->size = grub_le_to_cpu64 (fdiro->ino.long_file.size); + else + file->size = grub_le_to_cpu32 (fdiro->ino.file.size); return GRUB_ERR_NONE; } +static grub_ssize_t +direct_read (struct grub_squash_data *data, + struct grub_squash_cache_inode *ino, + grub_off_t off, char *buf, grub_size_t len) +{ + grub_err_t err; + grub_off_t cumulated_uncompressed_size = 0; + grub_uint64_t a; + grub_size_t i; + grub_size_t origlen = len; + + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + a = grub_le_to_cpu64 (ino->ino.long_file.chunk); + else + a = grub_le_to_cpu32 (ino->ino.file.chunk); + + if (!ino->block_sizes) + { + grub_off_t total_size; + grub_size_t total_blocks; + grub_size_t block_offset; + if (ino->ino.type + == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + { + total_size = grub_le_to_cpu64 (ino->ino.long_file.size); + block_offset = ((char *) &ino->ino.long_file.block_size + - (char *) &ino->ino); + } + else + { + total_size = grub_le_to_cpu32 (ino->ino.file.size); + block_offset = ((char *) &ino->ino.file.block_size + - (char *) &ino->ino); + } + total_blocks = grub_divmod64 (total_size + + grub_le_to_cpu32 (data->sb.block_size) - 1, + grub_le_to_cpu32 (data->sb.block_size), + 0); + ino->block_sizes = grub_malloc (total_blocks + * sizeof (ino->block_sizes[0])); + ino->cumulated_block_sizes = grub_malloc (total_blocks + * sizeof (ino->cumulated_block_sizes[0])); + if (!ino->block_sizes || !ino->cumulated_block_sizes) + { + grub_free (ino->block_sizes); + grub_free (ino->cumulated_block_sizes); + ino->block_sizes = 0; + ino->cumulated_block_sizes = 0; + return -1; + } + err = read_chunk (data, ino->block_sizes, + total_blocks * sizeof (ino->block_sizes[0]), + grub_le_to_cpu64 (data->sb.inodeoffset) + + ino->ino_chunk, + ino->ino_offset + block_offset); + if (err) + { + grub_free (ino->block_sizes); + grub_free (ino->cumulated_block_sizes); + ino->block_sizes = 0; + ino->cumulated_block_sizes = 0; + return -1; + } + ino->cumulated_block_sizes[0] = 0; + for (i = 1; i < total_blocks; i++) + ino->cumulated_block_sizes[i] = ino->cumulated_block_sizes[i - 1] + + (grub_le_to_cpu32 (ino->block_sizes[i - 1]) & ~SQUASH_BLOCK_FLAGS); + } + + if (a == 0) + a = sizeof (struct grub_squash_super); + i = grub_divmod64 (off, grub_le_to_cpu32 (data->sb.block_size), 0); + cumulated_uncompressed_size = grub_le_to_cpu32 (data->sb.block_size) + * (grub_disk_addr_t) i; + while (cumulated_uncompressed_size < off + len) + { + grub_size_t boff, read; + boff = off - cumulated_uncompressed_size; + read = grub_le_to_cpu32 (data->sb.block_size) - boff; + if (read > len) + read = len; + if (!(ino->block_sizes[i] & SQUASH_BLOCK_UNCOMPRESSED)) + err = grub_zlib_disk_read (data->disk, + ino->cumulated_block_sizes[i] + a, + boff, buf, read); + else + err = grub_disk_read (data->disk, + (ino->cumulated_block_sizes[i] + a + boff) + >> GRUB_DISK_SECTOR_BITS, + (ino->cumulated_block_sizes[i] + a + boff) + & (GRUB_DISK_SECTOR_SIZE - 1), + read, buf); + if (err) + return -1; + off += read; + len -= read; + buf += read; + cumulated_uncompressed_size += grub_le_to_cpu32 (data->sb.block_size); + i++; + } + return origlen; +} + + static grub_ssize_t grub_squash_read_data (struct grub_squash_data *data, - grub_disk_t disk, const struct grub_squash_inode *ino, + struct grub_squash_cache_inode *ino, grub_off_t off, char *buf, grub_size_t len) { grub_err_t err; grub_uint64_t a, b; + grub_uint32_t fragment; int compressed = 0; + struct grub_squash_frag_desc frag; - if (grub_le_to_cpu16 (ino->file.fragment) == 0xffff) + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) { - 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); + a = grub_le_to_cpu64 (ino->ino.long_file.chunk); + fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment); } else { - struct grub_squash_frag_desc frag; - err = read_chunk (disk, &frag, sizeof (frag), - data->fragments, sizeof (frag) - * grub_le_to_cpu16 (ino->file.fragment)); - if (err) - return -1; - a = grub_le_to_cpu64 (frag.offset) + grub_le_to_cpu32 (ino->file.chunk); - compressed = !(data->sb.flags & SQUASH_FLAG_UNCOMPRESSED_FRAGMENTS); + a = grub_le_to_cpu32 (ino->ino.file.chunk); + fragment = grub_le_to_cpu32 (ino->ino.file.fragment); } - b = grub_le_to_cpu32 (data->ino.file.offset) + off; - + if (fragment == 0xffffffff) + return direct_read (data, ino, off, buf, len); + + err = read_chunk (data, &frag, sizeof (frag), + data->fragments, sizeof (frag) * fragment); + if (err) + return -1; + a += grub_le_to_cpu64 (frag.offset); + compressed = !(frag.size & SQUASH_BLOCK_UNCOMPRESSED); + if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) + b = grub_le_to_cpu64 (ino->ino.long_file.offset) + off; + else + b = grub_le_to_cpu32 (ino->ino.file.offset) + off; + /* FIXME: cache uncompressed chunks. */ if (compressed) - err = grub_zlib_disk_read (disk, a, b, buf, len); + err = grub_zlib_disk_read (data->disk, a, b, buf, len); else - err = grub_disk_read (disk, (a + b) >> GRUB_DISK_SECTOR_BITS, + err = grub_disk_read (data->disk, (a + b) >> GRUB_DISK_SECTOR_BITS, (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); if (err) return -1; @@ -498,7 +650,7 @@ 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, + return grub_squash_read_data (data, &data->ino, file->offset, buf, len); } From d4888031f2577c86f354393bf4e2e5f22ea25bd4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:12:36 +0200 Subject: [PATCH 1278/1414] Fix tar 4G limit and handle paths containing dot. * grub-core/fs/cpio.c (grub_cpio_data): Use grub_off_t for offsets. (canonicalize): New function. (grub_cpio_find_file): Use canonicalize. Store offs in grub_disk_addr_t. (grub_cpio_dir): Use grub_disk_addr_t. (grub_cpio_open): Likewise. --- ChangeLog | 11 ++++ grub-core/fs/cpio.c | 134 ++++++++++++++++++++++++++------------------ 2 files changed, 89 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 586de218f..19bf1326e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-10-25 Vladimir Serbinenko + + Fix tar 4G limit and handle paths containing dot. + + * grub-core/fs/cpio.c (grub_cpio_data): Use grub_off_t for offsets. + (canonicalize): New function. + (grub_cpio_find_file): Use canonicalize. Store offs in + grub_disk_addr_t. + (grub_cpio_dir): Use grub_disk_addr_t. + (grub_cpio_open): Likewise. + 2011-10-25 Vladimir Serbinenko Fix handling of uncompressed blocks on squashfs and break 4G limit. diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 0d84382ac..92531390e 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -71,80 +71,102 @@ struct head struct grub_cpio_data { grub_disk_t disk; - grub_uint32_t hofs; - grub_uint32_t dofs; - grub_uint32_t size; + grub_off_t hofs; + grub_off_t dofs; + grub_off_t size; }; static grub_dl_t my_mod; +static inline void +canonicalize (char *name) +{ + char *iptr, *optr; + for (iptr = name, optr = name; *iptr; ) + { + while (*iptr == '/') + iptr++; + if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0)) + { + iptr += 2; + continue; + } + while (*iptr && *iptr != '/') + *optr++ = *iptr++; + if (*iptr) + *optr++ = *iptr++; + } + *optr = 0; +} + static grub_err_t grub_cpio_find_file (struct grub_cpio_data *data, char **name, - grub_int32_t *mtime, grub_uint32_t * ofs) + grub_int32_t *mtime, grub_disk_addr_t * ofs) { #ifndef MODE_USTAR - struct head hd; + struct head hd; - if (grub_disk_read - (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; + if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) + return grub_errno; - if (hd.magic != MAGIC_BCPIO) - return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); + if (hd.magic != MAGIC_BCPIO) + 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; + 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++; + if (hd.namesize & 1) + hd.namesize++; - if ((*name = grub_malloc (hd.namesize)) == NULL) - return grub_errno; + if ((*name = grub_malloc (hd.namesize)) == NULL) + return grub_errno; - if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), - hd.namesize, *name)) - { - grub_free (*name); - return grub_errno; - } + if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), + hd.namesize, *name)) + { + grub_free (*name); + return grub_errno; + } - if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 - && ! grub_memcmp(*name, "TRAILER!!!", 11)) - { - *ofs = 0; - return GRUB_ERR_NONE; - } + if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 + && ! grub_memcmp(*name, "TRAILER!!!", 11)) + { + *ofs = 0; + return GRUB_ERR_NONE; + } - data->dofs = data->hofs + sizeof (hd) + hd.namesize; - *ofs = data->dofs + data->size; - if (data->size & 1) - (*ofs)++; + canonicalize (*name); + + data->dofs = data->hofs + sizeof (hd) + hd.namesize; + *ofs = data->dofs + data->size; + if (data->size & 1) + (*ofs)++; #else - struct head hd; + struct head hd; - if (grub_disk_read - (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; + if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) + return grub_errno; - if (!hd.name[0]) - { - *ofs = 0; - return GRUB_ERR_NONE; - } + if (!hd.name[0]) + { + *ofs = 0; + return GRUB_ERR_NONE; + } - if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) - return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); + if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) + return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); - if ((*name = grub_strdup (hd.name)) == NULL) - return grub_errno; + if ((*name = grub_strdup (hd.name)) == NULL) + return grub_errno; - data->size = grub_strtoul (hd.size, NULL, 8); - 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); + data->size = grub_strtoull (hd.size, NULL, 8); + 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); + canonicalize (*name); #endif return GRUB_ERR_NONE; } @@ -191,10 +213,10 @@ grub_cpio_dir (grub_device_t device, const char *path, const struct grub_dirhook_info *info)) { struct grub_cpio_data *data; - grub_uint32_t ofs; + grub_disk_addr_t ofs; char *prev, *name; const char *np; - int len; + grub_size_t len; grub_dl_ref (my_mod); @@ -230,7 +252,7 @@ grub_cpio_dir (grub_device_t device, const char *path, if (p) *p = 0; - if ((!prev) || (grub_strcmp (prev, name) != 0)) + if (((!prev) || (grub_strcmp (prev, name) != 0)) && name[len] != 0) { struct grub_dirhook_info info; grub_memset (&info, 0, sizeof (info)); @@ -262,7 +284,7 @@ static grub_err_t grub_cpio_open (grub_file_t file, const char *name) { struct grub_cpio_data *data; - grub_uint32_t ofs; + grub_disk_addr_t ofs; char *fn; int i, j; From e12119495df2f7213169985c10889ec46b205b8e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:18:58 +0200 Subject: [PATCH 1279/1414] Support multi-extent iso files. * grub-core/fs/iso9660.c (grub_iso9660_data): Remove first_sector. Add node. (grub_fshelp_node): Revamp. All users updated. (FLAG_*): New enum. (read_node): New function. (grub_iso9660_susp_iterate): Use read_node. Receive a node as argument. All users updated. (grub_iso9660_mount): Don't attempt to read sua when there is none. (get_node_size): New function. (grub_iso9660_iterate_dir): Use read_node. Agglomerate multi-extent entries. Fix memory leak on . and .. (grub_iso9660_read): Use read_node. (grub_iso9660_close): Free node. --- ChangeLog | 19 ++++ grub-core/fs/iso9660.c | 208 +++++++++++++++++++++++++++++------------ 2 files changed, 167 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19bf1326e..a9b26a313 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-10-25 Vladimir Serbinenko + + Support multi-extent iso files. + + * grub-core/fs/iso9660.c (grub_iso9660_data): Remove first_sector. + Add node. + (grub_fshelp_node): Revamp. All users updated. + (FLAG_*): New enum. + (read_node): New function. + (grub_iso9660_susp_iterate): Use read_node. Receive a node as argument. + All users updated. + (grub_iso9660_mount): Don't attempt to read sua when there is none. + (get_node_size): New function. + (grub_iso9660_iterate_dir): Use read_node. Agglomerate multi-extent + entries. + Fix memory leak on . and .. + (grub_iso9660_read): Use read_node. + (grub_iso9660_close): Free node. + 2011-10-25 Vladimir Serbinenko Fix tar 4G limit and handle paths containing dot. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 5b53ca597..f6cbbca95 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -149,22 +149,28 @@ struct grub_iso9660_data { struct grub_iso9660_primary_voldesc voldesc; grub_disk_t disk; - unsigned int first_sector; int rockridge; int susp_skip; int joliet; + struct grub_fshelp_node *node; }; struct grub_fshelp_node { struct grub_iso9660_data *data; - struct grub_iso9660_dir dirent; - unsigned int size; - unsigned int blk; - unsigned int dir_blk; - unsigned int dir_off; + grub_size_t have_dirents, alloc_dirents; + grub_off_t dir_off; + struct grub_iso9660_dir dirents[8]; }; +enum + { + FLAG_TYPE_PLAIN = 0, + FLAG_TYPE_DIR = 2, + FLAG_TYPE = 3, + FLAG_MORE_EXTENTS = 0x80 + }; + static grub_dl_t my_mod; @@ -214,30 +220,69 @@ iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) return 1; } +static grub_err_t +read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) +{ + grub_size_t i = 0; + + while (len > 0) + { + grub_size_t toread; + grub_err_t err; + while (i < node->have_dirents + && off >= grub_le_to_cpu32 (node->dirents[i].size)) + { + off -= grub_le_to_cpu32 (node->dirents[i].size); + i++; + } + if (i == node->have_dirents) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range"); + toread = grub_le_to_cpu32 (node->dirents[i].size); + if (toread > len) + toread = len; + err = grub_disk_read (node->data->disk, + ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ, + off, toread, buf); + if (err) + return err; + len -= toread; + off += toread; + buf += toread; + } + return GRUB_ERR_NONE; +} + /* 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. */ static grub_err_t -grub_iso9660_susp_iterate (struct grub_iso9660_data *data, - int sua_block, int sua_pos, int sua_size, +grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + grub_size_t sua_size, grub_err_t (*hook) (struct grub_iso9660_susp_entry *entry)) { char *sua; struct grub_iso9660_susp_entry *entry; + grub_disk_addr_t ce_block; + int is_ce = 0; auto grub_err_t load_sua (void); /* Load a part of the System Usage Area. */ grub_err_t load_sua (void) { + grub_err_t err; sua = grub_malloc (sua_size); if (!sua) return grub_errno; - if (grub_disk_read (data->disk, sua_block, sua_pos, - sua_size, sua)) - return grub_errno; + if (is_ce) + err = grub_disk_read (node->data->disk, ce_block, off, + sua_size, sua); + else + err = read_node (node, off, sua_size, sua); + if (err) + return err; entry = (struct grub_iso9660_susp_entry *) sua; return 0; @@ -259,10 +304,11 @@ grub_iso9660_susp_iterate (struct grub_iso9660_data *data, { struct grub_iso9660_susp_ce *ce; + is_ce = 1; ce = (struct grub_iso9660_susp_ce *) entry; sua_size = grub_le_to_cpu32 (ce->len); - sua_pos = grub_le_to_cpu32 (ce->off); - sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + off = grub_le_to_cpu32 (ce->off); + ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; grub_free (sua); if (load_sua ()) @@ -383,6 +429,9 @@ grub_iso9660_mount (grub_disk_t disk) + (rootdir.namelen % 2) - 1); sua_size = rootdir.len - sua_pos; + if (!sua_size) + return data; + sua = grub_malloc (sua_size); if (! sua) goto fail; @@ -400,6 +449,14 @@ grub_iso9660_mount (grub_disk_t disk) /* Test if the SUSP protocol is used on this filesystem. */ if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.dir_off = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + /* The 2nd data byte stored how many bytes are skipped every time to get to the SUA (System Usage Area). */ data->susp_skip = entry->data[2]; @@ -407,9 +464,7 @@ grub_iso9660_mount (grub_disk_t disk) /* Iterate over the entries in the SUA area to detect extensions. */ - if (grub_iso9660_susp_iterate (data, - (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), + if (grub_iso9660_susp_iterate (&rootnode, sua_pos, sua_size, susp_iterate)) goto fail; } @@ -502,10 +557,10 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) return 0; } - sua_off = (sizeof (node->dirent) + node->dirent.namelen + 1 - - (node->dirent.namelen % 2) + sua_off = (sizeof (node->dirents[0]) + node->dirents[0].namelen + 1 + - (node->dirents[0].namelen % 2) + node->data->susp_skip); - sua_size = node->dirent.len - sua_off; + sua_size = node->dirents[0].len - sua_off; symlink = grub_malloc (1); if (!symlink) @@ -513,8 +568,7 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) *symlink = '\0'; - if (grub_iso9660_susp_iterate (node->data, node->dir_blk, - node->dir_off + sua_off, + if (grub_iso9660_susp_iterate (node, node->dir_off + sua_off, sua_size, susp_iterate_sl)) { grub_free (symlink); @@ -524,6 +578,16 @@ grub_iso9660_read_symlink (grub_fshelp_node_t node) return symlink; } +static grub_off_t +get_node_size (grub_fshelp_node_t node) +{ + grub_off_t ret = 0; + grub_size_t i; + + for (i = 0; i < node->have_dirents; i++) + ret += grub_le_to_cpu32 (node->dirents[i].size); + return ret; +} static int grub_iso9660_iterate_dir (grub_fshelp_node_t dir, @@ -533,10 +597,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_node_t node)) { struct grub_iso9660_dir dirent; - unsigned int offset = 0; + grub_off_t offset = 0; char *filename; int filename_alloc = 0; enum grub_fshelp_filetype type; + grub_off_t len; auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *); @@ -598,13 +663,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, return 0; } - for (; offset < dir->size; offset += dirent.len) + len = get_node_size (dir); + + for (; offset < len; offset += dirent.len) { - if (grub_disk_read (dir->data->disk, - (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + offset / GRUB_DISK_SECTOR_SIZE, - offset % GRUB_DISK_SECTOR_SIZE, - sizeof (dirent), (char *) &dirent)) + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; /* The end of the block, skip to the next one. */ @@ -629,39 +692,30 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, type = GRUB_FSHELP_UNKNOWN; if (dir->data->rockridge - && grub_iso9660_susp_iterate (dir->data, - (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + (sua_off - / GRUB_DISK_SECTOR_SIZE), - sua_off % GRUB_DISK_SECTOR_SIZE, - sua_size, susp_iterate_dir)) + && grub_iso9660_susp_iterate (dir, sua_off, sua_size, + susp_iterate_dir)) return 0; /* Read the name. */ - if (grub_disk_read (dir->data->disk, - (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + nameoffset / GRUB_DISK_SECTOR_SIZE, - nameoffset % GRUB_DISK_SECTOR_SIZE, - dirent.namelen, (char *) name)) + if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) return 0; node = grub_malloc (sizeof (struct grub_fshelp_node)); if (!node) return 0; + node->alloc_dirents = ARRAY_SIZE (node->dirents); + node->have_dirents = 1; + /* Setup a new node. */ node->data = dir->data; - node->size = grub_le_to_cpu32 (dirent.size); - node->blk = grub_le_to_cpu32 (dirent.first_sector); - node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ) - + offset / GRUB_DISK_SECTOR_SIZE); - node->dir_off = offset % GRUB_DISK_SECTOR_SIZE; + node->dir_off = offset; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ if (type == GRUB_FSHELP_UNKNOWN) { - if ((dirent.flags & 3) == 2) + if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) type = GRUB_FSHELP_DIR; else type = GRUB_FSHELP_REG; @@ -678,7 +732,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* . and .. */ if (dirent.namelen == 1 && (name[0] == 0 || name[0] == 1)) - continue; + { + grub_free (node); + continue; + } else filename = name; } @@ -701,7 +758,35 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename_alloc = 1; } - node->dirent = dirent; + node->dirents[0] = dirent; + while (dirent.flags & FLAG_MORE_EXTENTS) + { + offset += dirent.len; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + { + if (filename_alloc) + grub_free (filename); + grub_free (node); + return 0; + } + if (node->have_dirents >= node->alloc_dirents) + { + struct grub_fshelp_node *new_node; + node->alloc_dirents *= 2; + new_node = grub_malloc (sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); + if (!new_node) + { + if (filename_alloc) + grub_free (filename); + grub_free (node); + return 0; + } + } + node->dirents[node->have_dirents++] = dirent; + } if (hook (filename, type, node)) { if (filename_alloc) @@ -738,7 +823,7 @@ grub_iso9660_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 = !!iso9660_to_unixtime2 (&node->dirent.mtime, &info.mtime); + info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); grub_free (node); return hook (filename, &info); @@ -751,8 +836,10 @@ grub_iso9660_dir (grub_device_t device, const char *path, goto fail; rootnode.data = data; - rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector); - rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size); + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.dir_off = 0; + rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ if (grub_fshelp_find_file (path, &rootnode, @@ -792,8 +879,10 @@ grub_iso9660_open (struct grub_file *file, const char *name) goto fail; rootnode.data = data; - rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector); - rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size); + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.dir_off = 0; + rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ if (grub_fshelp_find_file (name, &rootnode, @@ -803,10 +892,9 @@ grub_iso9660_open (struct grub_file *file, const char *name) GRUB_FSHELP_REG)) goto fail; - data->first_sector = foundnode->blk; - + data->node = foundnode; file->data = data; - file->size = foundnode->size; + file->size = get_node_size (foundnode); file->offset = 0; return 0; @@ -828,10 +916,7 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) /* XXX: The file is stored in as a single extent. */ data->disk->read_hook = file->read_hook; - grub_disk_read (data->disk, - data->first_sector << GRUB_ISO9660_LOG2_BLKSZ, - file->offset, - len, buf); + read_node (data->node, file->offset, len, buf); data->disk->read_hook = NULL; if (grub_errno) @@ -844,7 +929,10 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_iso9660_close (grub_file_t file) { - grub_free (file->data); + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + grub_free (data->node); + grub_free (data); grub_dl_unref (my_mod); From db82136381f991edb8fe9bb28406a03ec1d19e2d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 18:20:39 +0200 Subject: [PATCH 1280/1414] * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): Use union to avoid breaking strict-aliasing rules. --- ChangeLog | 5 +++++ grub-core/loader/i386/bsd.c | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9b26a313..8c8af24e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): + Use union to avoid breaking strict-aliasing rules. + 2011-10-25 Vladimir Serbinenko Support multi-extent iso files. diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 18ebeb760..f2d0845f8 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -960,8 +960,10 @@ grub_netbsd_add_boot_disk_and_wedge (void) grub_partition_t part; grub_uint32_t biosdev; grub_uint32_t partmapsector; - struct grub_partition_bsd_disk_label *label; - grub_uint64_t buf[GRUB_DISK_SECTOR_SIZE / 8]; + union { + grub_uint64_t raw[GRUB_DISK_SECTOR_SIZE / 8]; + struct grub_partition_bsd_disk_label label; + } buf; grub_uint8_t *hash; grub_uint64_t ctx[(GRUB_MD_MD5->contextsize + 7) / 8]; @@ -981,7 +983,8 @@ grub_netbsd_add_boot_disk_and_wedge (void) partmapsector = grub_partition_get_start (part->parent) + part->offset; disk->partition = part->parent; - if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf) != GRUB_ERR_NONE) + if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf.raw) + != GRUB_ERR_NONE) goto fail; disk->partition = part; @@ -997,7 +1000,7 @@ grub_netbsd_add_boot_disk_and_wedge (void) biw.matchnblks = 1; GRUB_MD_MD5->init (&ctx); - GRUB_MD_MD5->write (&ctx, buf, GRUB_DISK_SECTOR_SIZE); + GRUB_MD_MD5->write (&ctx, buf.raw, GRUB_DISK_SECTOR_SIZE); GRUB_MD_MD5->final (&ctx); hash = GRUB_MD_MD5->read (&ctx); memcpy (biw.matchhash, hash, 16); @@ -1006,18 +1009,17 @@ grub_netbsd_add_boot_disk_and_wedge (void) } /* Fill bootdisk if this a NetBSD disk label. */ - label = (struct grub_partition_bsd_disk_label *) &buf; if (part->partmap != NULL && (grub_strcmp (part->partmap->name, "netbsd") == 0) && - label->magic == grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) + buf.label.magic == grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) { struct grub_netbsd_btinfo_bootdisk bid; grub_memset (&bid, 0, sizeof (bid)); bid.labelsector = partmapsector; - bid.label.type = label->type; - bid.label.checksum = label->checksum; - memcpy (bid.label.packname, label->packname, 16); + bid.label.type = buf.label.type; + bid.label.checksum = buf.label.checksum; + memcpy (bid.label.packname, buf.label.packname, 16); bid.biosdev = biosdev; bid.partition = part->number; grub_bsd_add_meta (NETBSD_BTINFO_BOOTDISK, &bid, sizeof (bid)); From 66b40850331be5979d85a3d0583c7bd74c704b08 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 21:52:48 +0200 Subject: [PATCH 1281/1414] Fix symlink handling on iso9660. * grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink All users updated. (grub_iso9660_susp_iterate): Accept zero-size iterate. (grub_iso9660_read_symlink): Moved most of code ... (grub_iso9660_iterate_dir): ... here. Fill node->symlink. --- ChangeLog | 10 +++ grub-core/fs/iso9660.c | 182 ++++++++++++++++++----------------------- 2 files changed, 90 insertions(+), 102 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c8af24e4..d40675db7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-25 Vladimir Serbinenko + + Fix symlink handling on iso9660. + + * grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink + All users updated. + (grub_iso9660_susp_iterate): Accept zero-size iterate. + (grub_iso9660_read_symlink): Moved most of code ... + (grub_iso9660_iterate_dir): ... here. Fill node->symlink. + 2011-10-25 Vladimir Serbinenko * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index f6cbbca95..f3e828b89 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -159,7 +159,7 @@ struct grub_fshelp_node { struct grub_iso9660_data *data; grub_size_t have_dirents, alloc_dirents; - grub_off_t dir_off; + char *symlink; struct grub_iso9660_dir dirents[8]; }; @@ -257,7 +257,7 @@ read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) every entry. */ static grub_err_t grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - grub_size_t sua_size, + grub_ssize_t sua_size, grub_err_t (*hook) (struct grub_iso9660_susp_entry *entry)) { @@ -288,6 +288,9 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, return 0; } + if (sua_size <= 0) + return GRUB_ERR_NONE; + if (load_sua ()) return grub_errno; @@ -454,7 +457,7 @@ grub_iso9660_mount (grub_disk_t disk) rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.dir_off = 0; + rootnode.symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* The 2nd data byte stored how many bytes are skipped every time @@ -480,102 +483,7 @@ grub_iso9660_mount (grub_disk_t disk) static char * grub_iso9660_read_symlink (grub_fshelp_node_t node) { - int sua_off; - int sua_size; - char *symlink = 0; - int addslash = 0; - - auto void add_part (const char *part, int len); - auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *); - - /* Extend the symlink. */ - void add_part (const char *part, int len) - { - int size = grub_strlen (symlink); - - symlink = grub_realloc (symlink, size + len + 1); - if (! symlink) - return; - - grub_strncat (symlink, part, len); - } - - /* Read in a symlink. */ - grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry) - { - if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) - { - unsigned int pos = 1; - - /* The symlink is not stored as a POSIX symlink, translate it. */ - while (pos < grub_le_to_cpu32 (entry->len)) - { - if (addslash) - { - add_part ("/", 1); - addslash = 0; - } - - /* The current position is the `Component Flag'. */ - switch (entry->data[pos] & 30) - { - case 0: - { - /* The data on pos + 2 is the actual data, pos + 1 - is the length. Both are part of the `Component - Record'. */ - add_part ((char *) &entry->data[pos + 2], - entry->data[pos + 1]); - if ((entry->data[pos] & 1)) - addslash = 1; - - break; - } - - case 2: - add_part ("./", 2); - break; - - case 4: - add_part ("../", 3); - break; - - case 8: - add_part ("/", 1); - break; - } - /* In pos + 1 the length of the `Component Record' is - stored. */ - pos += entry->data[pos + 1] + 2; - } - - /* Check if `grub_realloc' failed. */ - if (grub_errno) - return grub_errno; - } - - return 0; - } - - sua_off = (sizeof (node->dirents[0]) + node->dirents[0].namelen + 1 - - (node->dirents[0].namelen % 2) - + node->data->susp_skip); - sua_size = node->dirents[0].len - sua_off; - - symlink = grub_malloc (1); - if (!symlink) - return 0; - - *symlink = '\0'; - - if (grub_iso9660_susp_iterate (node, node->dir_off + sua_off, - sua_size, susp_iterate_sl)) - { - grub_free (symlink); - return 0; - } - - return symlink; + return node->symlink ? grub_strdup (node->symlink) : grub_strdup (""); } static grub_off_t @@ -602,6 +510,23 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, int filename_alloc = 0; enum grub_fshelp_filetype type; grub_off_t len; + char *symlink = 0; + int addslash = 0; + + auto void add_part (const char *part, int len); + + /* Extend the symlink. */ + void add_part (const char *part, int len2) + { + int size = symlink ? grub_strlen (symlink) : 0; + + symlink = grub_realloc (symlink, size + len2 + 1); + if (! symlink) + return; + + symlink[size] = 0; + grub_strncat (symlink, part, len2); + } auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *); @@ -659,6 +584,56 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, type = GRUB_FSHELP_UNKNOWN; } } + else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) + { + unsigned int pos = 1; + + /* The symlink is not stored as a POSIX symlink, translate it. */ + while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len)) + { + if (addslash) + { + add_part ("/", 1); + addslash = 0; + } + + /* The current position is the `Component Flag'. */ + switch (entry->data[pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 + is the length. Both are part of the `Component + Record'. */ + add_part ((char *) &entry->data[pos + 2], + entry->data[pos + 1]); + if ((entry->data[pos] & 1)) + addslash = 1; + + break; + } + + case 2: + add_part ("./", 2); + break; + + case 4: + add_part ("../", 3); + break; + + case 8: + add_part ("/", 1); + break; + } + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->data[pos + 1] + 2; + } + + /* Check if `grub_realloc' failed. */ + if (grub_errno) + return grub_errno; + } return 0; } @@ -667,6 +642,9 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, for (; offset < len; offset += dirent.len) { + symlink = 0; + addslash = 0; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; @@ -709,7 +687,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* Setup a new node. */ node->data = dir->data; - node->dir_off = offset; + node->symlink = symlink; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ @@ -838,7 +816,7 @@ grub_iso9660_dir (grub_device_t device, const char *path, rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.dir_off = 0; + rootnode.symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ @@ -881,7 +859,7 @@ grub_iso9660_open (struct grub_file *file, const char *name) rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.dir_off = 0; + rootnode.symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ From 19832ddb37a6e4a034a2501954fd01a8ff935c73 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 25 Oct 2011 21:53:57 +0200 Subject: [PATCH 1282/1414] * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. --- ChangeLog | 4 ++++ grub-core/fs/fat.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index d40675db7..9f05edaa2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. + 2011-10-25 Vladimir Serbinenko Fix symlink handling on iso9660. diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 36a43fca0..fb1113814 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -1117,9 +1117,12 @@ grub_fat_uuid (grub_device_t device, char **uuid) data = grub_fat_mount (disk); if (data) { + char *ptr; *uuid = grub_xasprintf ("%04x-%04x", (grub_uint16_t) (data->uuid >> 16), (grub_uint16_t) data->uuid); + for (ptr = *uuid; ptr && *ptr; ptr++) + *ptr = grub_toupper (*ptr); } else *uuid = NULL; From e9cc6b7b0e26f38b22a72ecc931273b22a9e1d2a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 00:29:46 +0200 Subject: [PATCH 1283/1414] * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. --- ChangeLog | 4 ++++ grub-core/fs/ntfs.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f05edaa2..3b0b4697a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 5d128bcc0..6b8455c34 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -1087,14 +1087,15 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) if (*uuid) for (ptr = *uuid; *ptr; ptr++) *ptr = grub_toupper (*ptr); + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); } else *uuid = NULL; grub_dl_unref (my_mod); - grub_free (data); - return grub_errno; } From 67e2bd718e9ddd0571a28358e8928dc320e2d76e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 00:32:17 +0200 Subject: [PATCH 1284/1414] Read label on HFS+. * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function. (grub_hfsplus_btree_search): Fix types. (grub_hfsplus_label): Implement. --- ChangeLog | 8 ++++ grub-core/fs/hfsplus.c | 87 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b0b4697a..17e215b62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-25 Vladimir Serbinenko + + Read label on HFS+. + + * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function. + (grub_hfsplus_btree_search): Fix types. + (grub_hfsplus_label): Implement. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 245cd93a5..3d9bc42fa 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -553,6 +553,25 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, return diff; } +/* Compare the on disk catalog key KEYA with the catalog key we are + looking for (KEYB). */ +static int +grub_hfsplus_cmp_catkey_id (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb) +{ + struct grub_hfsplus_catkey *catkey_a = &keya->catkey; + struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey; + + /* Safe unsigned comparison */ + grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent); + if (aparent > catkey_b->parent) + return 1; + if (aparent < catkey_b->parent) + return -1; + + return 0; +} + /* Compare the on disk extent overflow key KEYA with the extent overflow key we are looking for (KEYB). */ static int @@ -662,7 +681,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, /* Read a node. */ if (grub_hfsplus_read_file (&btree->file, 0, - (long)currnode * (long)btree->nodesize, + (grub_disk_addr_t) currnode + * (grub_disk_addr_t) btree->nodesize, btree->nodesize, (char *) node) <= 0) { grub_free (node); @@ -961,13 +981,66 @@ grub_hfsplus_dir (grub_device_t device, const char *path, static grub_err_t -grub_hfsplus_label (grub_device_t device __attribute__((unused)) - , char **label __attribute__((unused))) +grub_hfsplus_label (grub_device_t device, char **label) { - /* XXX: It's not documented how to read a label. */ - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "reading the label of a HFS+ " - "partition is not implemented"); + struct grub_hfsplus_data *data; + grub_disk_t disk = device->disk; + struct grub_hfsplus_catkey *catkey; + int i, label_len; + struct grub_hfsplus_key_internal intern; + struct grub_hfsplus_btnode *node; + grub_disk_addr_t ptr; + + *label = 0; + + data = grub_hfsplus_mount (disk); + if (!data) + return grub_errno; + + /* Create a key that points to the label. */ + intern.catkey.parent = 1; + intern.catkey.name = ""; + + /* First lookup the first entry. */ + if (grub_hfsplus_btree_search (&data->catalog_tree, &intern, + grub_hfsplus_cmp_catkey_id, &node, &ptr)) + { + grub_free (data); + return 0; + } + + catkey = (struct grub_hfsplus_catkey *) + grub_hfsplus_btree_recptr (&data->catalog_tree, node, 0); + + label_len = grub_be_to_cpu16 (catkey->namelen); + for (i = 0; i < label_len; i++) + { + catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); + + /* If the name is obviously invalid, skip this node. */ + if (catkey->name[i] == 0) + return 0; + } + + *label = grub_malloc (label_len + 1); + if (! *label) + return grub_errno; + + if (! grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, + label_len)) + { + grub_free (node); + grub_free (*label); + grub_free (data); + *label = 0; + return grub_errno; + } + (*label)[label_len] = '\0'; + + grub_free (node); + grub_free (data); + + return GRUB_ERR_NONE; } /* Get mtime. */ From c0584900ee804a1b8d1a687cfd042321f05f2150 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 00:35:41 +0200 Subject: [PATCH 1285/1414] * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. --- ChangeLog | 4 ++++ grub-core/fs/jfs.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17e215b62..683fd53f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-25 Vladimir Serbinenko + + * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. + 2011-10-25 Vladimir Serbinenko Read label on HFS+. diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 4a7bb0214..c5e82bfec 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -52,9 +52,9 @@ struct grub_jfs_sblock grub_uint32_t blksz; grub_uint16_t log2_blksz; - grub_uint8_t unused[71]; + grub_uint8_t unused[79]; grub_uint8_t volname[11]; - grub_uint8_t unused2[32]; + grub_uint8_t unused2[24]; grub_uint8_t uuid[16]; }; From 5587329c914465659893d484363d919c1fe35c71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 17:32:21 +0200 Subject: [PATCH 1286/1414] ZFS fixes. * grub-core/fs/zfs/zfs.c (fzap_iterate): Fix handling of indexes sharing the same block. Iterate over correct number of indices. (dnode_get_path): Handle symlinks correctly. --- ChangeLog | 8 ++++++ grub-core/fs/zfs/zfs.c | 64 +++++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 683fd53f3..9787d8f9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-25 Vladimir Serbinenko + + ZFS fixes. + + * grub-core/fs/zfs/zfs.c (fzap_iterate): Fix handling of indexes + sharing the same block. Iterate over correct number of indices. + (dnode_get_path): Handle symlinks correctly. + 2011-10-25 Vladimir Serbinenko * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9d6ad7055..6721cddc1 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -941,7 +941,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, { zap_leaf_phys_t *l; void *l_in; - grub_uint64_t idx, blkid; + grub_uint64_t idx, idx2, blkid; grub_uint16_t chunk; int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << DNODE_SHIFT); @@ -964,10 +964,16 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); return 0; } - for (idx = 0; idx < zap->zap_ptrtbl.zt_numblks; idx++) + for (idx = 0; idx < (1ULL << zap->zap_ptrtbl.zt_shift); idx++) { blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))]; + for (idx2 = 0; idx2 < idx; idx2++) + if (blkid == ((grub_uint64_t *) zap)[idx2 + (1 << (blksft - 3 - 1))]) + break; + if (idx2 != idx) + continue; + err = dmu_read (zap_dnode, blkid, &l_in, &endian, data); l = l_in; if (err) @@ -1093,7 +1099,7 @@ zap_iterate (dnode_end_t * zap_dnode, return 0; block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); - grub_dprintf ("zfs", "zap read\n"); + grub_dprintf ("zfs", "zap iterate\n"); if (block_type == ZBT_MICRO) { @@ -1310,22 +1316,55 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, break; *path = ch; -#if 0 - if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa && ch) + if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { + char *sym_value; + grub_size_t avail_in_dnode; + grub_size_t sym_sz; + int free_symval = 0; char *oldpath = path, *oldpathbuf = path_buf; - path = path_buf - = grub_malloc (sizeof (dnode_path->dn.dn.dn_bonus) - - sizeof (znode_phys_t) + grub_strlen (oldpath) + 1); + sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys)); + avail_in_dnode = (char *) (&dnode_path->dn + 1) - sym_value; + + sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian); + + if (sym_sz > avail_in_dnode - 8) + { + grub_size_t block; + grub_size_t blksz; + blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec, + dnode_path->dn.endian) + << SPA_MINBLOCKSHIFT); + + sym_value = grub_malloc (sym_sz); + if (!sym_value) + return grub_errno; + for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++) + { + void *t; + grub_size_t movesize; + + err = dmu_read (&(dnode_path->dn), block, &t, 0, data); + if (err) + return err; + + movesize = MIN (sym_sz - block * blksz, blksz); + + grub_memcpy (sym_value + block * blksz, t, movesize); + grub_free (t); + } + free_symval = 1; + } + path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); if (!path_buf) { grub_free (oldpathbuf); return grub_errno; } - grub_memcpy (path, - (char *) DN_BONUS(&dnode_path->dn.dn) + sizeof (znode_phys_t), - sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)); - path [sizeof (dnode_path->dn.dn.dn_bonus) - sizeof (znode_phys_t)] = 0; + grub_memcpy (path, sym_value, sym_sz); + if (free_symval) + grub_free (sym_value); + path [sym_sz] = 0; grub_memcpy (path + grub_strlen (path), oldpath, grub_strlen (oldpath) + 1); @@ -1343,7 +1382,6 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (dn_new); } } -#endif } if (!err) From a562fbb48b6934f6dcde9030538a0809016a5acb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 19:11:10 +0200 Subject: [PATCH 1287/1414] Bump spa version --- include/grub/zfs/zfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index e1759dbbd..374068d06 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -28,7 +28,7 @@ /* * On-disk version number. */ -#define SPA_VERSION 28ULL +#define SPA_VERSION 31ULL /* * The following are configuration names used in the nvlist describing a pool's From 186b402804c37ff3fda5b2a969d071a978194195 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 26 Oct 2011 19:27:36 +0200 Subject: [PATCH 1288/1414] * include/grub/datetime.h (grub_datetime2unixtime): Fix off-by-one error. --- ChangeLog | 7 ++++++- include/grub/datetime.h | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9787d8f9e..084131202 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2011-10-25 Vladimir Serbinenko +2011-10-26 Vladimir Serbinenko + + * include/grub/datetime.h (grub_datetime2unixtime): Fix off-by-one + error. + +2011-10-26 Vladimir Serbinenko ZFS fixes. diff --git a/include/grub/datetime.h b/include/grub/datetime.h index dea0f8ea9..049dbc227 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -86,13 +86,13 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) 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; + ret = 2 * SECPERYEAR + SECPERDAY; /* Transform C divisions and modulos to mathematical ones */ - y4 = (datetime->year - 1971) / 4; - if (datetime->year < 1971) + y4 = (datetime->year - 1972) / 4; + if (datetime->year < 1972) y4--; - ay = datetime->year - 1971 - 4 * y4; + ay = datetime->year - 1972 - 4 * y4; ret += y4 * SECPER4YEARS; ret += ay * SECPERYEAR; From 34c59654519cc13b25b39b8add54e757526e5bed Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:04:04 +0200 Subject: [PATCH 1289/1414] Support version 33 including symlinks --- grub-core/fs/zfs/zfs.c | 149 ++++++++++++++++++++++++++++++++++--- include/grub/zfs/sa_impl.h | 3 + include/grub/zfs/zfs.h | 2 +- 3 files changed, 141 insertions(+), 13 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index e248a1114..454fc4a4a 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1839,19 +1839,18 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, break; *path = ch; - if (((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) + if (dnode_path->dn.dn.dn_bonustype == DMU_OT_ZNODE + && ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { char *sym_value; - grub_size_t avail_in_dnode; grub_size_t sym_sz; int free_symval = 0; char *oldpath = path, *oldpathbuf = path_buf; sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys)); - avail_in_dnode = (char *) (&dnode_path->dn + 1) - sym_value; sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian); - if (sym_sz > avail_in_dnode - 8) + if (dnode_path->dn.dn.dn_flags & 1) { grub_size_t block; grub_size_t blksz; @@ -1905,6 +1904,62 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (dn_new); } } + if (dnode_path->dn.dn.dn_bonustype == DMU_OT_SA) + { + void *sahdrp; + int hdrsize; + + if (dnode_path->dn.dn.dn_bonuslen != 0) + { + sahdrp = DN_BONUS (&dnode_path->dn.dn); + } + else if (dnode_path->dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &dnode_path->dn.dn.dn_spill; + + err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data); + if (err) + return err; + } + else + { + return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + + if (((grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_TYPE_OFFSET), dnode_path->dn.endian) >> 12) & 0xf) == 0xa) + { + char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET; + grub_size_t sym_sz = + grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), dnode_path->dn.endian); + char *oldpath = path, *oldpathbuf = path_buf; + path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1); + if (!path_buf) + { + grub_free (oldpathbuf); + return grub_errno; + } + grub_memcpy (path, sym_value, sym_sz); + path [sym_sz] = 0; + grub_memcpy (path + grub_strlen (path), oldpath, + grub_strlen (oldpath) + 1); + + grub_free (oldpathbuf); + if (path[0] != '/') + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + else while (dnode_path != root) + { + dn_new = dnode_path; + dnode_path = dn_new->next; + grub_free (dn_new); + } + } + } } if (!err) @@ -2666,12 +2721,14 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) } hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET); + file->size = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); } - else + else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE) { file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian); } + else + return grub_error (GRUB_ERR_BAD_FS, "bad bonus type"); file->data = data; file->offset = 0; @@ -2830,8 +2887,39 @@ fill_fs_info (struct grub_dirhook_info *info, return; } - info->mtimeset = 1; - info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + if (dn.dn.dn_bonustype == DMU_OT_SA) + { + void *sahdrp; + int hdrsize; + + if (dn.dn.dn_bonuslen != 0) + { + sahdrp = (sa_hdr_phys_t *) DN_BONUS (&dn.dn); + } + else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &dn.dn.dn_spill; + + err = zio_read (bp, dn.endian, &sahdrp, NULL, data); + if (err) + return; + } + else + { + grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + return; + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + } + + if (dn.dn.dn_bonustype == DMU_OT_ZNODE) + { + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + } return; } @@ -2855,10 +2943,47 @@ grub_zfs_dir (grub_device_t device, const char *path, grub_memset (&info, 0, sizeof (info)); dnode_get (&(data->mdn), val, 0, &dn, data); - info.mtimeset = 1; - info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); - info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); - grub_dprintf ("zfs", "type=%d, name=%s\n", + + if (dn.dn.dn_bonustype == DMU_OT_SA) + { + void *sahdrp; + int hdrsize; + + if (dn.dn.dn_bonuslen != 0) + { + sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn); + } + else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) + { + blkptr_t *bp = &dn.dn.dn_spill; + + err = zio_read (bp, dn.endian, &sahdrp, NULL, data); + if (err) + { + grub_print_error (); + return 0; + } + } + else + { + grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + grub_print_error (); + return 0; + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + info.mtimeset = 1; + info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + } + + if (dn.dn.dn_bonustype == DMU_OT_ZNODE) + { + info.mtimeset = 1; + info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], + dn.endian); + } + info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); + grub_dprintf ("zfs", "type=%d, name=%s\n", (int)dn.dn.dn_type, (char *)name); return hook (name, &info); } diff --git a/include/grub/zfs/sa_impl.h b/include/grub/zfs/sa_impl.h index a2b728d37..0845d1290 100644 --- a/include/grub/zfs/sa_impl.h +++ b/include/grub/zfs/sa_impl.h @@ -29,6 +29,9 @@ typedef struct sa_hdr_phys { } sa_hdr_phys_t; #define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0) +#define SA_TYPE_OFFSET 0x0 #define SA_SIZE_OFFSET 0x8 +#define SA_MTIME_OFFSET 0x38 +#define SA_SYMLINK_OFFSET 0xa0 #endif /* _SYS_SA_IMPL_H */ diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 374068d06..d7029903a 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -28,7 +28,7 @@ /* * On-disk version number. */ -#define SPA_VERSION 31ULL +#define SPA_VERSION 33ULL /* * The following are configuration names used in the nvlist describing a pool's From 8563e2a6707a0a8bed9b36734799a7a3a62e5103 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:36:10 +0200 Subject: [PATCH 1290/1414] Small multidevice fix --- grub-core/fs/zfs/zfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 454fc4a4a..b4deba5c0 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -495,9 +495,9 @@ fill_vdev_info_real (struct grub_zfs_data *data, fill->vdev_phys_sector = insert->vdev_phys_sector; fill->current_uberblock = insert->current_uberblock; fill->original = insert->original; + if (!data->device_original) + data->device_original = fill; } - if (!data->device_original) - data->device_original = fill; return GRUB_ERR_NONE; } From 52a050751b79c3480f8019a789e255df2b546e70 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:52:54 +0200 Subject: [PATCH 1291/1414] * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. --- ChangeLog | 4 ++++ grub-core/fs/nilfs2.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1abd5daa2..7d2bdd80d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-26 Vladimir Serbinenko + + * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. + 2011-10-26 Vladimir Serbinenko ZFS multi-device and version 33 support. diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 62cf167c7..5986002ef 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -1117,7 +1117,7 @@ grub_nilfs2_uuid (grub_device_t device, char **uuid) { *uuid = grub_xasprintf - ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x", + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", data->sblock.s_uuid[0], data->sblock.s_uuid[1], data->sblock.s_uuid[2], data->sblock.s_uuid[3], data->sblock.s_uuid[4], data->sblock.s_uuid[5], From 8e32442e804edaf471ffc4156541e089ce2d5374 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:55:07 +0200 Subject: [PATCH 1292/1414] * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support -l argument. Add newline at the end if printing. (GRUB_MOD_INIT): Document -l. --- ChangeLog | 6 ++++++ grub-core/commands/xnu_uuid.c | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d2bdd80d..d2ed9f2ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-26 Vladimir Serbinenko + + * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support + -l argument. Add newline at the end if printing. + (GRUB_MOD_INIT): Document -l. + 2011-10-26 Vladimir Serbinenko * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. diff --git a/grub-core/commands/xnu_uuid.c b/grub-core/commands/xnu_uuid.c index f618b4ec0..3d152a6d6 100644 --- a/grub-core/commands/xnu_uuid.c +++ b/grub-core/commands/xnu_uuid.c @@ -51,10 +51,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]; char *ptr; grub_uint8_t ctx[GRUB_MD_MD5->contextsize]; + int low = 0; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required"); + if (argc > 1 && grub_strcmp (args[0], "-l") == 0) + { + low = 1; + argc--; + args++; + } + serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16)); GRUB_MD_MD5->init (&ctx); @@ -75,10 +83,11 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11], (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13], (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]); - for (ptr = uuid_string; *ptr; ptr++) - *ptr = grub_toupper (*ptr); + if (!low) + for (ptr = uuid_string; *ptr; ptr++) + *ptr = grub_toupper (*ptr); if (argc == 1) - grub_printf ("%s", uuid_string); + grub_printf ("%s\n", uuid_string); if (argc > 1) grub_env_set (args[1], uuid_string); @@ -91,9 +100,10 @@ static grub_command_t cmd; GRUB_MOD_INIT (xnu_uuid) { cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid, - N_("GRUBUUID [VARNAME]"), + N_("[-l] GRUBUUID [VARNAME]"), N_("Transform 64-bit UUID to format " - "suitable for XNU.")); + "suitable for XNU. If -l is given keep " + "it lowercase as done by blkid.")); } GRUB_MOD_FINI (xnu_uuid) From 3be82e10a9fb1a1d7a7486827f362cb9036f489c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:58:32 +0200 Subject: [PATCH 1293/1414] fstest xnu_uuid subcommand. * grub-core/commands/xnu_uuid.c (libgrubkrn): Add grub-core/commands/xnu_uuid.c. * util/grub-fstest.c (CMD_XNU_UUID): New enum value. (fstest): Handle xnu_uuid. (options): Document xnu_uuid. (argp_parser): Parse xnu_uuid. --- ChangeLog | 11 +++++++++++ Makefile.util.def | 1 + util/grub-fstest.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d2ed9f2ef..9068bd856 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-10-26 Vladimir Serbinenko + + fstest xnu_uuid subcommand. + + * grub-core/commands/xnu_uuid.c (libgrubkrn): Add + grub-core/commands/xnu_uuid.c. + * util/grub-fstest.c (CMD_XNU_UUID): New enum value. + (fstest): Handle xnu_uuid. + (options): Document xnu_uuid. + (argp_parser): Parse xnu_uuid. + 2011-10-26 Vladimir Serbinenko * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support diff --git a/Makefile.util.def b/Makefile.util.def index e1040c24f..1b66ab961 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -43,6 +43,7 @@ library = { common_nodist = grub_script.tab.h; common = grub-core/commands/blocklist.c; + common = grub-core/commands/xnu_uuid.c; common = grub-core/commands/testload.c; common = grub-core/commands/ls.c; common = grub-core/disk/dmraid_nvidia.c; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index b6ed2ef0c..60889d05e 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -63,7 +63,8 @@ enum { CMD_CRC, CMD_BLOCKLIST, CMD_TESTLOAD, - CMD_ZFSINFO + CMD_ZFSINFO, + CMD_XNU_UUID }; #define BUF_SIZE 32256 @@ -378,6 +379,27 @@ fstest (int n, char **args) case CMD_TESTLOAD: execute_command ("testload", n, args); grub_printf ("\n"); + case CMD_XNU_UUID: + { + grub_device_t dev; + grub_fs_t fs; + char *uuid = 0; + char *argv[3] = { "-l", NULL, NULL}; + dev = grub_device_open (n ? args[0] : 0); + if (!dev) + grub_util_error (grub_errmsg); + fs = grub_fs_probe (dev); + if (!fs) + grub_util_error (grub_errmsg); + if (!fs->uuid) + grub_util_error ("couldn't retrieve UUID"); + if (fs->uuid (dev, &uuid)) + grub_util_error (grub_errmsg); + if (!uuid) + grub_util_error ("couldn't retrieve UUID"); + argv[1] = uuid; + execute_command ("xnu_uuid", 2, argv); + } } for (i = 0; i < num_disks; i++) @@ -406,6 +428,7 @@ static struct argp_option options[] = { {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}, {N_("blocklist FILE"), 0, 0, OPTION_DOC, N_("Display blocklist of FILE."), 1}, + {N_("xnu_uuid"), 0, 0, OPTION_DOC, N_("Compute XNU UUID of the device."), 1}, {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"skip", 's', "N", 0, N_("Skip N bytes from output file."), 2}, @@ -558,6 +581,11 @@ argp_parser (int key, char *arg, struct argp_state *state) cmd = CMD_TESTLOAD; nparm = 1; } + else if (grub_strcmp (arg, "xnu_uuid") == 0) + { + cmd = CMD_XNU_UUID; + nparm = 0; + } else { fprintf (stderr, _("Invalid command %s.\n"), arg); From 91c3fdde0deb12db912ca9a3e0436babae634f1e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 02:59:45 +0200 Subject: [PATCH 1294/1414] * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. --- ChangeLog | 4 ++ grub-core/fs/ntfs.c | 124 ++++++++++++++++++-------------- grub-core/fs/ntfscomp.c | 53 +++++++------- include/grub/ntfs.h | 156 +++++++++++++++++++++------------------- 4 files changed, 181 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9068bd856..f8b6a78dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-26 Vladimir Serbinenko + + * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. + 2011-10-26 Vladimir Serbinenko fstest xnu_uuid subcommand. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 6b8455c34..bff760e71 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#define grub_fshelp_node grub_ntfs_file + #include #include #include @@ -30,7 +32,19 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; -ntfscomp_func_t grub_ntfscomp_func; +#define grub_fshelp_node grub_ntfs_file + +#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) + +#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t)) +#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t)) +#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t)) + +#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t) +#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t) +#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t) + +grub_ntfscomp_func_t grub_ntfscomp_func; static grub_err_t fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) @@ -87,7 +101,7 @@ static void init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) { at->mft = mft; - at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0; + at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0; at->attr_nxt = mft->buf + u16at (mft->buf, 0x14); at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; } @@ -103,7 +117,7 @@ free_attr (struct grub_ntfs_attr *at) static char * find_attr (struct grub_ntfs_attr *at, unsigned char attr) { - if (at->flags & AF_ALST) + if (at->flags & GRUB_NTFS_AF_ALST) { retry: while (at->attr_nxt < at->attr_end) @@ -114,7 +128,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) { char *new_pos; - if (at->flags & AF_MMFT) + if (at->flags & GRUB_NTFS_AF_MMFT) { if ((grub_disk_read (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0, @@ -160,7 +174,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) while ((unsigned char) *at->attr_cur != 0xFF) { at->attr_nxt += u16at (at->attr_cur, 4); - if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST) + if ((unsigned char) *at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) at->attr_end = at->attr_cur; if (((unsigned char) *at->attr_cur == attr) || (attr == 0)) return at->attr_cur; @@ -170,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) { char *pa; - at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR); + at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); if (at->emft_buf == NULL) return NULL; @@ -199,7 +213,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) at->attr_nxt = at->attr_end + u16at (pa, 0x14); at->attr_end = at->attr_end + u32at (pa, 4); } - at->flags |= AF_ALST; + at->flags |= GRUB_NTFS_AF_ALST; while (at->attr_nxt < at->attr_end) { if (((unsigned char) *at->attr_nxt == attr) || (attr == 0)) @@ -209,9 +223,9 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) if (at->attr_nxt >= at->attr_end) return NULL; - if ((at->flags & AF_MMFT) && (attr == AT_DATA)) + if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA)) { - at->flags |= AF_GPOS; + at->flags |= GRUB_NTFS_AF_GPOS; at->attr_cur = at->attr_nxt; pa = at->attr_cur; v32at (pa, 0x10) = at->mft->data->mft_start; @@ -223,13 +237,13 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) break; if (read_attr (at, pa + 0x10, - u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR), - at->mft->data->mft_size << BLK_SHR, 0, 0)) + u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), + at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) return NULL; pa += u16at (pa, 4); } at->attr_nxt = at->attr_cur; - at->flags &= ~AF_GPOS; + at->flags &= ~GRUB_NTFS_AF_GPOS; } goto retry; } @@ -245,13 +259,13 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, init_attr (at, mft); if ((pa = find_attr (at, attr)) == NULL) return NULL; - if ((at->flags & AF_ALST) == 0) + if ((at->flags & GRUB_NTFS_AF_ALST) == 0) { while (1) { if ((pa = find_attr (at, attr)) == NULL) break; - if (at->flags & AF_ALST) + if (at->flags & GRUB_NTFS_AF_ALST) return pa; } grub_errno = GRUB_ERR_NONE; @@ -296,7 +310,7 @@ retry: c2 = ((unsigned char) (*run) >> 4); if (!c1) { - if ((ctx->attr) && (ctx->attr->flags & AF_ALST)) + if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) { void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector, unsigned offset, @@ -325,9 +339,9 @@ retry: run = read_run_data (run, c2, &val, 1); /* offset to previous LCN */ ctx->curr_lcn += val; if (val == 0) - ctx->flags |= RF_BLNK; + ctx->flags |= GRUB_NTFS_RF_BLNK; else - ctx->flags &= ~RF_BLNK; + ctx->flags &= ~GRUB_NTFS_RF_BLNK; ctx->cur_run = run; return 0; } @@ -345,7 +359,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) return ctx->curr_lcn; } else - return (ctx->flags & RF_BLNK) ? 0 : (block - + return (ctx->flags & GRUB_NTFS_RF_BLNK) ? 0 : (block - ctx->curr_vcn + ctx->curr_lcn); } @@ -376,24 +390,24 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return 0; } - if (u16at (pa, 0xC) & FLAG_COMPRESSED) - ctx->flags |= RF_COMP; + if (u16at (pa, 0xC) & GRUB_NTFS_FLAG_COMPRESSED) + ctx->flags |= GRUB_NTFS_RF_COMP; else - ctx->flags &= ~RF_COMP; + ctx->flags &= ~GRUB_NTFS_RF_COMP; ctx->cur_run = pa + u16at (pa, 0x20); - if (ctx->flags & RF_COMP) + if (ctx->flags & GRUB_NTFS_RF_COMP) { if (!cached) return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed"); if (at->sbuf) { - if ((ofs & (~(COM_LEN - 1))) == at->save_pos) + if ((ofs & (~(GRUB_NTFS_COM_LEN - 1))) == at->save_pos) { grub_disk_addr_t n; - n = COM_LEN - (ofs - at->save_pos); + n = GRUB_NTFS_COM_LEN - (ofs - at->save_pos); if (n > len) n = len; @@ -408,17 +422,17 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, } else { - at->sbuf = grub_malloc (COM_LEN); + at->sbuf = grub_malloc (GRUB_NTFS_COM_LEN); if (at->sbuf == NULL) return grub_errno; at->save_pos = 1; } - vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc); + vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC / ctx->comp.spc); ctx->target_vcn &= ~0xF; } else - vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0); + vcn = ctx->target_vcn = grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, 0); ctx->next_vcn = u32at (pa, 0x10); ctx->curr_lcn = 0; @@ -428,12 +442,12 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return grub_errno; } - if (at->flags & AF_GPOS) + if (at->flags & GRUB_NTFS_AF_GPOS) { grub_disk_addr_t st0, st1; grub_uint64_t m; - grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m); + grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, &m); st0 = (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m; @@ -450,7 +464,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, return 0; } - if (!(ctx->flags & RF_COMP)) + if (!(ctx->flags & GRUB_NTFS_RF_COMP)) { unsigned int pow; @@ -481,12 +495,12 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, save_cur = at->attr_cur; at->attr_nxt = at->attr_cur; attr = (unsigned char) *at->attr_nxt; - if (at->flags & AF_ALST) + if (at->flags & GRUB_NTFS_AF_ALST) { char *pa; grub_disk_addr_t vcn; - vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0); + vcn = grub_divmod64 (ofs, at->mft->data->spc << GRUB_NTFS_BLK_SHR, 0); pa = at->attr_nxt + u16at (at->attr_nxt, 4); while (pa < at->attr_end) { @@ -513,8 +527,8 @@ static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) { if (read_attr - (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR), - data->mft_size << BLK_SHR, 0, 0)) + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), + data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); return fixup (data, buf, data->mft_size, "FILE"); } @@ -526,7 +540,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) mft->inode_read = 1; - mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR); + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); if (mft->buf == NULL) return grub_errno; @@ -541,7 +555,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) { char *pa; - pa = locate_attr (&mft->attr, mft, AT_DATA); + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA); if (pa == NULL) return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno); @@ -550,7 +564,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) else mft->size = u64at (pa, 0x30); - if ((mft->attr.flags & AF_ALST) == 0) + if ((mft->attr.flags & GRUB_NTFS_AF_ALST) == 0) mft->attr.attr_end = 0; /* Don't jump to attribute list */ } else @@ -603,7 +617,7 @@ list_file (struct grub_ntfs_file *diro, char *pos, } type = - (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : + (u32at (pos, 0x48) & GRUB_NTFS_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG; fdiro = grub_zalloc (sizeof (struct grub_ntfs_file)); @@ -668,7 +682,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, init_attr (at, mft); while (1) { - if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL) + if ((cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT)) == NULL) { grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); goto done; @@ -694,7 +708,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, bitmap_len = 0; free_attr (at); init_attr (at, mft); - while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL) + while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) { int ofs; @@ -735,7 +749,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, } free_attr (at); - cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION); + cur_pos = locate_attr (at, mft, GRUB_NTFS_AT_INDEX_ALLOCATION); while (cur_pos != NULL) { /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */ @@ -743,7 +757,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, (u32at (cur_pos, 0x40) == 0x490024) && (u32at (cur_pos, 0x44) == 0x300033)) break; - cur_pos = find_attr (at, AT_INDEX_ALLOCATION); + cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ALLOCATION); } if ((!cur_pos) && (bitmap)) @@ -756,7 +770,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, { grub_disk_addr_t v, i; - indx = grub_malloc (mft->data->idx_size << BLK_SHR); + indx = grub_malloc (mft->data->idx_size << GRUB_NTFS_BLK_SHR); if (indx == NULL) goto done; @@ -766,8 +780,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, if (*bitmap & v) { if ((read_attr - (at, indx, i * (mft->data->idx_size << BLK_SHR), - (mft->data->idx_size << BLK_SHR), 0, 0)) + (at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR), + (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0)) || (fixup (mft->data, indx, mft->data->idx_size, "INDX"))) goto done; ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook); @@ -814,32 +828,32 @@ grub_ntfs_mount (grub_disk_t disk) goto fail; data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector); - data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR); + data->spc = bpb.sectors_per_cluster * (data->blocksize >> GRUB_NTFS_BLK_SHR); if (bpb.clusters_per_mft > 0) data->mft_size = data->spc * bpb.clusters_per_mft; else - data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR); + data->mft_size = 1 << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); if (bpb.clusters_per_index > 0) data->idx_size = data->spc * bpb.clusters_per_index; else - data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR); + data->idx_size = 1 << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc; - if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX)) + if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX)) goto fail; data->mmft.data = data; data->cmft.data = data; - data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR); + data->mmft.buf = grub_malloc (data->mft_size << GRUB_NTFS_BLK_SHR); if (!data->mmft.buf) goto fail; if (grub_disk_read - (disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf)) + (disk, data->mft_start, 0, data->mft_size << GRUB_NTFS_BLK_SHR, data->mmft.buf)) goto fail; data->uuid = grub_le_to_cpu64 (bpb.num_serial); @@ -847,10 +861,10 @@ grub_ntfs_mount (grub_disk_t disk) if (fixup (data, data->mmft.buf, data->mft_size, "FILE")) goto fail; - if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA)) + if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA)) goto fail; - if (init_file (&data->cmft, FILE_ROOT)) + if (init_file (&data->cmft, GRUB_NTFS_FILE_ROOT)) goto fail; return data; @@ -1030,7 +1044,7 @@ grub_ntfs_label (grub_device_t device, char **label) if (!mft->inode_read) { - mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR); + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); if (mft->buf == NULL) goto fail; @@ -1039,7 +1053,7 @@ grub_ntfs_label (grub_device_t device, char **label) } init_attr (&mft->attr, mft); - pa = find_attr (&mft->attr, AT_VOLUME_NAME); + pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) { char *buf; diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c index d2893cb99..890faa3bf 100644 --- a/grub-core/fs/ntfscomp.c +++ b/grub-core/fs/ntfscomp.c @@ -21,7 +21,6 @@ #include #include #include -#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -35,7 +34,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) (cc->disk, (cc->comp_table[cc->comp_head][1] - (cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0, - cc->spc << BLK_SHR, cc->cbuf)) + cc->spc << GRUB_NTFS_BLK_SHR, cc->cbuf)) return grub_errno; cc->cbuf_vcn++; if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0])) @@ -47,7 +46,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) static grub_err_t decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res) { - if (cc->cbuf_ofs >= (cc->spc << BLK_SHR)) + if (cc->cbuf_ofs >= (cc->spc << GRUB_NTFS_BLK_SHR)) { if (decomp_nextvcn (cc)) return grub_errno; @@ -87,7 +86,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) bits = copied = tag = 0; while (cnt > 0) { - if (copied > COM_LEN) + if (copied > GRUB_NTFS_COM_LEN) return grub_error (GRUB_ERR_BAD_FS, "compression block too large"); @@ -150,7 +149,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) } else { - if (cnt != COM_LEN) + if (cnt != GRUB_NTFS_COM_LEN) return grub_error (GRUB_ERR_BAD_FS, "invalid compression block size"); } @@ -160,7 +159,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) { int n; - n = (cc->spc << BLK_SHR) - cc->cbuf_ofs; + n = (cc->spc << GRUB_NTFS_BLK_SHR) - cc->cbuf_ofs; if (n > cnt) n = cnt; if ((dest) && (n)) @@ -179,7 +178,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) static grub_err_t read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) { - int cpb = COM_SEC / ctx->comp.spc; + int cpb = GRUB_NTFS_COM_SEC / ctx->comp.spc; while (num) { @@ -192,7 +191,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) return grub_error (GRUB_ERR_BAD_FS, "invalid compression block"); ctx->comp.comp_head = ctx->comp.comp_tail = 0; ctx->comp.cbuf_vcn = ctx->target_vcn; - ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR); + ctx->comp.cbuf_ofs = (ctx->comp.spc << GRUB_NTFS_BLK_SHR); if (ctx->target_vcn >= ctx->next_vcn) { if (grub_ntfs_read_run_list (ctx)) @@ -200,7 +199,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) } while (ctx->target_vcn + 16 > ctx->next_vcn) { - if (ctx->flags & RF_BLNK) + if (ctx->flags & GRUB_NTFS_RF_BLNK) break; ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn; ctx->comp.comp_table[ctx->comp.comp_tail][1] = @@ -216,15 +215,15 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) nn = num; num -= nn; - if (ctx->flags & RF_BLNK) + if (ctx->flags & GRUB_NTFS_RF_BLNK) { ctx->target_vcn += nn * cpb; if (ctx->comp.comp_tail == 0) { if (buf) { - grub_memset (buf, 0, nn * COM_LEN); - buf += nn * COM_LEN; + grub_memset (buf, 0, nn * GRUB_NTFS_COM_LEN); + buf += nn * GRUB_NTFS_COM_LEN; } } else @@ -234,7 +233,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) if (decomp_block (&ctx->comp, buf)) return grub_errno; if (buf) - buf += COM_LEN; + buf += GRUB_NTFS_COM_LEN; nn--; } } @@ -259,9 +258,9 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) (ctx->comp.comp_table[ctx->comp.comp_head][1] - (ctx->comp.comp_table[ctx->comp.comp_head][0] - ctx->target_vcn)) * ctx->comp.spc, 0, - tt * (ctx->comp.spc << BLK_SHR), buf)) + tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf)) return grub_errno; - buf += tt * (ctx->comp.spc << BLK_SHR); + buf += tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); } nn -= tt; if (ctx->target_vcn >= @@ -276,9 +275,9 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) (ctx->comp.disk, (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc, 0, - nn * (ctx->comp.spc << BLK_SHR), buf)) + nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf)) return grub_errno; - buf += nn * (ctx->comp.spc << BLK_SHR); + buf += nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); } ctx->target_vcn += nn; } @@ -294,7 +293,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, grub_err_t ret; ctx->comp.comp_head = ctx->comp.comp_tail = 0; - ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR); + ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << GRUB_NTFS_BLK_SHR); if (!ctx->comp.cbuf) return 0; @@ -304,17 +303,17 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, if ((vcn > ctx->target_vcn) && (read_block - (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC))) + (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / GRUB_NTFS_COM_SEC))) { ret = grub_errno; goto quit; } - if (ofs % COM_LEN) + if (ofs % GRUB_NTFS_COM_LEN) { grub_uint32_t t, n, o; - t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); if (read_block (ctx, at->sbuf, 1)) { ret = grub_errno; @@ -323,8 +322,8 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, at->save_pos = t; - o = ofs % COM_LEN; - n = COM_LEN - o; + o = ofs % GRUB_NTFS_COM_LEN; + n = GRUB_NTFS_COM_LEN - o; if (n > len) n = len; grub_memcpy (dest, &at->sbuf[o], n); @@ -334,19 +333,19 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, len -= n; } - if (read_block (ctx, dest, len / COM_LEN)) + if (read_block (ctx, dest, len / GRUB_NTFS_COM_LEN)) { ret = grub_errno; goto quit; } - dest += (len / COM_LEN) * COM_LEN; - len = len % COM_LEN; + dest += (len / GRUB_NTFS_COM_LEN) * GRUB_NTFS_COM_LEN; + len = len % GRUB_NTFS_COM_LEN; if (len) { grub_uint32_t t; - t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); if (read_block (ctx, at->sbuf, 1)) { ret = grub_errno; diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index e220fecf4..cf90ce110 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -20,79 +20,87 @@ #ifndef GRUB_NTFS_H #define GRUB_NTFS_H 1 -#define FILE_MFT 0 -#define FILE_MFTMIRR 1 -#define FILE_LOGFILE 2 -#define FILE_VOLUME 3 -#define FILE_ATTRDEF 4 -#define FILE_ROOT 5 -#define FILE_BITMAP 6 -#define FILE_BOOT 7 -#define FILE_BADCLUS 8 -#define FILE_QUOTA 9 -#define FILE_UPCASE 10 +enum + { + GRUB_NTFS_FILE_MFT = 0, + GRUB_NTFS_FILE_MFTMIRR = 1, + GRUB_NTFS_FILE_LOGFILE = 2, + GRUB_NTFS_FILE_VOLUME = 3, + GRUB_NTFS_FILE_ATTRDEF = 4, + GRUB_NTFS_FILE_ROOT = 5, + GRUB_NTFS_FILE_BITMAP = 6, + GRUB_NTFS_FILE_BOOT = 7, + GRUB_NTFS_FILE_BADCLUS = 8, + GRUB_NTFS_FILE_QUOTA = 9, + GRUB_NTFS_FILE_UPCASE = 10, + }; -#define AT_STANDARD_INFORMATION 0x10 -#define AT_ATTRIBUTE_LIST 0x20 -#define AT_FILENAME 0x30 -#define AT_OBJECT_ID 0x40 -#define AT_SECURITY_DESCRIPTOR 0x50 -#define AT_VOLUME_NAME 0x60 -#define AT_VOLUME_INFORMATION 0x70 -#define AT_DATA 0x80 -#define AT_INDEX_ROOT 0x90 -#define AT_INDEX_ALLOCATION 0xA0 -#define AT_BITMAP 0xB0 -#define AT_SYMLINK 0xC0 -#define AT_EA_INFORMATION 0xD0 -#define AT_EA 0xE0 +enum + { + GRUB_NTFS_AT_STANDARD_INFORMATION = 0x10, + GRUB_NTFS_AT_ATTRIBUTE_LIST = 0x20, + GRUB_NTFS_AT_FILENAME = 0x30, + GRUB_NTFS_AT_OBJECT_ID = 0x40, + GRUB_NTFS_AT_SECURITY_DESCRIPTOR = 0x50, + GRUB_NTFS_AT_VOLUME_NAME = 0x60, + GRUB_NTFS_AT_VOLUME_INFORMATION = 0x70, + GRUB_NTFS_AT_DATA = 0x80, + GRUB_NTFS_AT_INDEX_ROOT = 0x90, + GRUB_NTFS_AT_INDEX_ALLOCATION = 0xA0, + GRUB_NTFS_AT_BITMAP = 0xB0, + GRUB_NTFS_AT_SYMLINK = 0xC0, + GRUB_NTFS_AT_EA_INFORMATION = 0xD0, + GRUB_NTFS_AT_EA = 0xE0, + }; -#define ATTR_READ_ONLY 0x1 -#define ATTR_HIDDEN 0x2 -#define ATTR_SYSTEM 0x4 -#define ATTR_ARCHIVE 0x20 -#define ATTR_DEVICE 0x40 -#define ATTR_NORMAL 0x80 -#define ATTR_TEMPORARY 0x100 -#define ATTR_SPARSE 0x200 -#define ATTR_REPARSE 0x400 -#define ATTR_COMPRESSED 0x800 -#define ATTR_OFFLINE 0x1000 -#define ATTR_NOT_INDEXED 0x2000 -#define ATTR_ENCRYPTED 0x4000 -#define ATTR_DIRECTORY 0x10000000 -#define ATTR_INDEX_VIEW 0x20000000 +enum + { + GRUB_NTFS_ATTR_READ_ONLY = 0x1, + GRUB_NTFS_ATTR_HIDDEN = 0x2, + GRUB_NTFS_ATTR_SYSTEM = 0x4, + GRUB_NTFS_ATTR_ARCHIVE = 0x20, + GRUB_NTFS_ATTR_DEVICE = 0x40, + GRUB_NTFS_ATTR_NORMAL = 0x80, + GRUB_NTFS_ATTR_TEMPORARY = 0x100, + GRUB_NTFS_ATTR_SPARSE = 0x200, + GRUB_NTFS_ATTR_REPARSE = 0x400, + GRUB_NTFS_ATTR_COMPRESSED = 0x800, + GRUB_NTFS_ATTR_OFFLINE = 0x1000, + GRUB_NTFS_ATTR_NOT_INDEXED = 0x2000, + GRUB_NTFS_ATTR_ENCRYPTED = 0x4000, + GRUB_NTFS_ATTR_DIRECTORY = 0x10000000, + GRUB_NTFS_ATTR_INDEX_VIEW = 0x20000000 + }; -#define FLAG_COMPRESSED 1 -#define FLAG_ENCRYPTED 0x4000 -#define FLAG_SPARSE 0x8000 +enum + { + GRUB_NTFS_FLAG_COMPRESSED = 1, + GRUB_NTFS_FLAG_ENCRYPTED = 0x4000, + GRUB_NTFS_FLAG_SPARSE = 0x8000 + }; -#define BLK_SHR GRUB_DISK_SECTOR_BITS +#define GRUB_NTFS_BLK_SHR GRUB_DISK_SECTOR_BITS -#define MAX_MFT (1024 >> BLK_SHR) -#define MAX_IDX (16384 >> BLK_SHR) +#define GRUB_NTFS_MAX_MFT (1024 >> GRUB_NTFS_BLK_SHR) +#define GRUB_NTFS_MAX_IDX (16384 >> GRUB_NTFS_BLK_SHR) -#define COM_LEN 4096 -#define COM_LOG_LEN 12 -#define COM_SEC (COM_LEN >> BLK_SHR) +#define GRUB_NTFS_COM_LEN 4096 +#define GRUB_NTFS_COM_LOG_LEN 12 +#define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR) -#define AF_ALST 1 -#define AF_MMFT 2 -#define AF_GPOS 4 +enum + { + GRUB_NTFS_AF_ALST = 1, + GRUB_NTFS_AF_MMFT = 2, + GRUB_NTFS_AF_GPOS = 4, + }; -#define RF_COMP 1 -#define RF_CBLK 2 -#define RF_BLNK 4 - -#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) - -#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t)) -#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t)) -#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t)) - -#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t) -#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t) -#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t) +enum + { + GRUB_NTFS_RF_COMP = 1, + GRUB_NTFS_RF_CBLK = 2, + GRUB_NTFS_RF_BLNK = 4 + }; struct grub_ntfs_bpb { @@ -120,8 +128,6 @@ struct grub_ntfs_bpb grub_uint32_t checksum; } __attribute__ ((packed)); -#define grub_ntfs_file grub_fshelp_node - struct grub_ntfs_attr { int flags; @@ -132,7 +138,7 @@ struct grub_ntfs_attr struct grub_ntfs_file *mft; }; -struct grub_fshelp_node +struct grub_ntfs_file { struct grub_ntfs_data *data; char *buf; @@ -174,13 +180,15 @@ struct grub_ntfs_rlst struct grub_ntfs_comp comp; }; -typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char *dest, - grub_uint32_t ofs, grub_uint32_t len, - struct grub_ntfs_rlst * ctx, - grub_uint32_t vcn); +typedef grub_err_t (*grub_ntfscomp_func_t) (struct grub_ntfs_attr * at, + char *dest, + grub_uint32_t ofs, + grub_uint32_t len, + struct grub_ntfs_rlst * ctx, + grub_uint32_t vcn); -extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func); +extern grub_ntfscomp_func_t grub_ntfscomp_func; -grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx); +grub_err_t grub_ntfs_read_run_list (struct grub_ntfs_rlst *ctx); #endif /* ! GRUB_NTFS_H */ From 5773fb64104944b2af0a988183861e88b5579fe6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 03:04:27 +0200 Subject: [PATCH 1295/1414] Support NTFS reparse points. * grub-core/fs/ntfs.c (list_file): Set symlink type when appropriate. (symlink_descriptor): New struct. (grub_ntfs_read_symlink): New function. (grub_ntfs_iterate_dir): Use grub_ntfs_read_symlink. (grub_ntfs_open): Likewise. --- ChangeLog | 10 ++++ grub-core/fs/ntfs.c | 110 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8b6a78dc..8c3c50434 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-26 Vladimir Serbinenko + + Support NTFS reparse points. + + * grub-core/fs/ntfs.c (list_file): Set symlink type when appropriate. + (symlink_descriptor): New struct. + (grub_ntfs_read_symlink): New function. + (grub_ntfs_iterate_dir): Use grub_ntfs_read_symlink. + (grub_ntfs_open): Likewise. + 2011-10-26 Vladimir Serbinenko * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index bff760e71..13de52cd8 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -609,6 +609,7 @@ list_file (struct grub_ntfs_file *diro, char *pos, { enum grub_fshelp_filetype type; struct grub_ntfs_file *fdiro; + grub_uint32_t attr; if (u16at (pos, 4)) { @@ -616,9 +617,13 @@ list_file (struct grub_ntfs_file *diro, char *pos, return 0; } - type = - (u32at (pos, 0x48) & GRUB_NTFS_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : - GRUB_FSHELP_REG; + attr = u32at (pos, 0x48); + if (attr & GRUB_NTFS_ATTR_REPARSE) + type = GRUB_FSHELP_SYMLINK; + else if (attr & GRUB_NTFS_ATTR_DIRECTORY) + type = GRUB_FSHELP_DIR; + else + type = GRUB_FSHELP_REG; fdiro = grub_zalloc (sizeof (struct grub_ntfs_file)); if (!fdiro) @@ -653,6 +658,101 @@ list_file (struct grub_ntfs_file *diro, char *pos, return 0; } +struct symlink_descriptor +{ + grub_uint32_t type; + grub_uint32_t total_len; + grub_uint16_t off1; + grub_uint16_t len1; + grub_uint16_t off2; + grub_uint16_t len2; +} __attribute__ ((packed)); + +static char * +grub_ntfs_read_symlink (grub_fshelp_node_t node) +{ + struct grub_ntfs_file *mft; + struct symlink_descriptor symdesc; + grub_err_t err; + grub_uint16_t *buf16; + char *buf, *end; + grub_size_t len; + grub_size_t i; + char *pa; + grub_size_t off; + + mft = (struct grub_ntfs_file *) node; + + mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (mft->buf == NULL) + return NULL; + + if (read_mft (mft->data, mft->buf, mft->ino)) + return NULL; + + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_SYMLINK); + if (pa == NULL) + { + grub_error (GRUB_ERR_BAD_FS, "no $SYMLINK in MFT 0x%X", mft->ino); + return NULL; + } + + err = read_attr (&mft->attr, (char *) &symdesc, 0, + sizeof (struct symlink_descriptor), 1, 0); + if (err) + return NULL; + + switch (grub_cpu_to_le32 (symdesc.type)) + { + case 0xa000000c: + off = sizeof (struct symlink_descriptor) + 4 + grub_cpu_to_le32 (symdesc.off1); + len = grub_cpu_to_le32 (symdesc.len1); + break; + case 0xa0000003: + off = sizeof (struct symlink_descriptor) + grub_cpu_to_le32 (symdesc.off1); + len = grub_cpu_to_le32 (symdesc.len1); + break; + default: + grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", + grub_cpu_to_le32 (symdesc.type)); + grub_printf ("%d\n", __LINE__); + return NULL; + } + + buf16 = grub_malloc (len); + if (!buf16) + return NULL; + + err = read_attr (&mft->attr, (char *) buf16, off, len, 1, 0); + if (err) + return NULL; + + buf = grub_malloc (len * 2 + 1); + if (!buf) + { + grub_free (buf16); + return NULL; + } + + for (i = 0; i < len / 2; i++) + { + buf16[i] = grub_le_to_cpu16 (buf16[i]); + if (buf16[i] == '\\') + buf16[i] = '/'; + } + + end = (char *) grub_utf16_to_utf8 ((grub_uint8_t *) buf, buf16, len / 2); + *end = '\0'; + /* Split the sequence to avoid GCC thinking that this is a trigraph. */ + if (grub_memcmp (buf, "/?" "?/", 4) == 0 && buf[5] == ':' && buf[6] == '/' + && grub_isalpha (buf[4])) + { + grub_memmove (buf, buf + 6, end - buf + 1 - 6); + end -= 6; + } + return buf; +} + static int grub_ntfs_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -915,7 +1015,7 @@ grub_ntfs_dir (grub_device_t device, const char *path, goto fail; grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir, - 0, GRUB_FSHELP_DIR); + grub_ntfs_read_symlink, GRUB_FSHELP_DIR); if (grub_errno) goto fail; @@ -953,7 +1053,7 @@ grub_ntfs_open (grub_file_t file, const char *name) goto fail; grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir, - 0, GRUB_FSHELP_REG); + grub_ntfs_read_symlink, GRUB_FSHELP_REG); if (grub_errno) goto fail; From f8d82408d9f13aa960e2f73317cabb0a66f207e7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 20:55:09 +0200 Subject: [PATCH 1296/1414] * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. (zfs_unmount): Fix memory leak. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8c3c50434..980452003 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-27 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. + (zfs_unmount): Fix memory leak. + 2011-10-26 Vladimir Serbinenko Support NTFS reparse points. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3253457c7..9bd68222a 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -865,7 +865,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, } case DEVICE_MIRROR: { - grub_err_t err; + grub_err_t err = GRUB_ERR_NONE; unsigned i; if (desc->n_children <= 0) return grub_error (GRUB_ERR_BAD_FS, @@ -2498,6 +2498,7 @@ zfs_unmount (struct grub_zfs_data *data) unsigned i; for (i = 0; i < data->n_devices_attached; i++) unmount_device (&data->devices_attached[i]); + grub_free (data->devices_attached); grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); From 5b1ae25f068e405374a8f5b063b1f8a4260274a4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 27 Oct 2011 20:58:52 +0200 Subject: [PATCH 1297/1414] Support BFS (befs) UUID. * grub-core/fs/afs.c (grub_afs_inode): Make small_data zero-size. (grub_afs_small_data_element_header): New struct. (grub_afs_read_inode): Read complete inode. Fix ino type while on it. (grub_afs_read_attribute) [MODE_BFS]: New function. (grub_afs_iterate_dir): Allocate for complete inode. (grub_afs_mount): Likewise. (grub_afs_uuid) [MODE_BFS]: New function. (grub_afs_fs) [MODE_BFS]: Add .uuid. --- ChangeLog | 13 ++++ grub-core/fs/afs.c | 163 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 162 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 980452003..cfb00531a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-10-27 Vladimir Serbinenko + + Support BFS (befs) UUID. + + * grub-core/fs/afs.c (grub_afs_inode): Make small_data zero-size. + (grub_afs_small_data_element_header): New struct. + (grub_afs_read_inode): Read complete inode. Fix ino type while on it. + (grub_afs_read_attribute) [MODE_BFS]: New function. + (grub_afs_iterate_dir): Allocate for complete inode. + (grub_afs_mount): Likewise. + (grub_afs_uuid) [MODE_BFS]: New function. + (grub_afs_fs) [MODE_BFS]: Add .uuid. + 2011-10-27 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index b64ebb52c..ea7a9e9ed 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -210,7 +210,14 @@ struct grub_afs_inode grub_uint32_t unused; struct grub_afs_datastream stream; grub_uint32_t pad[4]; - grub_uint32_t small_data[1]; + grub_uint8_t small_data[0]; +} __attribute__ ((packed)); + +struct grub_afs_small_data_element_header +{ + grub_uint32_t type; + grub_uint16_t name_len; + grub_uint16_t value_len; } __attribute__ ((packed)); struct grub_fshelp_node @@ -229,6 +236,19 @@ struct grub_afs_data static grub_dl_t my_mod; +static int +grub_afs_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)); +static grub_ssize_t +grub_afs_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + grub_off_t pos, grub_size_t len, char *buf); + + static grub_afs_off_t grub_afs_run_to_num (struct grub_afs_sblock *sb, struct grub_afs_blockrun *run) @@ -239,15 +259,87 @@ grub_afs_run_to_num (struct grub_afs_sblock *sb, static grub_err_t grub_afs_read_inode (struct grub_afs_data *data, - grub_uint32_t ino, struct grub_afs_inode *inode) + grub_uint64_t ino, struct grub_afs_inode *inode) { return grub_disk_read (data->disk, ino * (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS), - 0, sizeof (struct grub_afs_inode), - inode); + 0, data->sblock.block_size, inode); } +#ifdef MODE_BFS +static grub_ssize_t +grub_afs_read_attribute (grub_fshelp_node_t node, + const char *name, char *buf, grub_size_t len) +{ + grub_ssize_t read = -1; + auto int NESTED_FUNC_ATTR hook (const char *filename, + enum grub_fshelp_filetype filetype + __attribute__ ((unused)), + grub_fshelp_node_t attr_node); + + int NESTED_FUNC_ATTR hook (const char *filename, + enum grub_fshelp_filetype filetype + __attribute__ ((unused)), + grub_fshelp_node_t attr_node) + { + if (grub_strcmp (filename, name) == 0) + { + read = grub_afs_read_file (attr_node, 0, 0, len, buf); + return 1; + } + return 0; + } + grub_uint8_t *ptr = node->inode.small_data; + grub_uint8_t *end = ((grub_uint8_t *) &node->inode + + node->data->sblock.block_size); + + while (ptr + sizeof (struct grub_afs_small_data_element_header) < end) + { + struct grub_afs_small_data_element_header *el; + char *el_name; + grub_uint8_t *data; + el = (struct grub_afs_small_data_element_header *) ptr; + if (el->name_len == 0) + break; + el_name = (char *) (el + 1); + data = (grub_uint8_t *) el_name + grub_afs_to_cpu16 (el->name_len) + 3; + ptr = data + grub_afs_to_cpu16 (el->value_len) + 1; + if (grub_memcmp (name, el_name, grub_afs_to_cpu16 (el->name_len)) == 0 + && name[el->name_len] == 0) + { + grub_size_t copy; + copy = len; + if (grub_afs_to_cpu16 (el->value_len) > copy) + copy = grub_afs_to_cpu16 (el->value_len); + grub_memcpy (buf, data, copy); + return copy; + } + } + + { + struct grub_fshelp_node *fdiro; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node) + + node->data->sblock.block_size + - sizeof (struct grub_afs_inode)); + if (! fdiro) + return -1; + + fdiro->data = node->data; + if (grub_afs_read_inode (node->data, + grub_afs_run_to_num (&node->data->sblock, + &node->inode.attrib_dir), + &fdiro->inode)) + return -1; + + grub_afs_iterate_dir (fdiro, hook); + } + + return read; +} +#endif + static grub_disk_addr_t grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { @@ -424,7 +516,9 @@ grub_afs_iterate_dir (grub_fshelp_node_t dir, struct grub_fshelp_node *fdiro; int mode, type; - fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + fdiro = grub_malloc (sizeof (struct grub_fshelp_node) + + dir->data->sblock.block_size + - sizeof (struct grub_afs_inode)); if (! fdiro) return 0; @@ -521,18 +615,31 @@ static struct grub_afs_data * grub_afs_mount (grub_disk_t disk) { struct grub_afs_data *data = 0; - - data = grub_malloc (sizeof (struct grub_afs_data)); - if (!data) - return 0; + struct grub_afs_sblock sb; + grub_err_t err; /* Read the superblock. */ - if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0, - sizeof (struct grub_afs_sblock), &data->sblock)) - goto fail; + err = grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0, + sizeof (struct grub_afs_sblock), &sb); + if (err) + { + if (err == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); + return NULL; + } - if (! grub_afs_validate_sblock (&data->sblock)) - goto fail; + if (! grub_afs_validate_sblock (&sb)) + { + grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); + return NULL; + } + + data = grub_malloc (sizeof (struct grub_afs_data) + sb.block_size + - sizeof (struct grub_afs_inode)); + if (!data) + return NULL; + + data->sblock = sb; data->diropen.data = data; data->inode = &data->diropen.inode; @@ -681,6 +788,31 @@ grub_afs_label (grub_device_t device, char **label) return grub_errno; } +#ifdef MODE_BFS +static grub_err_t +grub_afs_uuid (grub_device_t device, char **uuid) +{ + struct grub_afs_data *data; + grub_disk_t disk = device->disk; + grub_uint64_t vid; + grub_ssize_t read; + + *uuid = NULL; + + data = grub_afs_mount (disk); + if (!data) + return grub_errno; + read = grub_afs_read_attribute (&data->diropen, "be:volume_id", + (char *) &vid, + sizeof (vid)); + if (read == sizeof (vid)) + *uuid = grub_xasprintf ("%" PRIxGRUB_UINT64_T, grub_afs_to_cpu64 (vid)); + + grub_free (data); + + return grub_errno; +} +#endif static struct grub_fs grub_afs_fs = { .name = GRUB_AFS_FSNAME, @@ -689,6 +821,9 @@ static struct grub_fs grub_afs_fs = { .read = grub_afs_read, .close = grub_afs_close, .label = grub_afs_label, +#ifdef MODE_BFS + .uuid = grub_afs_uuid, +#endif .next = 0 }; From 6563f63dfd8eb3b3e5db20b774ca3fadb3aac4b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 15:52:15 +0200 Subject: [PATCH 1298/1414] * grub-core/disk/raid.c (scan_devices): Check partition. * grub-core/disk/lvm.c (do_lvm_scan): Likewise. --- ChangeLog | 5 +++++ grub-core/disk/lvm.c | 7 ++++++- grub-core/disk/raid.c | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfb00531a..d2fc4ba84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-28 Vladimir Serbinenko + + * grub-core/disk/raid.c (scan_devices): Check partition. + * grub-core/disk/lvm.c (do_lvm_scan): Likewise. + 2011-10-27 Vladimir Serbinenko Support BFS (befs) UUID. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 7c19f08de..7c65db4ab 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -153,7 +154,11 @@ do_lvm_scan (const char *scan_for) for (vg = vg_list; vg; vg = vg->next) for (pv = vg->pvs; pv; pv = pv->next) if (pv->disk && pv->disk->id == disk->id - && pv->disk->dev->id == disk->dev->id) + && pv->disk->dev->id == disk->dev->id + && grub_partition_get_start (pv->disk->partition) + == grub_partition_get_start (disk->partition) + && grub_partition_get_len (pv->disk->partition) + == grub_partition_get_len (disk->partition)) { grub_disk_close (disk); return 0; diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 5d8326daf..07249eabc 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include #endif @@ -119,7 +120,11 @@ scan_devices (const char *arname) struct grub_raid_member *m; for (m = arr->members; m < arr->members + arr->nr_devs; m++) if (m->device && m->device->id == disk->id - && m->device->dev->id == m->device->dev->id) + && m->device->dev->id == m->device->dev->id + && grub_partition_get_start (m->device->partition) + == grub_partition_get_start (disk->partition) + && grub_partition_get_len (m->device->partition) + == grub_partition_get_len (disk->partition)) { grub_disk_close (disk); return 0; From ad03fe768e8b47cb51612dfa3545fd1a892bbe7f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 15:59:47 +0200 Subject: [PATCH 1299/1414] Correct befs block counting logic. * grub-core/fs/afs.c (GRUB_AFS_BLOCKS_PER_DI_RUN): Replaced with... (GRUB_AFS_LOG_BLOCKS_PER_DI_RUN): ... this. (GRUB_AFS_BLOCKRUN_LOG_SIZE): New definition. (grub_afs_read_inode): Use block_shift. (RANGE_SHIFT): New definition. (grub_afs_read_block): Account for RANGE_SHIFT, emit errors on unexpected conditions, use shifts and appropriate types. (GRUB_MOD_INIT): Check the value of GRUB_AFS_BLOCKRUN_LOG_SIZE. --- ChangeLog | 13 +++++++++ grub-core/fs/afs.c | 67 ++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2fc4ba84..64ae05ef4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-10-28 Vladimir Serbinenko + + Correct befs block counting logic. + + * grub-core/fs/afs.c (GRUB_AFS_BLOCKS_PER_DI_RUN): Replaced with... + (GRUB_AFS_LOG_BLOCKS_PER_DI_RUN): ... this. + (GRUB_AFS_BLOCKRUN_LOG_SIZE): New definition. + (grub_afs_read_inode): Use block_shift. + (RANGE_SHIFT): New definition. + (grub_afs_read_block): Account for RANGE_SHIFT, emit errors on + unexpected conditions, use shifts and appropriate types. + (GRUB_MOD_INIT): Check the value of GRUB_AFS_BLOCKRUN_LOG_SIZE. + 2011-10-28 Vladimir Serbinenko * grub-core/disk/raid.c (scan_devices): Check partition. diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c index ea7a9e9ed..9a646ac88 100644 --- a/grub-core/fs/afs.c +++ b/grub-core/fs/afs.c @@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #endif #define GRUB_AFS_DIRECT_BLOCK_COUNT 12 -#define GRUB_AFS_BLOCKS_PER_DI_RUN 4 +#define GRUB_AFS_LOG_BLOCKS_PER_DI_RUN 2 #ifdef MODE_BFS #define GRUB_AFS_SBLOCK_SECTOR 1 @@ -103,6 +103,7 @@ typedef grub_uint64_t grub_afs_off_t; typedef grub_uint64_t grub_afs_bigtime; typedef grub_uint64_t grub_afs_bvalue_t; +#define GRUB_AFS_BLOCKRUN_LOG_SIZE 3 struct grub_afs_blockrun { grub_uint32_t group; @@ -262,8 +263,7 @@ grub_afs_read_inode (struct grub_afs_data *data, grub_uint64_t ino, struct grub_afs_inode *inode) { return grub_disk_read (data->disk, - ino * - (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS), + ino << (data->sblock.block_shift - GRUB_DISK_SECTOR_BITS), 0, data->sblock.block_size, inode); } @@ -340,13 +340,19 @@ grub_afs_read_attribute (grub_fshelp_node_t node, } #endif +#ifdef MODE_BFS +#define RANGE_SHIFT sb->block_shift +#else +#define RANGE_SHIFT 0 +#endif + static grub_disk_addr_t grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { struct grub_afs_sblock *sb = &node->data->sblock; struct grub_afs_datastream *ds = &node->inode.stream; - if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range)) + if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_direct_range)) { int i; @@ -356,21 +362,24 @@ grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock; fileblock -= grub_afs_to_cpu16 (ds->direct[i].len); } + grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); + return 0; } - else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range)) + else if ((fileblock << RANGE_SHIFT) + < grub_afs_to_cpu64 (ds->max_indirect_range)) { - int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun); + grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); struct grub_afs_blockrun indir[ptrs_per_blk]; grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect); int i; - fileblock -= grub_afs_to_cpu64 (ds->max_direct_range); + fileblock -= grub_afs_to_cpu64 (ds->max_direct_range) >> RANGE_SHIFT; for (i = 0; i < ds->indirect.len; i++, blk++) { - int j; + grub_size_t j; if (grub_disk_read (node->data->disk, - blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS), + blk << (sb->block_shift - GRUB_DISK_SECTOR_BITS), 0, sizeof (indir), indir)) return 0; @@ -383,43 +392,47 @@ grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) fileblock -= grub_afs_to_cpu16 (indir[j].len); } } + grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); + return 0; } - else + else if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_double_indirect_range)) { - int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun); + grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); struct grub_afs_blockrun indir[ptrs_per_blk]; - + grub_disk_addr_t off, dptr, dblk, idptr, idblk; /* ([idblk][idptr]) ([dblk][dptr]) [blk] */ - int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range); - int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN; - int dblk_size = dptr_size * ptrs_per_blk; - int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN; - int idblk_size = idptr_size * ptrs_per_blk; + fileblock -= grub_afs_to_cpu64 (ds->max_indirect_range) >> RANGE_SHIFT; - int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN; - int dptr = (cur_pos / dptr_size) % ptrs_per_blk; - int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN; - int idptr = (cur_pos / idptr_size) % ptrs_per_blk; - int idblk = (cur_pos / idblk_size); + /* Divisions and modulo fixed number are optimised by compiler. */ + off = fileblock & ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); + dptr = fileblock >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; + dblk = dptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); + dptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); + idptr = dblk >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; + dblk &= ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); + idblk = idptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); + idptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); if (grub_disk_read (node->data->disk, (grub_afs_run_to_num (sb, &ds->double_indirect) - + idblk) * - (sb->block_size >> GRUB_DISK_SECTOR_BITS), + + idblk) << (sb->block_shift - GRUB_DISK_SECTOR_BITS), 0, sizeof (indir), indir)) return 0; if (grub_disk_read (node->data->disk, - (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) * - (sb->block_size >> GRUB_DISK_SECTOR_BITS), + (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) + << (sb->block_shift - GRUB_DISK_SECTOR_BITS), 0, sizeof (indir), indir)) return 0; return grub_afs_run_to_num (sb, &indir[dptr]) + off; } + + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "triple-indirect on " GRUB_AFS_FSNAME " isn't supported"); return 0; } @@ -837,6 +850,8 @@ GRUB_MOD_INIT (afs_be) GRUB_MOD_INIT (afs) #endif { + COMPILE_TIME_ASSERT ((1 << GRUB_AFS_BLOCKRUN_LOG_SIZE) + == sizeof (struct grub_afs_blockrun)); grub_fs_register (&grub_afs_fs); my_mod = mod; } From ed9ba06dd011b1e66bcb757f4cb5e4a4db54ecbc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:05:16 +0200 Subject: [PATCH 1300/1414] Use shifts in squash4. * grub-core/fs/squash4.c (grub_squash_data): New field log2_blksz. (squash_mount): Check block size and take logarithm. (direct_read): Use shifts. --- ChangeLog | 8 ++++++++ grub-core/fs/squash4.c | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 64ae05ef4..6d0cfde93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-28 Vladimir Serbinenko + + Use shifts in squash4. + + * grub-core/fs/squash4.c (grub_squash_data): New field log2_blksz. + (squash_mount): Check block size and take logarithm. + (direct_read): Use shifts. + 2011-10-28 Vladimir Serbinenko Correct befs block counting logic. diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index d45732c16..a3832b6be 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -173,6 +173,7 @@ struct grub_squash_data struct grub_squash_super sb; struct grub_squash_cache_inode ino; grub_uint64_t fragments; + int log2_blksz; }; struct grub_fshelp_node @@ -267,7 +268,10 @@ squash_mount (grub_disk_t disk) grub_error (GRUB_ERR_BAD_FS, "not a squash4"); if (err) return NULL; - if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC) + if (grub_le_to_cpu32 (sb.magic) != SQUASH_MAGIC + || grub_le_to_cpu32 (sb.block_size) == 0 + || ((grub_le_to_cpu32 (sb.block_size) - 1) + & grub_le_to_cpu32 (sb.block_size))) { grub_error (GRUB_ERR_BAD_FS, "not squash4"); return NULL; @@ -290,6 +294,10 @@ squash_mount (grub_disk_t disk) data->disk = disk; data->fragments = grub_le_to_cpu64 (frag); + for (data->log2_blksz = 0; + (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sb.block_size); + data->log2_blksz++); + return data; } @@ -528,10 +536,9 @@ direct_read (struct grub_squash_data *data, block_offset = ((char *) &ino->ino.file.block_size - (char *) &ino->ino); } - total_blocks = grub_divmod64 (total_size - + grub_le_to_cpu32 (data->sb.block_size) - 1, - grub_le_to_cpu32 (data->sb.block_size), - 0); + total_blocks = ((total_size + + grub_le_to_cpu32 (data->sb.block_size) - 1) + >> data->log2_blksz); ino->block_sizes = grub_malloc (total_blocks * sizeof (ino->block_sizes[0])); ino->cumulated_block_sizes = grub_malloc (total_blocks @@ -565,7 +572,7 @@ direct_read (struct grub_squash_data *data, if (a == 0) a = sizeof (struct grub_squash_super); - i = grub_divmod64 (off, grub_le_to_cpu32 (data->sb.block_size), 0); + i = off >> data->log2_blksz; cumulated_uncompressed_size = grub_le_to_cpu32 (data->sb.block_size) * (grub_disk_addr_t) i; while (cumulated_uncompressed_size < off + len) From 564dd58c2acf88c5f2a046eae52feb62332dde61 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:09:20 +0200 Subject: [PATCH 1301/1414] Use shifts in minix filesystem. * grub-core/fs/minix.c (GRUB_MINIX_ZONESZ): Use log_block_size. (GRUB_MINIX_ZONE2SECT): Likewise. (grub_minix_data): Replace block_size with log_block_size. (grub_minix_read_file): Use shifts. (grub_minix_mount): Check block size and take a logarithm. --- ChangeLog | 10 ++++++++++ grub-core/fs/minix.c | 32 +++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d0cfde93..f73d431d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-28 Vladimir Serbinenko + + Use shifts in minix filesystem. + + * grub-core/fs/minix.c (GRUB_MINIX_ZONESZ): Use log_block_size. + (GRUB_MINIX_ZONE2SECT): Likewise. + (grub_minix_data): Replace block_size with log_block_size. + (grub_minix_read_file): Use shifts. + (grub_minix_mount): Check block size and take a logarithm. + 2011-10-28 Vladimir Serbinenko Use shifts in squash4. diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index 43785b657..401883e36 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -76,11 +76,11 @@ typedef grub_uint16_t grub_minix_ino_t; #define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \ + grub_le_to_cpu16 (data->sblock.log2_zone_size)) #endif -#define GRUB_MINIX_ZONESZ (data->block_size \ - << grub_le_to_cpu16 (data->sblock.log2_zone_size)) +#define GRUB_MINIX_ZONESZ (1 << (data->log_block_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)) +#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << (data->log_block_size - GRUB_DISK_SECTOR_BITS)) #else #define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ) #endif @@ -159,7 +159,7 @@ struct grub_minix_data int linknest; grub_disk_t disk; int filename_size; - grub_size_t block_size; + grub_size_t log_block_size; }; static grub_dl_t my_mod; @@ -251,14 +251,15 @@ grub_minix_read_file (struct grub_minix_data *data, if (len + pos > GRUB_MINIX_INODE_SIZE (data)) len = GRUB_MINIX_INODE_SIZE (data) - pos; - blockcnt = grub_divmod64 ((len + pos + data->block_size - 1), - data->block_size, 0); - posblock = grub_divmod64 (pos, data->block_size, &blockoff); + blockcnt = ((len + pos + (1 << data->log_block_size) - 1) + >> data->log_block_size); + posblock = pos >> data->log_block_size; + blockoff = pos & ((1 << data->log_block_size) - 1); for (i = posblock; i < blockcnt; i++) { grub_disk_addr_t blknr; - grub_uint64_t blockend = data->block_size; + grub_uint64_t blockend = 1 << data->log_block_size; grub_off_t skipfirst = 0; blknr = grub_minix_get_file_block (data, i); @@ -268,10 +269,10 @@ grub_minix_read_file (struct grub_minix_data *data, /* Last block. */ if (i == blockcnt - 1) { - grub_divmod64 (len + pos, data->block_size, &blockend); + blockend = (len + pos) & ((1 << data->log_block_size) - 1); if (!blockend) - blockend = data->block_size; + blockend = 1 << data->log_block_size; } /* First block. */ @@ -289,7 +290,7 @@ grub_minix_read_file (struct grub_minix_data *data, if (grub_errno) return -1; - buf += data->block_size - skipfirst; + buf += (1 << data->log_block_size) - skipfirst; } return len; @@ -479,9 +480,14 @@ grub_minix_mount (grub_disk_t disk) data->disk = disk; data->linknest = 0; #ifdef MODE_MINIX3 - data->block_size = grub_le_to_cpu16 (data->sblock.block_size); + if ((grub_le_to_cpu16 (data->sblock.block_size) + & (grub_le_to_cpu16 (data->sblock.block_size) - 1)) + || grub_le_to_cpu16 (data->sblock.block_size) == 0) + goto fail; + for (data->log_block_size = 0; (1 << data->log_block_size) + < grub_le_to_cpu16 (data->sblock.block_size); data->log_block_size++); #else - data->block_size = 1024U; + data->log_block_size = 10; #endif return data; From e551115a26167205995f315881881ddf0db7b722 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:21:18 +0200 Subject: [PATCH 1302/1414] Use shifts in nilfs2. * grub-core/fs/nilfs2.c (LOG_INODE_SIZE): New definition. (LOG_NILFS_DAT_ENTRY_SIZE): Likewise. (grub_nilfs2_palloc_entries_per_group): Replace with ... (grub_nilfs2_log_palloc_entries_per_group): ... this. (grub_nilfs2_palloc_group): Use shifts and bitmasks. (grub_nilfs2_entries_per_block): Replaced with ... (grub_nilfs2_log_entries_per_block_log): ... this. (grub_nilfs2_blocks_per_group): Replaced with ... (grub_nilfs2_blocks_per_group_log): ... this. (grub_nilfs2_blocks_per_desc_block): Replaced with ... (grub_nilfs2_blocks_per_desc_block_log): ... this. (grub_nilfs2_palloc_desc_block_offset): Replaced with ... (grub_nilfs2_palloc_desc_block_offset_log): ... this. (grub_nilfs2_palloc_entry_offset): Replaced ... (grub_nilfs2_palloc_entry_offset_log): ... this. Use shifts. (grub_nilfs2_dat_translate): Use shifts. (grub_nilfs2_read_inode): Likewise. (GRUB_MOD_INIT): Ensure that logs are correct. --- ChangeLog | 23 ++++++++++++ grub-core/fs/nilfs2.c | 87 +++++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index f73d431d2..979b5335a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2011-10-28 Vladimir Serbinenko + + Use shifts in nilfs2. + + * grub-core/fs/nilfs2.c (LOG_INODE_SIZE): New definition. + (LOG_NILFS_DAT_ENTRY_SIZE): Likewise. + (grub_nilfs2_palloc_entries_per_group): Replace with ... + (grub_nilfs2_log_palloc_entries_per_group): ... this. + (grub_nilfs2_palloc_group): Use shifts and bitmasks. + (grub_nilfs2_entries_per_block): Replaced with ... + (grub_nilfs2_log_entries_per_block_log): ... this. + (grub_nilfs2_blocks_per_group): Replaced with ... + (grub_nilfs2_blocks_per_group_log): ... this. + (grub_nilfs2_blocks_per_desc_block): Replaced with ... + (grub_nilfs2_blocks_per_desc_block_log): ... this. + (grub_nilfs2_palloc_desc_block_offset): Replaced with ... + (grub_nilfs2_palloc_desc_block_offset_log): ... this. + (grub_nilfs2_palloc_entry_offset): Replaced ... + (grub_nilfs2_palloc_entry_offset_log): ... this. Use shifts. + (grub_nilfs2_dat_translate): Use shifts. + (grub_nilfs2_read_inode): Likewise. + (GRUB_MOD_INIT): Ensure that logs are correct. + 2011-10-28 Vladimir Serbinenko Use shifts in minix filesystem. diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 5986002ef..a8bbe9566 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -58,6 +58,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); in 512 block size */ #define NILFS_2ND_SUPER_BLOCK(devsize) (((devsize >> 3) - 1) << 3) +#define LOG_INODE_SIZE 7 struct grub_nilfs2_inode { grub_uint64_t i_blocks; @@ -214,6 +215,7 @@ struct grub_nilfs2_palloc_group_desc grub_uint32_t pg_nfrees; }; +#define LOG_NILFS_DAT_ENTRY_SIZE 5 struct grub_nilfs2_dat_entry { grub_uint64_t de_blocknr; @@ -296,17 +298,17 @@ static grub_dl_t my_mod; static inline unsigned long -grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data) +grub_nilfs2_log_palloc_entries_per_group (struct grub_nilfs2_data *data) { - return 1UL << (LOG2_BLOCK_SIZE (data) + 3); + return LOG2_BLOCK_SIZE (data) + 3; } static inline grub_uint64_t grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, grub_uint64_t nr, grub_uint64_t * offset) { - return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data), - offset); + *offset = nr & ((1 << grub_nilfs2_log_palloc_entries_per_group (data)) - 1); + return nr >> grub_nilfs2_log_palloc_entries_per_group (data); } static inline grub_uint32_t @@ -317,55 +319,58 @@ grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data) } static inline grub_uint32_t -grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data, - unsigned long entry_size) +grub_nilfs2_log_entries_per_block_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) { - return NILFS2_BLOCK_SIZE (data) / entry_size; + return LOG2_BLOCK_SIZE (data) - log_entry_size; } static inline grub_uint32_t -grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data, - unsigned long entry_size) +grub_nilfs2_blocks_per_group_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) { - return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data), - grub_nilfs2_entries_per_block (data, - entry_size)) + 1; + return (1 << (grub_nilfs2_log_palloc_entries_per_group (data) + - grub_nilfs2_log_entries_per_block_log (data, + log_entry_size))) + 1; } static inline grub_uint32_t -grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data, - unsigned long entry_size) +grub_nilfs2_blocks_per_desc_block_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) { return grub_nilfs2_palloc_groups_per_desc_block (data) * - grub_nilfs2_blocks_per_group (data, entry_size) + 1; + grub_nilfs2_blocks_per_group_log (data, log_entry_size) + 1; } static inline grub_uint32_t -grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data, - unsigned long group, - unsigned long entry_size) +grub_nilfs2_palloc_desc_block_offset_log (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long log_entry_size) { grub_uint32_t desc_block = group / grub_nilfs2_palloc_groups_per_desc_block (data); - return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size); + return desc_block * grub_nilfs2_blocks_per_desc_block_log (data, + log_entry_size); } static inline grub_uint32_t grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, unsigned long group, - unsigned long entry_size) + unsigned long log_entry_size) { unsigned long desc_offset = group % grub_nilfs2_palloc_groups_per_desc_block (data); - return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 + - desc_offset * grub_nilfs2_blocks_per_group (data, entry_size); + return grub_nilfs2_palloc_desc_block_offset_log (data, group, log_entry_size) + + 1 + + desc_offset * grub_nilfs2_blocks_per_group_log (data, log_entry_size); } static inline grub_uint32_t -grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, - grub_uint64_t nr, unsigned long entry_size) +grub_nilfs2_palloc_entry_offset_log (struct grub_nilfs2_data *data, + grub_uint64_t nr, + unsigned long log_entry_size) { unsigned long group; grub_uint64_t group_offset; @@ -373,10 +378,9 @@ grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, group = grub_nilfs2_palloc_group (data, nr, &group_offset); return grub_nilfs2_palloc_bitmap_block_offset (data, group, - entry_size) + 1 + - grub_divmod64 (group_offset, grub_nilfs2_entries_per_block (data, - entry_size), - NULL); + 1 << log_entry_size) + 1 + + (group_offset >> grub_nilfs2_log_entries_per_block_log (data, + log_entry_size)); } @@ -582,12 +586,11 @@ grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key) grub_uint64_t blockno, offset; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); - blockno = grub_nilfs2_palloc_entry_offset (data, key, - sizeof (struct - grub_nilfs2_dat_entry)); + blockno = grub_nilfs2_palloc_entry_offset_log (data, key, + LOG_NILFS_DAT_ENTRY_SIZE); - grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry), - NILFS2_BLOCK_SIZE (data), &offset); + offset = ((key * sizeof (struct grub_nilfs2_dat_entry)) + & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0); if (pptr == (grub_uint64_t) - 1) @@ -652,8 +655,8 @@ grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, sizeof(struct grub_nilfs2_checkpoint). */ blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) / - sizeof (struct grub_nilfs2_checkpoint), &offset); - + sizeof (struct grub_nilfs2_checkpoint), &offset); + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1); if (pptr == (grub_uint64_t) - 1) { @@ -686,12 +689,11 @@ grub_nilfs2_read_inode (struct grub_nilfs2_data *data, grub_disk_t disk = data->disk; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); - blockno = grub_nilfs2_palloc_entry_offset (data, ino, - sizeof (struct - grub_nilfs2_inode)); + blockno = grub_nilfs2_palloc_entry_offset_log (data, ino, + LOG_INODE_SIZE); - grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino, - NILFS2_BLOCK_SIZE (data), &offset); + offset = ((sizeof (struct grub_nilfs2_inode) * ino) + & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1); if (pptr == (grub_uint64_t) - 1) { @@ -1178,6 +1180,11 @@ static struct grub_fs grub_nilfs2_fs = { GRUB_MOD_INIT (nilfs2) { + COMPILE_TIME_ASSERT ((1 << LOG_NILFS_DAT_ENTRY_SIZE) + == sizeof (struct + grub_nilfs2_dat_entry)); + COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE + == sizeof (struct grub_nilfs2_inode)); grub_fs_register (&grub_nilfs2_fs); my_mod = mod; } From c39224b052b2322cc75bca9432fdb29617415c82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 28 Oct 2011 16:26:17 +0200 Subject: [PATCH 1303/1414] Prefer rockridge over Joliet. * grub-core/fs/iso9660.c (grub_iso9660_mount): Move rockridge detection to ... (set_rockridge): ... here. (grub_iso9660_mount): Check rockridge on the primary label when discovering. Ignore Joliet if Rockridge is present. --- ChangeLog | 10 +++ grub-core/fs/iso9660.c | 140 ++++++++++++++++++++++------------------- 2 files changed, 85 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 979b5335a..deaa6ba68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-10-28 Vladimir Serbinenko + + Prefer rockridge over Joliet. + + * grub-core/fs/iso9660.c (grub_iso9660_mount): Move rockridge detection + to ... + (set_rockridge): ... here. + (grub_iso9660_mount): Check rockridge on the primary label when + discovering. Ignore Joliet if Rockridge is present. + 2011-10-28 Vladimir Serbinenko Use shifts in nilfs2. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index f3e828b89..a2e731351 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -347,17 +347,14 @@ grub_iso9660_convert_string (grub_uint16_t *us, int len) return p; } -static struct grub_iso9660_data * -grub_iso9660_mount (grub_disk_t disk) +static grub_err_t +set_rockridge (struct grub_iso9660_data *data) { - struct grub_iso9660_data *data = 0; - struct grub_iso9660_dir rootdir; int sua_pos; int sua_size; char *sua; + struct grub_iso9660_dir rootdir; struct grub_iso9660_susp_entry *entry; - struct grub_iso9660_primary_voldesc voldesc; - int block; auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *); @@ -373,6 +370,67 @@ grub_iso9660_mount (grub_disk_t disk) return 0; } + data->rockridge = 0; + + /* Read the system use area and test it to see if SUSP is + supported. */ + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), 0, + sizeof (rootdir), (char *) &rootdir)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + sua_pos = (sizeof (rootdir) + rootdir.namelen + + (rootdir.namelen % 2) - 1); + sua_size = rootdir.len - sua_pos; + + if (!sua_size) + return GRUB_ERR_NONE; + + sua = grub_malloc (sua_size); + if (! sua) + return grub_errno; + + if (grub_disk_read (data->disk, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, + sua_size, sua)) + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + + entry = (struct grub_iso9660_susp_entry *) sua; + + /* Test if the SUSP protocol is used on this filesystem. */ + if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) + { + struct grub_fshelp_node rootnode; + + rootnode.data = data; + rootnode.alloc_dirents = 0; + rootnode.have_dirents = 1; + rootnode.symlink = 0; + rootnode.dirents[0] = data->voldesc.rootdir; + + /* The 2nd data byte stored how many bytes are skipped every time + to get to the SUA (System Usage Area). */ + data->susp_skip = entry->data[2]; + entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); + + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (&rootnode, + sua_pos, sua_size, susp_iterate)) + return grub_errno; + } + return GRUB_ERR_NONE; +} + +static struct grub_iso9660_data * +grub_iso9660_mount (grub_disk_t disk) +{ + struct grub_iso9660_data *data = 0; + struct grub_iso9660_primary_voldesc voldesc; + int block; + data = grub_zalloc (sizeof (struct grub_iso9660_data)); if (! data) return 0; @@ -400,9 +458,11 @@ grub_iso9660_mount (grub_disk_t disk) } if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY) - copy_voldesc = 1; - else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) && - (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) && + copy_voldesc = 1; + else if (!data->rockridge + && (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) + && (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) + && ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */ (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ @@ -412,66 +472,16 @@ grub_iso9660_mount (grub_disk_t disk) } if (copy_voldesc) - grub_memcpy((char *) &data->voldesc, (char *) &voldesc, - sizeof (struct grub_iso9660_primary_voldesc)); + { + grub_memcpy((char *) &data->voldesc, (char *) &voldesc, + sizeof (struct grub_iso9660_primary_voldesc)); + if (set_rockridge (data)) + goto fail; + } block++; } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); - /* Read the system use area and test it to see if SUSP is - supported. */ - if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), 0, - sizeof (rootdir), (char *) &rootdir)) - { - grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - goto fail; - } - - sua_pos = (sizeof (rootdir) + rootdir.namelen - + (rootdir.namelen % 2) - 1); - sua_size = rootdir.len - sua_pos; - - if (!sua_size) - return data; - - sua = grub_malloc (sua_size); - if (! sua) - goto fail; - - if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, - sua_size, sua)) - { - grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - goto fail; - } - - entry = (struct grub_iso9660_susp_entry *) sua; - - /* Test if the SUSP protocol is used on this filesystem. */ - if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) - { - struct grub_fshelp_node rootnode; - - rootnode.data = data; - rootnode.alloc_dirents = 0; - rootnode.have_dirents = 1; - rootnode.symlink = 0; - rootnode.dirents[0] = data->voldesc.rootdir; - - /* The 2nd data byte stored how many bytes are skipped every time - to get to the SUA (System Usage Area). */ - data->susp_skip = entry->data[2]; - entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); - - /* Iterate over the entries in the SUA area to detect - extensions. */ - if (grub_iso9660_susp_iterate (&rootnode, - sua_pos, sua_size, susp_iterate)) - goto fail; - } - return data; fail: From faba3d163aa2ef77a38e0aebfc0c873fadfdcb35 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 29 Oct 2011 11:29:34 +0200 Subject: [PATCH 1304/1414] Remove afs and befs because of copyright problem. * grub-core/fs/afs.c: Removed. * grub-core/fs/afs_be.c: Removed. * grub-core/fs/befs.c: Removed. * grub-core/fs/befs_be.c: Removed. * Makefile.util.def (libgrubkern): Remove afs, afs_be, befs and befs_be. * grub-core/Makefile.core.def (afs): Removed. (afs_be): Likewise. (befs): Likewise. (befs_be): Likewise. --- ChangeLog | 14 + Makefile.util.def | 4 - grub-core/Makefile.core.def | 20 - grub-core/fs/afs.c | 870 ------------------------------------ grub-core/fs/afs_be.c | 2 - grub-core/fs/befs.c | 3 - grub-core/fs/befs_be.c | 4 - 7 files changed, 14 insertions(+), 903 deletions(-) delete mode 100644 grub-core/fs/afs.c delete mode 100644 grub-core/fs/afs_be.c delete mode 100644 grub-core/fs/befs.c delete mode 100644 grub-core/fs/befs_be.c diff --git a/ChangeLog b/ChangeLog index deaa6ba68..892357ff3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-10-29 Vladimir Serbinenko + + Remove afs and befs because of copyright problem. + + * grub-core/fs/afs.c: Removed. + * grub-core/fs/afs_be.c: Removed. + * grub-core/fs/befs.c: Removed. + * grub-core/fs/befs_be.c: Removed. + * Makefile.util.def (libgrubkern): Remove afs, afs_be, befs and befs_be. + * grub-core/Makefile.core.def (afs): Removed. + (afs_be): Likewise. + (befs): Likewise. + (befs_be): Likewise. + 2011-10-28 Vladimir Serbinenko Prefer rockridge over Joliet. diff --git a/Makefile.util.def b/Makefile.util.def index 1b66ab961..bc66a51d4 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -55,10 +55,6 @@ library = { common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; common = grub-core/fs/affs.c; - common = grub-core/fs/afs_be.c; - common = grub-core/fs/afs.c; - common = grub-core/fs/befs_be.c; - common = grub-core/fs/befs.c; common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 6d3c31ea6..2d91c3b64 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -970,26 +970,6 @@ module = { common = fs/affs.c; }; -module = { - name = afs; - common = fs/afs.c; -}; - -module = { - name = afs_be; - common = fs/afs_be.c; -}; - -module = { - name = befs; - common = fs/befs.c; -}; - -module = { - name = befs_be; - common = fs/befs_be.c; -}; - module = { name = btrfs; common = fs/btrfs.c; diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c deleted file mode 100644 index 9a646ac88..000000000 --- a/grub-core/fs/afs.c +++ /dev/null @@ -1,870 +0,0 @@ -/* afs.c - The native AtheOS file-system. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef MODE_BIGENDIAN -#define GRUB_AFS_FSNAME_SUFFIX "_be" -#else -#define GRUB_AFS_FSNAME_SUFFIX "" -#endif - -#ifdef MODE_BFS -#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX -#else -#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX -#endif - -#define GRUB_AFS_DIRECT_BLOCK_COUNT 12 -#define GRUB_AFS_LOG_BLOCKS_PER_DI_RUN 2 - -#ifdef MODE_BFS -#define GRUB_AFS_SBLOCK_SECTOR 1 -#define GRUB_AFS_SBLOCK_MAGIC1 0x42465331 /* BFS1. */ -#else -#define GRUB_AFS_SBLOCK_SECTOR 2 -#define GRUB_AFS_SBLOCK_MAGIC1 0x41465331 /* AFS1. */ -#endif - -#define GRUB_AFS_SBLOCK_MAGIC2 0xdd121031 -#define GRUB_AFS_SBLOCK_MAGIC3 0x15b6830e - -#define GRUB_AFS_INODE_MAGIC 0x64358428 - -#ifdef MODE_BFS -#define GRUB_AFS_BTREE_MAGIC 0x69f6c2e8 -#else -#define GRUB_AFS_BTREE_MAGIC 0x65768995 -#endif - -#define GRUB_AFS_BNODE_SIZE 1024 - -#define GRUB_AFS_S_IFMT 00170000 -#define GRUB_AFS_S_IFLNK 0120000 - -#define GRUB_AFS_S_IFREG 0100000 -#define GRUB_AFS_S_IFDIR 0040000 -#define GRUB_AFS_S_IFIFO 0010000 - -#define GRUB_AFS_NULL_VAL ((grub_afs_bvalue_t)-1) - -#ifdef MODE_BIGENDIAN -#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x) -#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x) -#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x) -#else -#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x) -#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x) -#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x) -#endif - -#ifdef MODE_BFS -#define B_KEY_INDEX_ALIGN 8 -#else -#define B_KEY_INDEX_ALIGN 4 -#endif - -#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \ - ((char *) (node) \ - + ALIGN_UP (sizeof (struct grub_afs_bnode) \ - + node->key_size, \ - B_KEY_INDEX_ALIGN))) - -#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \ - ((char *) B_KEY_INDEX_OFFSET (node) + \ - node->key_count * 2)) - -typedef grub_uint64_t grub_afs_off_t; -typedef grub_uint64_t grub_afs_bigtime; -typedef grub_uint64_t grub_afs_bvalue_t; - -#define GRUB_AFS_BLOCKRUN_LOG_SIZE 3 -struct grub_afs_blockrun -{ - grub_uint32_t group; - grub_uint16_t start; - grub_uint16_t len; -} __attribute__ ((packed)); - -struct grub_afs_datastream -{ - struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT]; - grub_afs_off_t max_direct_range; - struct grub_afs_blockrun indirect; - grub_afs_off_t max_indirect_range; - struct grub_afs_blockrun double_indirect; - grub_afs_off_t max_double_indirect_range; - grub_afs_off_t size; -} __attribute__ ((packed)); - -struct grub_afs_bnode -{ - grub_afs_bvalue_t left; - grub_afs_bvalue_t right; - grub_afs_bvalue_t overflow; -#ifdef MODE_BFS - grub_uint16_t key_count; - grub_uint16_t key_size; -#else - grub_uint32_t key_count; - grub_uint32_t key_size; -#endif - char key_data[0]; -} __attribute__ ((packed)); - -#ifdef MODE_BFS -struct grub_afs_btree -{ - grub_uint32_t magic; - grub_uint32_t unused1; - grub_uint32_t tree_depth; - grub_uint32_t unused2; - grub_afs_bvalue_t root; - grub_uint32_t unused3[4]; -} __attribute__ ((packed)); -#else -struct grub_afs_btree -{ - grub_uint32_t magic; - grub_afs_bvalue_t root; - grub_uint32_t tree_depth; - grub_afs_bvalue_t last_node; - grub_afs_bvalue_t first_free; -} __attribute__ ((packed)); -#endif - -/* Beware that following structure describes AtheFS and if you write code - which uses currently unused fields check it with both AtheFS and BeFS. - */ -struct grub_afs_sblock -{ - char name[32]; - grub_uint32_t magic1; - grub_uint32_t byte_order; - grub_uint32_t block_size; - grub_uint32_t block_shift; - grub_afs_off_t num_blocks; - grub_afs_off_t used_blocks; - grub_uint32_t inode_size; - grub_uint32_t magic2; - grub_uint32_t block_per_group; /* Number of blocks per allocation - group. (Max 65536) */ - grub_uint32_t alloc_group_shift; /* Number of bits to shift a group - number to get a byte address. */ - grub_uint32_t alloc_group_count; - grub_uint32_t flags; - struct grub_afs_blockrun log_block; - grub_afs_off_t log_start; - grub_uint32_t valid_log_blocks; - grub_uint32_t log_size; - grub_uint32_t magic3; - struct grub_afs_blockrun root_dir; /* Root dir inode. */ - struct grub_afs_blockrun deleted_files; /* Directory containing files - scheduled for deletion. */ - struct grub_afs_blockrun index_dir; /* Directory of index files. */ - grub_uint32_t boot_loader_size; - grub_uint32_t pad[7]; -} __attribute__ ((packed)); - -struct grub_afs_inode -{ - grub_uint32_t magic1; - struct grub_afs_blockrun inode_num; - grub_uint32_t uid; - grub_uint32_t gid; - grub_uint32_t mode; - grub_uint32_t flags; -#ifndef MODE_BFS - grub_uint32_t link_count; -#endif - grub_afs_bigtime create_time; - grub_afs_bigtime modified_time; - struct grub_afs_blockrun parent; - struct grub_afs_blockrun attrib_dir; - grub_uint32_t index_type; /* Key data-key only used for index files. */ - grub_uint32_t inode_size; - grub_uint32_t unused; - struct grub_afs_datastream stream; - grub_uint32_t pad[4]; - grub_uint8_t small_data[0]; -} __attribute__ ((packed)); - -struct grub_afs_small_data_element_header -{ - grub_uint32_t type; - grub_uint16_t name_len; - grub_uint16_t value_len; -} __attribute__ ((packed)); - -struct grub_fshelp_node -{ - struct grub_afs_data *data; - struct grub_afs_inode inode; -}; - -struct grub_afs_data -{ - grub_disk_t disk; - struct grub_afs_sblock sblock; - struct grub_afs_inode *inode; - struct grub_fshelp_node diropen; -}; - -static grub_dl_t my_mod; - -static int -grub_afs_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)); -static grub_ssize_t -grub_afs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - grub_off_t pos, grub_size_t len, char *buf); - - -static grub_afs_off_t -grub_afs_run_to_num (struct grub_afs_sblock *sb, - struct grub_afs_blockrun *run) -{ - return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group) - * sb->block_per_group + grub_afs_to_cpu16 (run->start)); -} - -static grub_err_t -grub_afs_read_inode (struct grub_afs_data *data, - grub_uint64_t ino, struct grub_afs_inode *inode) -{ - return grub_disk_read (data->disk, - ino << (data->sblock.block_shift - GRUB_DISK_SECTOR_BITS), - 0, data->sblock.block_size, inode); -} - -#ifdef MODE_BFS -static grub_ssize_t -grub_afs_read_attribute (grub_fshelp_node_t node, - const char *name, char *buf, grub_size_t len) -{ - grub_ssize_t read = -1; - auto int NESTED_FUNC_ATTR hook (const char *filename, - enum grub_fshelp_filetype filetype - __attribute__ ((unused)), - grub_fshelp_node_t attr_node); - - int NESTED_FUNC_ATTR hook (const char *filename, - enum grub_fshelp_filetype filetype - __attribute__ ((unused)), - grub_fshelp_node_t attr_node) - { - if (grub_strcmp (filename, name) == 0) - { - read = grub_afs_read_file (attr_node, 0, 0, len, buf); - return 1; - } - return 0; - } - grub_uint8_t *ptr = node->inode.small_data; - grub_uint8_t *end = ((grub_uint8_t *) &node->inode - + node->data->sblock.block_size); - - while (ptr + sizeof (struct grub_afs_small_data_element_header) < end) - { - struct grub_afs_small_data_element_header *el; - char *el_name; - grub_uint8_t *data; - el = (struct grub_afs_small_data_element_header *) ptr; - if (el->name_len == 0) - break; - el_name = (char *) (el + 1); - data = (grub_uint8_t *) el_name + grub_afs_to_cpu16 (el->name_len) + 3; - ptr = data + grub_afs_to_cpu16 (el->value_len) + 1; - if (grub_memcmp (name, el_name, grub_afs_to_cpu16 (el->name_len)) == 0 - && name[el->name_len] == 0) - { - grub_size_t copy; - copy = len; - if (grub_afs_to_cpu16 (el->value_len) > copy) - copy = grub_afs_to_cpu16 (el->value_len); - grub_memcpy (buf, data, copy); - return copy; - } - } - - { - struct grub_fshelp_node *fdiro; - - fdiro = grub_malloc (sizeof (struct grub_fshelp_node) - + node->data->sblock.block_size - - sizeof (struct grub_afs_inode)); - if (! fdiro) - return -1; - - fdiro->data = node->data; - if (grub_afs_read_inode (node->data, - grub_afs_run_to_num (&node->data->sblock, - &node->inode.attrib_dir), - &fdiro->inode)) - return -1; - - grub_afs_iterate_dir (fdiro, hook); - } - - return read; -} -#endif - -#ifdef MODE_BFS -#define RANGE_SHIFT sb->block_shift -#else -#define RANGE_SHIFT 0 -#endif - -static grub_disk_addr_t -grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) -{ - struct grub_afs_sblock *sb = &node->data->sblock; - struct grub_afs_datastream *ds = &node->inode.stream; - - if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_direct_range)) - { - int i; - - for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++) - { - if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len)) - return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock; - fileblock -= grub_afs_to_cpu16 (ds->direct[i].len); - } - grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); - return 0; - } - else if ((fileblock << RANGE_SHIFT) - < grub_afs_to_cpu64 (ds->max_indirect_range)) - { - grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); - struct grub_afs_blockrun indir[ptrs_per_blk]; - grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect); - int i; - - fileblock -= grub_afs_to_cpu64 (ds->max_direct_range) >> RANGE_SHIFT; - for (i = 0; i < ds->indirect.len; i++, blk++) - { - grub_size_t j; - - if (grub_disk_read (node->data->disk, - blk << (sb->block_shift - GRUB_DISK_SECTOR_BITS), - 0, sizeof (indir), - indir)) - return 0; - - for (j = 0; j < ptrs_per_blk; j++) - { - if (fileblock < grub_afs_to_cpu16 (indir[j].len)) - return grub_afs_run_to_num (sb, &indir[j]) + fileblock; - - fileblock -= grub_afs_to_cpu16 (indir[j].len); - } - } - grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); - return 0; - } - else if ((fileblock << RANGE_SHIFT) < grub_afs_to_cpu64 (ds->max_double_indirect_range)) - { - grub_size_t ptrs_per_blk = (1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)); - struct grub_afs_blockrun indir[ptrs_per_blk]; - grub_disk_addr_t off, dptr, dblk, idptr, idblk; - /* ([idblk][idptr]) ([dblk][dptr]) [blk] */ - - fileblock -= grub_afs_to_cpu64 (ds->max_indirect_range) >> RANGE_SHIFT; - - /* Divisions and modulo fixed number are optimised by compiler. */ - off = fileblock & ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); - dptr = fileblock >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; - dblk = dptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); - dptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); - idptr = dblk >> GRUB_AFS_LOG_BLOCKS_PER_DI_RUN; - dblk &= ((1 << GRUB_AFS_LOG_BLOCKS_PER_DI_RUN) - 1); - idblk = idptr >> (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE); - idptr &= ((1 << (sb->block_shift - GRUB_AFS_BLOCKRUN_LOG_SIZE)) - 1); - - if (grub_disk_read (node->data->disk, - (grub_afs_run_to_num (sb, &ds->double_indirect) - + idblk) << (sb->block_shift - GRUB_DISK_SECTOR_BITS), - 0, sizeof (indir), - indir)) - return 0; - - if (grub_disk_read (node->data->disk, - (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) - << (sb->block_shift - GRUB_DISK_SECTOR_BITS), - 0, sizeof (indir), - indir)) - return 0; - - return grub_afs_run_to_num (sb, &indir[dptr]) + off; - } - - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "triple-indirect on " GRUB_AFS_FSNAME " isn't supported"); - - return 0; -} - -static grub_ssize_t -grub_afs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - grub_off_t pos, grub_size_t len, char *buf) -{ - return grub_fshelp_read_file (node->data->disk, node, read_hook, - pos, len, buf, grub_afs_read_block, - grub_afs_to_cpu64 (node->inode.stream.size), - node->data->sblock.block_shift - - GRUB_DISK_SECTOR_BITS); -} - -static char * -grub_afs_read_symlink (grub_fshelp_node_t node) -{ - char *ret; - grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size); - - if (size == 0) - { - size = sizeof (node->inode.stream); - ret = grub_zalloc (size + 1); - if (! ret) - return 0; - grub_memcpy (ret, (char *) &(node->inode.stream), - sizeof (node->inode.stream)); - return ret; - } - ret = grub_zalloc (size + 1); - if (! ret) - return 0; - grub_afs_read_file (node, 0, 0, size, ret); - return ret; -} - -static int -grub_afs_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)) -{ - struct grub_afs_btree head; - char node_data [GRUB_AFS_BNODE_SIZE]; - struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data; - int i; - - if ((dir->inode.stream.size == 0) - || ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT) - != GRUB_AFS_S_IFDIR)) - return 0; - - grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head); - if (grub_errno) - return 0; - - grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root), - GRUB_AFS_BNODE_SIZE, (char *) node); - if (grub_errno) - return 0; - - for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++) - { - grub_afs_bvalue_t blk; - - blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]); - grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node); - if (grub_errno) - return 0; - } - - if (node->key_count) - { - grub_uint32_t cur_key = 0; - - while (1) - { - int key_start, key_size; - grub_uint16_t *index; - - index = B_KEY_INDEX_OFFSET (node); - - key_start = (cur_key > 0) - ? grub_afs_to_cpu16 (index[cur_key - 1]) : 0; - key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start; - if (key_size > 0) - { - char filename [key_size + 1]; - struct grub_fshelp_node *fdiro; - int mode, type; - - fdiro = grub_malloc (sizeof (struct grub_fshelp_node) - + dir->data->sblock.block_size - - sizeof (struct grub_afs_inode)); - if (! fdiro) - return 0; - - fdiro->data = dir->data; - if (grub_afs_read_inode (dir->data, - grub_afs_to_cpu64 - (B_KEY_VALUE_OFFSET (node) [cur_key]), - &fdiro->inode)) - return 0; - - grub_memcpy (filename, &node->key_data[key_start], key_size); - filename [key_size] = 0; - - mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT); - if (mode == GRUB_AFS_S_IFDIR) - type = GRUB_FSHELP_DIR; - else if (mode == GRUB_AFS_S_IFREG) - type = GRUB_FSHELP_REG; - else if (mode == GRUB_AFS_S_IFLNK) - type = GRUB_FSHELP_SYMLINK; - else - type = GRUB_FSHELP_UNKNOWN; - - if (hook (filename, type, fdiro)) - return 1; - } - - cur_key++; - if (cur_key >= grub_afs_to_cpu32 (node->key_count)) - { - if (node->right == GRUB_AFS_NULL_VAL) - break; - - grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right), - GRUB_AFS_BNODE_SIZE, (char *) node); - if (grub_errno) - return 0; - - cur_key = 0; - } - } - } - - return 0; -} - -static int -grub_afs_validate_sblock (struct grub_afs_sblock *sb) -{ - if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1) - { - sb->magic2 = grub_afs_to_cpu32 (sb->magic2); - sb->magic3 = grub_afs_to_cpu32 (sb->magic3); - sb->block_shift = grub_afs_to_cpu32 (sb->block_shift); - sb->block_size = grub_afs_to_cpu32 (sb->block_size); - sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks); - sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks); - sb->inode_size = grub_afs_to_cpu32 (sb->inode_size); - sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count); - sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift); - sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group); - sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count); - sb->log_size = grub_afs_to_cpu32 (sb->log_size); - } - else - return 0; - - if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) || - (sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3)) - return 0; - -#ifdef MODE_BFS - sb->block_per_group = 1 << (sb->alloc_group_shift); -#endif - - if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size) - || (sb->used_blocks > sb->num_blocks ) - || (sb->inode_size != sb->block_size) - || (0 == sb->block_size) -#ifndef MODE_BFS - || ((grub_uint32_t) (1 << sb->alloc_group_shift) != - sb->block_per_group * sb->block_size) - || (sb->alloc_group_count * sb->block_per_group < sb->num_blocks) - || (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size) - || (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size) -#endif - ) - return 0; - - return 1; -} - -static struct grub_afs_data * -grub_afs_mount (grub_disk_t disk) -{ - struct grub_afs_data *data = 0; - struct grub_afs_sblock sb; - grub_err_t err; - - /* Read the superblock. */ - err = grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0, - sizeof (struct grub_afs_sblock), &sb); - if (err) - { - if (err == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); - return NULL; - } - - if (! grub_afs_validate_sblock (&sb)) - { - grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); - return NULL; - } - - data = grub_malloc (sizeof (struct grub_afs_data) + sb.block_size - - sizeof (struct grub_afs_inode)); - if (!data) - return NULL; - - data->sblock = sb; - - data->diropen.data = data; - data->inode = &data->diropen.inode; - data->disk = disk; - - if (grub_afs_read_inode (data, - grub_afs_run_to_num (&data->sblock, - &data->sblock.root_dir), - data->inode)) - goto fail; - - return data; - -fail: - grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem"); - - grub_free (data); - return 0; -} - -static grub_err_t -grub_afs_open (struct grub_file *file, const char *name) -{ - struct grub_afs_data *data; - struct grub_fshelp_node *fdiro = 0; - - grub_dl_ref (my_mod); - - data = grub_afs_mount (file->device->disk); - if (! data) - goto fail; - - grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir, - grub_afs_read_symlink, GRUB_FSHELP_REG); - if (grub_errno) - goto fail; - - grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode)); - grub_free (fdiro); - - file->size = grub_afs_to_cpu64 (data->inode->stream.size); - file->data = data; - file->offset = 0; - - return 0; - -fail: - grub_free (data); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static grub_ssize_t -grub_afs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_afs_data *data = (struct grub_afs_data *) file->data; - - return grub_afs_read_file (&data->diropen, file->read_hook, - file->offset, len, buf); -} - -static grub_err_t -grub_afs_close (grub_file_t file) -{ - grub_free (file->data); - - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_afs_dir (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)) -{ - struct grub_afs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - 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); - info.mtimeset = 1; -#ifdef MODE_BFS - info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16; -#else - info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time), - 1000000, 0); -#endif - grub_free (node); - return hook (filename, &info); - } - - grub_dl_ref (my_mod); - - data = grub_afs_mount (device->disk); - if (! data) - goto fail; - - grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir, - grub_afs_read_symlink, GRUB_FSHELP_DIR); - if (grub_errno) - goto fail; - - grub_afs_iterate_dir (fdiro, iterate); - - if (fdiro != &data->diropen) - grub_free (fdiro); - - fail: - grub_free (data); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static grub_err_t -grub_afs_label (grub_device_t device, char **label) -{ - struct grub_afs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_afs_mount (disk); - if (data) - *label = grub_strndup (data->sblock.name, sizeof (data->sblock.name)); - else - *label = NULL; - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; -} - -#ifdef MODE_BFS -static grub_err_t -grub_afs_uuid (grub_device_t device, char **uuid) -{ - struct grub_afs_data *data; - grub_disk_t disk = device->disk; - grub_uint64_t vid; - grub_ssize_t read; - - *uuid = NULL; - - data = grub_afs_mount (disk); - if (!data) - return grub_errno; - read = grub_afs_read_attribute (&data->diropen, "be:volume_id", - (char *) &vid, - sizeof (vid)); - if (read == sizeof (vid)) - *uuid = grub_xasprintf ("%" PRIxGRUB_UINT64_T, grub_afs_to_cpu64 (vid)); - - grub_free (data); - - return grub_errno; -} -#endif - -static struct grub_fs grub_afs_fs = { - .name = GRUB_AFS_FSNAME, - .dir = grub_afs_dir, - .open = grub_afs_open, - .read = grub_afs_read, - .close = grub_afs_close, - .label = grub_afs_label, -#ifdef MODE_BFS - .uuid = grub_afs_uuid, -#endif - .next = 0 -}; - -#if defined (MODE_BIGENDIAN) && defined (MODE_BFS) -GRUB_MOD_INIT (befs_be) -#elif defined (MODE_BFS) -GRUB_MOD_INIT (befs) -#elif defined (MODE_BIGENDIAN) -GRUB_MOD_INIT (afs_be) -#else -GRUB_MOD_INIT (afs) -#endif -{ - COMPILE_TIME_ASSERT ((1 << GRUB_AFS_BLOCKRUN_LOG_SIZE) - == sizeof (struct grub_afs_blockrun)); - grub_fs_register (&grub_afs_fs); - my_mod = mod; -} - -#if defined (MODE_BIGENDIAN) && defined (MODE_BFS) -GRUB_MOD_FINI (befs_be) -#elif defined (MODE_BFS) -GRUB_MOD_FINI (befs) -#elif defined (MODE_BIGENDIAN) -GRUB_MOD_FINI (afs_be) -#else -GRUB_MOD_FINI (afs) -#endif -{ - grub_fs_unregister (&grub_afs_fs); -} diff --git a/grub-core/fs/afs_be.c b/grub-core/fs/afs_be.c deleted file mode 100644 index 1f1f48fbb..000000000 --- a/grub-core/fs/afs_be.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_BIGENDIAN 1 -#include "afs.c" diff --git a/grub-core/fs/befs.c b/grub-core/fs/befs.c deleted file mode 100644 index c54d8e1cc..000000000 --- a/grub-core/fs/befs.c +++ /dev/null @@ -1,3 +0,0 @@ -/* befs.c - The native BeOS/Haiku file-system. */ -#define MODE_BFS 1 -#include "afs.c" diff --git a/grub-core/fs/befs_be.c b/grub-core/fs/befs_be.c deleted file mode 100644 index f6e8179f4..000000000 --- a/grub-core/fs/befs_be.c +++ /dev/null @@ -1,4 +0,0 @@ -/* befs.c - The native BeOS/Haiku file-system. */ -#define MODE_BFS 1 -#define MODE_BIGENDIAN 1 -#include "afs.c" From 61b99bfc2a2229f352f74eb8349f54b832e0064b Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Sun, 30 Oct 2011 11:16:23 +0100 Subject: [PATCH 1305/1414] * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs and befs_be. --- ChangeLog | 5 +++++ po/POTFILES.in | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 892357ff3..604a427c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 Yves Blusseau + + * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs + and befs_be. + 2011-10-29 Vladimir Serbinenko Remove afs and befs because of copyright problem. diff --git a/po/POTFILES.in b/po/POTFILES.in index ebb0aadaa..1c718520b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -127,10 +127,6 @@ ./grub-core/font/font.c ./grub-core/font/font_cmd.c ./grub-core/fs/affs.c -./grub-core/fs/afs_be.c -./grub-core/fs/afs.c -./grub-core/fs/befs_be.c -./grub-core/fs/befs.c ./grub-core/fs/btrfs.c ./grub-core/fs/cpio.c ./grub-core/fs/ext2.c From 42b2a706bf071a47d20af08389d1ea3f917f2691 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 13:18:22 +0100 Subject: [PATCH 1306/1414] * util/grub-fstest.c (cmd_cp): Clarify error message. (cmd_cmp): Likewise. --- ChangeLog | 5 +++++ util/grub-fstest.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 604a427c6..d8c4bf764 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 Vladimir Serbinenko + + * util/grub-fstest.c (cmd_cp): Clarify error message. + (cmd_cmp): Likewise. + 2011-10-30 Yves Blusseau * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 60889d05e..996d71c3a 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -182,7 +182,8 @@ cmd_cp (char *src, char *dest) ff = fopen (dest, "wb"); if (ff == NULL) { - grub_util_error (_("open error")); + grub_util_error (_("OS file %s open error: %s"), dest, + strerror (errno)); return; } read_file (src, cp_hook); @@ -241,7 +242,8 @@ cmd_cmp (char *src, char *dest) ff = fopen (dest, "rb"); if (ff == NULL) { - grub_util_error (_("open error")); + grub_util_error (_("OS file %s open error: %s"), dest, + strerror (errno)); return; } From 5825b3794be953aa1b5e2ec564e38713ca59418f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 13:25:51 +0100 Subject: [PATCH 1307/1414] BFS implementation based on the specification. * grub-core/fs/bfs.c: New file. * Makefile.util.def (libgrubmods): Add bfs.c. * grub-core/Makefile.core.def (bfs): New module. --- ChangeLog | 8 + Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/bfs.c | 948 ++++++++++++++++++++++++++++++++++++ 4 files changed, 962 insertions(+) create mode 100644 grub-core/fs/bfs.c diff --git a/ChangeLog b/ChangeLog index d8c4bf764..d8ea7974c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-30 Vladimir Serbinenko + + BFS implementation based on the specification. + + * grub-core/fs/bfs.c: New file. + * Makefile.util.def (libgrubmods): Add bfs.c. + * grub-core/Makefile.core.def (bfs): New module. + 2011-10-30 Vladimir Serbinenko * util/grub-fstest.c (cmd_cp): Clarify error message. diff --git a/Makefile.util.def b/Makefile.util.def index bc66a51d4..053ff4340 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -55,6 +55,7 @@ library = { common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; common = grub-core/fs/affs.c; + common = grub-core/fs/bfs.c; common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; common = grub-core/fs/ext2.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2d91c3b64..c6127b28f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -970,6 +970,11 @@ module = { common = fs/affs.c; }; +module = { + name = bfs; + common = fs/bfs.c; +}; + module = { name = btrfs; common = fs/btrfs.c; diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c new file mode 100644 index 000000000..6f6ebf908 --- /dev/null +++ b/grub-core/fs/bfs.c @@ -0,0 +1,948 @@ +/* bfs.c - The Bee File System. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,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 . + */ +/* + Based on the book "Practical File System Design by Dominic Giampaolo + with corrections and completitions based on Haiku code. +*/ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define grub_bfs_to_cpu16 grub_le_to_cpu16 +#define grub_bfs_to_cpu32 grub_le_to_cpu32 +#define grub_bfs_to_cpu64 grub_le_to_cpu64 + +#define SUPER_BLOCK_MAGIC1 0x42465331 +#define SUPER_BLOCK_MAGIC2 0xdd121031 +#define SUPER_BLOCK_MAGIC3 0x15b6830e +#define POINTER_INVALID 0xffffffffffffffffULL + +#define ATTR_TYPE 0160000 +#define ATTR_REG 0100000 +#define ATTR_DIR 0040000 +#define ATTR_LNK 0120000 + +#define DOUBLE_INDIRECT_SHIFT 2 + +#define LOG_EXTENT_SIZE 3 +struct grub_bfs_extent +{ + grub_uint32_t ag; + grub_uint16_t start; + grub_uint16_t len; +} __attribute__ ((packed)); + +struct grub_bfs_superblock +{ + char label[32]; + grub_uint32_t magic1; + grub_uint32_t unused1; + grub_uint32_t bsize; + grub_uint32_t log2_bsize; + grub_uint8_t unused[20]; + grub_uint32_t magic2; + grub_uint32_t unused2; + grub_uint32_t log2_ag_size; + grub_uint8_t unused3[32]; + grub_uint32_t magic3; + struct grub_bfs_extent root_dir; +} __attribute__ ((packed)); + +struct grub_bfs_inode +{ + grub_uint8_t unused[20]; + grub_uint32_t mode; + grub_uint32_t flags; + grub_uint8_t unused2[8]; + grub_uint64_t mtime; + grub_uint8_t unused3[8]; + struct grub_bfs_extent attr; + grub_uint8_t unused4[12]; + + union + { + struct + { + struct grub_bfs_extent direct[12]; + grub_uint64_t max_direct_range; + struct grub_bfs_extent indirect; + grub_uint64_t max_indirect_range; + struct grub_bfs_extent double_indirect; + grub_uint64_t max_double_indirect_range; + grub_uint64_t size; + grub_uint32_t pad[4]; + } __attribute__ ((packed)); + char inplace_link[144]; + } __attribute__ ((packed)); + grub_uint8_t small_data[0]; +} __attribute__ ((packed)); + +enum +{ + LONG_SYMLINK = 0x40 +}; + +struct grub_bfs_small_data_element_header +{ + grub_uint32_t type; + grub_uint16_t name_len; + grub_uint16_t value_len; +} __attribute__ ((packed)); + +struct grub_bfs_btree_header +{ + grub_uint32_t magic; + grub_uint32_t node_size; + grub_uint32_t level; + grub_uint32_t unused; + grub_uint64_t root; + grub_uint32_t unused2[2]; +} __attribute__ ((packed)); + +struct grub_bfs_btree_node +{ + grub_uint64_t unused; + grub_uint64_t right; + grub_uint64_t overflow; + grub_uint16_t count_keys; + grub_uint16_t total_key_len; +} __attribute__ ((packed)); + +struct grub_bfs_data +{ + struct grub_bfs_superblock sb; + struct grub_bfs_inode ino[0]; +}; + +static grub_err_t +read_extent (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_extent *in, + grub_off_t off, + grub_off_t byteoff, + void *buf, grub_size_t len) +{ + return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) + << grub_bfs_to_cpu32 (sb->log2_ag_size)) + + grub_bfs_to_cpu16 (in->start) + off) + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) + , byteoff, + len, buf); +} + +static grub_err_t +read_bfs_file (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + grub_off_t off, void *buf, grub_size_t len, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length)) +{ + if (len == 0) + return GRUB_ERR_NONE; + + if (off + len > grub_bfs_to_cpu64 (ino->size)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to read past the end of file"); + + if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + { + unsigned i; + grub_uint64_t pos = 0; + for (i = 0; i < ARRAY_SIZE (ino->direct); i++) + { + grub_uint64_t newpos; + newpos = pos + (grub_bfs_to_cpu16 (ino->direct[i].len) + << grub_bfs_to_cpu32 (sb->log2_bsize)); + if (newpos > off) + { + grub_size_t read_size; + grub_err_t err; + read_size = newpos - off; + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; + err = read_extent (disk, sb, &ino->direct[i], 0, off - pos, + buf, read_size); + disk->read_hook = 0; + if (err) + return err; + off += read_size; + len -= read_size; + buf = (char *) buf + read_size; + if (len == 0) + return GRUB_ERR_NONE; + } + pos = newpos; + } + } + + if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + return grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); + + if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + { + unsigned i; + struct grub_bfs_extent *entries; + grub_size_t nentries; + grub_err_t err; + grub_uint64_t pos = grub_bfs_to_cpu64 (ino->max_direct_range); + nentries = (grub_bfs_to_cpu16 (ino->indirect.len) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE)); + entries = grub_malloc (nentries << LOG_EXTENT_SIZE); + if (!entries) + return grub_errno; + err = read_extent (disk, sb, &ino->indirect, 0, 0, + entries, nentries << LOG_EXTENT_SIZE); + for (i = 0; i < nentries; i++) + { + grub_uint64_t newpos; + newpos = pos + (grub_bfs_to_cpu16 (entries[i].len) + << grub_bfs_to_cpu32 (sb->log2_bsize)); + if (newpos > off) + { + grub_size_t read_size; + read_size = newpos - off; + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; + err = read_extent (disk, sb, &entries[i], 0, off - pos, + buf, read_size); + disk->read_hook = 0; + if (err) + { + grub_free (entries); + return err; + } + off += read_size; + len -= read_size; + buf = (char *) buf + read_size; + if (len == 0) + { + grub_free (entries); + return GRUB_ERR_NONE; + } + } + pos = newpos; + } + grub_free (entries); + } + + if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + return grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); + + { + struct grub_bfs_extent *l1_entries, *l2_entries; + grub_size_t nl1_entries, nl2_entries; + grub_off_t last_l1n = ~0ULL; + grub_err_t err; + nl1_entries = (grub_bfs_to_cpu16 (ino->double_indirect.len) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE)); + l1_entries = grub_malloc (nl1_entries << LOG_EXTENT_SIZE); + if (!l1_entries) + return grub_errno; + nl2_entries = 0; + l2_entries = grub_malloc (1 << (DOUBLE_INDIRECT_SHIFT + + grub_bfs_to_cpu32 (sb->log2_bsize))); + if (!l2_entries) + { + grub_free (l1_entries); + return grub_errno; + } + err = read_extent (disk, sb, &ino->double_indirect, 0, 0, + l1_entries, nl1_entries << LOG_EXTENT_SIZE); + if (err) + { + grub_free (l1_entries); + grub_free (l2_entries); + return err; + } + + while (len > 0) + { + grub_off_t boff, l2n, l1n; + grub_size_t read_size; + grub_off_t double_indirect_offset; + double_indirect_offset = off + - grub_bfs_to_cpu64 (ino->max_indirect_range); + boff = (double_indirect_offset + & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + + DOUBLE_INDIRECT_SHIFT)) - 1)); + l2n = ((double_indirect_offset >> (grub_bfs_to_cpu32 (sb->log2_bsize) + + DOUBLE_INDIRECT_SHIFT)) + & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE + + DOUBLE_INDIRECT_SHIFT)) + - 1)); + l1n = (double_indirect_offset >> (2 * grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE + + 2 * DOUBLE_INDIRECT_SHIFT)); + if (l1n > nl1_entries) + { + grub_free (l1_entries); + grub_free (l2_entries); + return grub_error (GRUB_ERR_BAD_FS, + "incorrect double-indirect block"); + } + if (l1n != last_l1n) + { + nl2_entries = (grub_bfs_to_cpu16 (l1_entries[l1n].len) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE)); + if (nl2_entries > (1U << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE + + DOUBLE_INDIRECT_SHIFT))) + nl2_entries = (1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + - LOG_EXTENT_SIZE + + DOUBLE_INDIRECT_SHIFT)); + err = read_extent (disk, sb, &l1_entries[l1n], 0, 0, + l2_entries, nl2_entries << LOG_EXTENT_SIZE); + if (err) + { + grub_free (l1_entries); + grub_free (l2_entries); + return err; + } + last_l1n = l1n; + } + if (l2n > nl2_entries) + { + grub_free (l1_entries); + grub_free (l2_entries); + return grub_error (GRUB_ERR_BAD_FS, + "incorrect double-indirect block"); + } + + read_size = (1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + + DOUBLE_INDIRECT_SHIFT)) - boff; + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; + err = read_extent (disk, sb, &l2_entries[l2n], 0, boff, + buf, read_size); + disk->read_hook = 0; + if (err) + { + grub_free (l1_entries); + grub_free (l2_entries); + return err; + } + off += read_size; + len -= read_size; + buf = (char *) buf + read_size; + } + return GRUB_ERR_NONE; + } +} + +static int +iterate_in_b_tree (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + int (*hook) (const char *name, grub_uint64_t value)) +{ + struct grub_bfs_btree_header head; + grub_err_t err; + int level; + grub_uint64_t node_off; + + err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); + if (err) + return 0; + node_off = grub_bfs_to_cpu64 (head.root); + + level = grub_bfs_to_cpu32 (head.level) - 1; + while (level--) + { + struct grub_bfs_btree_node node; + grub_uint64_t key_value; + err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); + if (err) + return 0; + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + &key_value, sizeof (grub_uint64_t), 0); + if (err) + return 0; + + node_off = grub_bfs_to_cpu64 (key_value); + } + + while (1) + { + struct grub_bfs_btree_node node; + err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); + if (err) + return 0; + { + char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + unsigned i; + grub_uint16_t start = 0, end = 0; + + err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); + if (err) + return 0; + key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8), + keylen_idx, grub_bfs_to_cpu16 (node.count_keys) + * 2, 0); + if (err) + return 0; + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, grub_bfs_to_cpu16 (node.count_keys) + * 8, 0); + if (err) + return 0; + + for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + { + char c; + start = end; + end = grub_bfs_to_cpu16 (keylen_idx[i]); + c = key_data[end]; + key_data[end] = 0; + if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) + return 1; + key_data[end] = c; + } + node_off = grub_bfs_to_cpu64 (node.right); + if (node_off == POINTER_INVALID) + return 0; + } + } +} + +static grub_err_t +find_in_b_tree (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, const char *name, + grub_uint64_t *res) +{ + struct grub_bfs_btree_header head; + grub_err_t err; + int level; + grub_uint64_t node_off; + + err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); + if (err) + return err; + node_off = grub_bfs_to_cpu64 (head.root); + + level = grub_bfs_to_cpu32 (head.level) - 1; + while (1) + { + struct grub_bfs_btree_node node; + err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); + if (err) + return err; + if (node.count_keys == 0) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", + name); + { + char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + unsigned i; + grub_uint16_t start = 0, end = 0; + err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); + if (err) + return err; + key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + err = read_bfs_file (disk, sb, ino, node_off + + + ALIGN_UP (sizeof (node) +grub_bfs_to_cpu16 (node.total_key_len), + 8), + keylen_idx, grub_bfs_to_cpu16 (node.count_keys) + * 2, 0); + if (err) + return err; + err = read_bfs_file (disk, sb, ino, node_off + + + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, grub_bfs_to_cpu16 (node.count_keys) + * 8, 0); + if (err) + return err; + + for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + { + int cmp; + char c; + start = end; + end = grub_bfs_to_cpu16 (keylen_idx[i]); + if (grub_bfs_to_cpu16 (node.total_key_len) <= end) + end = grub_bfs_to_cpu16 (node.total_key_len); + c = key_data[end]; + key_data[end] = 0; + cmp = grub_strcmp (key_data + start, name); + key_data[end] = c; + if (cmp == 0 && level == 0) + { + *res = grub_bfs_to_cpu64 (key_values[i]); + return GRUB_ERR_NONE; + } + if (cmp >= 0 && level != 0) + { + node_off = grub_bfs_to_cpu64 (key_values[i]); + break; + } + } + if (i < grub_bfs_to_cpu16 (node.count_keys)) + { + level--; + continue; + } + if (node.overflow != POINTER_INVALID) + { + node_off = grub_bfs_to_cpu64 (node.overflow); + /* This level-- isn't specified but is needed. */ + level--; + continue; + } + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", + name); + } + } +} + +static grub_err_t +hop_level (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + struct grub_bfs_inode *ino, + const char *name) +{ + grub_err_t err; + grub_uint64_t res; + + if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) != ATTR_DIR)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + err = find_in_b_tree (disk, sb, ino, name, &res); + if (err) + return err; + + return grub_disk_read (disk, res + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + grub_bfs_to_cpu32 (sb->bsize), (char *) ino); +} + +static grub_err_t +find_file (const char *path, grub_disk_t disk, + const struct grub_bfs_superblock *sb, + struct grub_bfs_inode *ino) +{ + char *ptr, *ptr2; + char *alloc = NULL; + grub_err_t err; + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; + } old_ino; + unsigned symlinks_max = 32; + + err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + return err; + + ptr = (char *) path; + while (1) + { + while (*ptr == '/') + ptr++; + if (*ptr == 0) + { + grub_free (alloc); + return GRUB_ERR_NONE; + } + ptr2 = grub_strchr (ptr, '/'); + grub_memcpy (&old_ino, ino, grub_bfs_to_cpu32 (sb->bsize)); + if (ptr2) + { + char component[ptr2 - ptr + 1]; + grub_memcpy (component, ptr, ptr2 - ptr); + component[ptr2 - ptr] = 0; + err = hop_level (disk, sb, ino, component); + } + else + err = hop_level (disk, sb, ino, ptr); + if (err) + return err; + + if (((grub_bfs_to_cpu32 (ino->mode) & ATTR_TYPE) == ATTR_LNK)) + { + char *old_alloc = alloc; + if (--symlinks_max == 0) + { + grub_free (alloc); + return grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + } + + if (grub_bfs_to_cpu32 (ino->flags) & LONG_SYMLINK) + { + grub_size_t symsize = grub_bfs_to_cpu64 (ino->size); + alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + + + symsize + 1); + if (!alloc) + { + grub_free (alloc); + return grub_errno; + } + grub_free (old_alloc); + err = read_bfs_file (disk, sb, ino, + 0, alloc, symsize, 0); + if (err) + { + grub_free (alloc); + return err; + } + alloc[symsize] = 0; + } + else + { + alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + + sizeof (ino->inplace_link) + 1); + if (!alloc) + { + grub_free (alloc); + return grub_errno; + } + grub_free (old_alloc); + grub_memcpy (alloc, ino->inplace_link, + sizeof (ino->inplace_link)); + alloc[sizeof (ino->inplace_link)] = 0; + } + if (alloc[0] == '/') + { + err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + { + grub_free (alloc); + return err; + } + } + else + grub_memcpy (ino, &old_ino, grub_bfs_to_cpu32 (sb->bsize)); + ptr = alloc + grub_strlen (alloc); + if (ptr2) + ptr = grub_stpcpy (ptr, ptr2); + *ptr = 0; + ptr = ptr2 = alloc; + continue; + } + + if (!ptr2) + { + grub_free (alloc); + return GRUB_ERR_NONE; + } + ptr = ptr2 + 1; + } +} + +static grub_err_t +mount (grub_disk_t disk, struct grub_bfs_superblock *sb) +{ + grub_err_t err; + err = grub_disk_read (disk, 1, 0, + sizeof (*sb), sb); + if (err == GRUB_ERR_OUT_OF_RANGE) + return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + if (err) + return err; + if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 + || grub_bfs_to_cpu32 (sb->magic2) != SUPER_BLOCK_MAGIC2 + || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 + || (grub_bfs_to_cpu32 (sb->bsize) + != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) + return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bfs_dir (grub_device_t device, const char *path, + int (*hook_in) (const char *filename, + const struct grub_dirhook_info *info)) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + auto int hook (const char *name, grub_uint64_t value); + + int hook (const char *name, grub_uint64_t value) + { + grub_err_t err2; + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + struct grub_dirhook_info info; + + err2 = grub_disk_read (device->disk, value + << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9) + , 0, + grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); + if (err2) + { + grub_print_error (); + return 0; + } + + info.mtimeset = 1; + info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; + info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR); + return hook_in (name, &info); + } + err = mount (device->disk, &sb); + if (err) + return err; + + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + err = find_file (path, device->disk, &sb, &ino.ino); + if (err) + return err; + if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_DIR)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + iterate_in_b_tree (device->disk, &sb, &ino.ino, hook); + } + + return grub_errno; +} + +static grub_err_t +grub_bfs_open (struct grub_file *file, const char *name) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + + err = mount (file->device->disk, &sb); + if (err) + return err; + + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + struct grub_bfs_data *data; + err = find_file (name, file->device->disk, &sb, &ino.ino); + if (err) + return err; + if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_REG)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + data = grub_zalloc (sizeof (struct grub_bfs_data) + + grub_bfs_to_cpu32 (sb.bsize)); + if (!data) + return grub_errno; + data->sb = sb; + grub_memcpy (&data->ino, &ino, grub_bfs_to_cpu32 (sb.bsize)); + file->data = data; + file->size = grub_bfs_to_cpu64 (ino.ino.size); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bfs_close (grub_file_t file) +{ + grub_free (file->data); + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_bfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_err_t err; + struct grub_bfs_data *data = file->data; + + err = read_bfs_file (file->device->disk, &data->sb, + data->ino, + file->offset, buf, len, file->read_hook); + if (err) + return -1; + return len; +} + +static grub_err_t +grub_bfs_label (grub_device_t device, char **label) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + + *label = 0; + + err = mount (device->disk, &sb); + if (err) + return err; + + *label = grub_strndup (sb.label, sizeof (sb.label)); + return GRUB_ERR_NONE; +} + +static grub_ssize_t +read_bfs_attr (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + const char *name, + void *buf, grub_size_t len) +{ + grub_uint8_t *ptr = (grub_uint8_t *) ino->small_data; + grub_uint8_t *end = ((grub_uint8_t *) ino + + grub_bfs_to_cpu32 (sb->bsize)); + + while (ptr + sizeof (struct grub_bfs_small_data_element_header) < end) + { + struct grub_bfs_small_data_element_header *el; + char *el_name; + grub_uint8_t *data; + el = (struct grub_bfs_small_data_element_header *) ptr; + if (el->name_len == 0) + break; + el_name = (char *) (el + 1); + data = (grub_uint8_t *) el_name + grub_bfs_to_cpu16 (el->name_len) + 3; + ptr = data + grub_bfs_to_cpu16 (el->value_len) + 1; + if (grub_memcmp (name, el_name, grub_bfs_to_cpu16 (el->name_len)) == 0 + && name[el->name_len] == 0) + { + grub_size_t copy; + copy = len; + if (grub_bfs_to_cpu16 (el->value_len) > copy) + copy = grub_bfs_to_cpu16 (el->value_len); + grub_memcpy (buf, data, copy); + return copy; + } + } + + if (ino->attr.len != 0) + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; + } ino2; + grub_size_t read; + grub_err_t err; + grub_uint64_t res; + + err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + return -1; + + err = find_in_b_tree (disk, sb, &ino2.ino, name, &res); + if (err) + return -1; + grub_disk_read (disk, res + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) + , 0, + grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); + read = grub_bfs_to_cpu64 (ino2.ino.size); + if (read > len) + read = len; + + err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); + if (err) + return -1; + return read; + } + return -1; +} + +static grub_err_t +grub_bfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_bfs_superblock sb; + grub_err_t err; + + *uuid = 0; + + err = mount (device->disk, &sb); + if (err) + return err; + + { + union { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; + } ino; + grub_uint64_t vid; + + err = read_extent (device->disk, &sb, &sb.root_dir, 0, 0, + &ino, grub_bfs_to_cpu32 (sb.bsize)); + if (err) + return err; + if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id", + &vid, 8) == 8) + *uuid = grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); + } + return GRUB_ERR_NONE; +} + + +static struct grub_fs grub_bfs_fs = { + .name = "bfs", + .dir = grub_bfs_dir, + .open = grub_bfs_open, + .read = grub_bfs_read, + .close = grub_bfs_close, + .label = grub_bfs_label, + .uuid = grub_bfs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif +}; + +GRUB_MOD_INIT (bfs) +{ + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); + grub_fs_register (&grub_bfs_fs); +} + +GRUB_MOD_FINI (bfs) +{ + grub_fs_unregister (&grub_bfs_fs); +} From c4a1628f6765a330f7d1afc40cefc139512b9e6c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 13:27:53 +0100 Subject: [PATCH 1308/1414] * grub-core/fs/bfs.c: Run indent. --- ChangeLog | 4 + grub-core/fs/bfs.c | 220 +++++++++++++++++++++++---------------------- 2 files changed, 115 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8ea7974c..c52bff5b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-30 Vladimir Serbinenko + + * grub-core/fs/bfs.c: Run indent. + 2011-10-30 Vladimir Serbinenko BFS implementation based on the specification. diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index 6f6ebf908..7b6e359ae 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -141,15 +141,12 @@ static grub_err_t read_extent (grub_disk_t disk, const struct grub_bfs_superblock *sb, const struct grub_bfs_extent *in, - grub_off_t off, - grub_off_t byteoff, - void *buf, grub_size_t len) + grub_off_t off, grub_off_t byteoff, void *buf, grub_size_t len) { return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) << grub_bfs_to_cpu32 (sb->log2_ag_size)) + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) - , byteoff, + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), byteoff, len, buf); } @@ -159,13 +156,15 @@ read_bfs_file (grub_disk_t disk, const struct grub_bfs_inode *ino, grub_off_t off, void *buf, grub_size_t len, void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length)) + unsigned offset, + unsigned length)) { if (len == 0) return GRUB_ERR_NONE; if (off + len > grub_bfs_to_cpu64 (ino->size)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to read past the end of file"); + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "attempt to read past the end of file"); if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) { @@ -210,11 +209,10 @@ read_bfs_file (grub_disk_t disk, grub_err_t err; grub_uint64_t pos = grub_bfs_to_cpu64 (ino->max_direct_range); nentries = (grub_bfs_to_cpu16 (ino->indirect.len) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE)); + << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); entries = grub_malloc (nentries << LOG_EXTENT_SIZE); if (!entries) - return grub_errno; + return grub_errno; err = read_extent (disk, sb, &ino->indirect, 0, 0, entries, nentries << LOG_EXTENT_SIZE); for (i = 0; i < nentries; i++) @@ -260,8 +258,7 @@ read_bfs_file (grub_disk_t disk, grub_off_t last_l1n = ~0ULL; grub_err_t err; nl1_entries = (grub_bfs_to_cpu16 (ino->double_indirect.len) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE)); + << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); l1_entries = grub_malloc (nl1_entries << LOG_EXTENT_SIZE); if (!l1_entries) return grub_errno; @@ -271,7 +268,7 @@ read_bfs_file (grub_disk_t disk, if (!l2_entries) { grub_free (l1_entries); - return grub_errno; + return grub_errno; } err = read_extent (disk, sb, &ino->double_indirect, 0, 0, l1_entries, nl1_entries << LOG_EXTENT_SIZE); @@ -289,17 +286,17 @@ read_bfs_file (grub_disk_t disk, grub_off_t double_indirect_offset; double_indirect_offset = off - grub_bfs_to_cpu64 (ino->max_indirect_range); - boff = (double_indirect_offset + boff = (double_indirect_offset & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) + DOUBLE_INDIRECT_SHIFT)) - 1)); l2n = ((double_indirect_offset >> (grub_bfs_to_cpu32 (sb->log2_bsize) + DOUBLE_INDIRECT_SHIFT)) & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE - + DOUBLE_INDIRECT_SHIFT)) - - 1)); - l1n = (double_indirect_offset >> (2 * grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE - + 2 * DOUBLE_INDIRECT_SHIFT)); + + DOUBLE_INDIRECT_SHIFT)) - 1)); + l1n = + (double_indirect_offset >> + (2 * grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE + + 2 * DOUBLE_INDIRECT_SHIFT)); if (l1n > nl1_entries) { grub_free (l1_entries); @@ -383,9 +380,10 @@ iterate_in_b_tree (grub_disk_t disk, if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8) - + grub_bfs_to_cpu16 (node.count_keys) * 2, + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node.total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, &key_value, sizeof (grub_uint64_t), 0); if (err) return 0; @@ -395,7 +393,7 @@ iterate_in_b_tree (grub_disk_t disk, while (1) { - struct grub_bfs_btree_node node; + struct grub_bfs_btree_node node; err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); if (err) return 0; @@ -406,24 +404,28 @@ iterate_in_b_tree (grub_disk_t disk, unsigned i; grub_uint16_t start = 0, end = 0; - err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + err = + read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); if (err) return 0; key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; - err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8), - keylen_idx, grub_bfs_to_cpu16 (node.count_keys) - * 2, 0); + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node. + total_key_len), + 8), keylen_idx, + grub_bfs_to_cpu16 (node.count_keys) * 2, 0); if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8) - + grub_bfs_to_cpu16 (node.count_keys) * 2, - key_values, grub_bfs_to_cpu16 (node.count_keys) - * 8, 0); + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node. + total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, + grub_bfs_to_cpu16 (node.count_keys) * 8, 0); if (err) return 0; @@ -449,7 +451,7 @@ static grub_err_t find_in_b_tree (grub_disk_t disk, const struct grub_bfs_superblock *sb, const struct grub_bfs_inode *ino, const char *name, - grub_uint64_t *res) + grub_uint64_t * res) { struct grub_bfs_btree_header head; grub_err_t err; @@ -464,7 +466,7 @@ find_in_b_tree (grub_disk_t disk, level = grub_bfs_to_cpu32 (head.level) - 1; while (1) { - struct grub_bfs_btree_node node; + struct grub_bfs_btree_node node; err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); if (err) return err; @@ -477,26 +479,28 @@ find_in_b_tree (grub_disk_t disk, grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; unsigned i; grub_uint16_t start = 0, end = 0; - err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + err = + read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, + grub_bfs_to_cpu16 (node.total_key_len), 0); if (err) return err; key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; - err = read_bfs_file (disk, sb, ino, node_off - + - ALIGN_UP (sizeof (node) +grub_bfs_to_cpu16 (node.total_key_len), - 8), - keylen_idx, grub_bfs_to_cpu16 (node.count_keys) - * 2, 0); + err = read_bfs_file (disk, sb, ino, node_off + + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node.total_key_len), + 8), keylen_idx, + grub_bfs_to_cpu16 (node.count_keys) * 2, 0); if (err) return err; - err = read_bfs_file (disk, sb, ino, node_off - - + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), - 8) - + grub_bfs_to_cpu16 (node.count_keys) * 2, - key_values, grub_bfs_to_cpu16 (node.count_keys) - * 8, 0); + err = read_bfs_file (disk, sb, ino, node_off + + ALIGN_UP (sizeof (node) + + grub_bfs_to_cpu16 (node. + total_key_len), + 8) + + grub_bfs_to_cpu16 (node.count_keys) * 2, + key_values, + grub_bfs_to_cpu16 (node.count_keys) * 8, 0); if (err) return err; @@ -544,8 +548,7 @@ find_in_b_tree (grub_disk_t disk, static grub_err_t hop_level (grub_disk_t disk, const struct grub_bfs_superblock *sb, - struct grub_bfs_inode *ino, - const char *name) + struct grub_bfs_inode *ino, const char *name) { grub_err_t err; grub_uint64_t res; @@ -564,13 +567,13 @@ hop_level (grub_disk_t disk, static grub_err_t find_file (const char *path, grub_disk_t disk, - const struct grub_bfs_superblock *sb, - struct grub_bfs_inode *ino) + const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino) { char *ptr, *ptr2; char *alloc = NULL; grub_err_t err; - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; } old_ino; @@ -619,7 +622,6 @@ find_file (const char *path, grub_disk_t disk, { grub_size_t symsize = grub_bfs_to_cpu64 (ino->size); alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) - + symsize + 1); if (!alloc) { @@ -627,8 +629,7 @@ find_file (const char *path, grub_disk_t disk, return grub_errno; } grub_free (old_alloc); - err = read_bfs_file (disk, sb, ino, - 0, alloc, symsize, 0); + err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0); if (err) { grub_free (alloc); @@ -638,7 +639,7 @@ find_file (const char *path, grub_disk_t disk, } else { - alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) + sizeof (ino->inplace_link) + 1); if (!alloc) { @@ -653,7 +654,7 @@ find_file (const char *path, grub_disk_t disk, if (alloc[0] == '/') { err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, - grub_bfs_to_cpu32 (sb->bsize)); + grub_bfs_to_cpu32 (sb->bsize)); if (err) { grub_free (alloc); @@ -683,8 +684,7 @@ static grub_err_t mount (grub_disk_t disk, struct grub_bfs_superblock *sb) { grub_err_t err; - err = grub_disk_read (disk, 1, 0, - sizeof (*sb), sb); + err = grub_disk_read (disk, 1, 0, sizeof (*sb), sb); if (err == GRUB_ERR_OUT_OF_RANGE) return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); if (err) @@ -692,7 +692,7 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 || grub_bfs_to_cpu32 (sb->magic2) != SUPER_BLOCK_MAGIC2 || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 - || (grub_bfs_to_cpu32 (sb->bsize) + || (grub_bfs_to_cpu32 (sb->bsize) != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); return GRUB_ERR_NONE; @@ -701,7 +701,7 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) static grub_err_t grub_bfs_dir (grub_device_t device, const char *path, int (*hook_in) (const char *filename, - const struct grub_dirhook_info *info)) + const struct grub_dirhook_info * info)) { struct grub_bfs_superblock sb; grub_err_t err; @@ -710,21 +710,21 @@ grub_bfs_dir (grub_device_t device, const char *path, int hook (const char *name, grub_uint64_t value) { grub_err_t err2; - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; struct grub_dirhook_info info; err2 = grub_disk_read (device->disk, value - << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9) - , 0, + << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9), 0, grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); if (err2) { grub_print_error (); return 0; - } + } info.mtimeset = 1; info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; @@ -736,7 +736,8 @@ grub_bfs_dir (grub_device_t device, const char *path, return err; { - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; @@ -762,7 +763,8 @@ grub_bfs_open (struct grub_file *file, const char *name) return err; { - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; @@ -799,10 +801,9 @@ grub_bfs_read (grub_file_t file, char *buf, grub_size_t len) { grub_err_t err; struct grub_bfs_data *data = file->data; - + err = read_bfs_file (file->device->disk, &data->sb, - data->ino, - file->offset, buf, len, file->read_hook); + data->ino, file->offset, buf, len, file->read_hook); if (err) return -1; return len; @@ -828,12 +829,10 @@ static grub_ssize_t read_bfs_attr (grub_disk_t disk, const struct grub_bfs_superblock *sb, const struct grub_bfs_inode *ino, - const char *name, - void *buf, grub_size_t len) + const char *name, void *buf, grub_size_t len) { grub_uint8_t *ptr = (grub_uint8_t *) ino->small_data; - grub_uint8_t *end = ((grub_uint8_t *) ino - + grub_bfs_to_cpu32 (sb->bsize)); + grub_uint8_t *end = ((grub_uint8_t *) ino + grub_bfs_to_cpu32 (sb->bsize)); while (ptr + sizeof (struct grub_bfs_small_data_element_header) < end) { @@ -859,36 +858,36 @@ read_bfs_attr (grub_disk_t disk, } if (ino->attr.len != 0) - { - union { - struct grub_bfs_inode ino; - grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; - } ino2; - grub_size_t read; - grub_err_t err; - grub_uint64_t res; + { + union + { + struct grub_bfs_inode ino; + grub_uint8_t raw[grub_bfs_to_cpu32 (sb->bsize)]; + } ino2; + grub_size_t read; + grub_err_t err; + grub_uint64_t res; - err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw, - grub_bfs_to_cpu32 (sb->bsize)); - if (err) - return -1; + err = read_extent (disk, sb, &ino->attr, 0, 0, ino2.raw, + grub_bfs_to_cpu32 (sb->bsize)); + if (err) + return -1; - err = find_in_b_tree (disk, sb, &ino2.ino, name, &res); - if (err) - return -1; - grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9) - , 0, - grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); - read = grub_bfs_to_cpu64 (ino2.ino.size); - if (read > len) - read = len; + err = find_in_b_tree (disk, sb, &ino2.ino, name, &res); + if (err) + return -1; + grub_disk_read (disk, res + << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); + read = grub_bfs_to_cpu64 (ino2.ino.size); + if (read > len) + read = len; - err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); - if (err) - return -1; - return read; - } + err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); + if (err) + return -1; + return read; + } return -1; } @@ -905,7 +904,8 @@ grub_bfs_uuid (grub_device_t device, char **uuid) return err; { - union { + union + { struct grub_bfs_inode ino; grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; } ino; @@ -917,7 +917,8 @@ grub_bfs_uuid (grub_device_t device, char **uuid) return err; if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id", &vid, 8) == 8) - *uuid = grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); + *uuid = + grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); } return GRUB_ERR_NONE; } @@ -938,7 +939,8 @@ static struct grub_fs grub_bfs_fs = { GRUB_MOD_INIT (bfs) { - COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == + sizeof (struct grub_bfs_extent)); grub_fs_register (&grub_bfs_fs); } From 785ab8c76053d18a1b80046d599e0ed7f8680f00 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 14:17:44 +0100 Subject: [PATCH 1309/1414] * grub-core/fs/bfs.c: MAcroify and add some necessary sanity checks. --- ChangeLog | 4 ++++ grub-core/fs/bfs.c | 37 +++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index c52bff5b9..8ff87aebd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-30 Vladimir Serbinenko + + * grub-core/fs/bfs.c: MAcroify and add some necessary sanity checks. + 2011-10-30 Vladimir Serbinenko * grub-core/fs/bfs.c: Run indent. diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index 7b6e359ae..c16a50f39 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -146,7 +146,8 @@ read_extent (grub_disk_t disk, return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) << grub_bfs_to_cpu32 (sb->log2_ag_size)) + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), byteoff, + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS), byteoff, len, buf); } @@ -383,7 +384,8 @@ iterate_in_b_tree (grub_disk_t disk, + ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), 8) + - grub_bfs_to_cpu16 (node.count_keys) * 2, + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint64_t), &key_value, sizeof (grub_uint64_t), 0); if (err) return 0; @@ -415,7 +417,8 @@ iterate_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node. total_key_len), 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) * 2, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), 0); if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off @@ -423,9 +426,11 @@ iterate_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node. total_key_len), 8) + - grub_bfs_to_cpu16 (node.count_keys) * 2, + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), key_values, - grub_bfs_to_cpu16 (node.count_keys) * 8, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint64_t), 0); if (err) return 0; @@ -434,6 +439,8 @@ iterate_in_b_tree (grub_disk_t disk, char c; start = end; end = grub_bfs_to_cpu16 (keylen_idx[i]); + if (grub_bfs_to_cpu16 (node.total_key_len) <= end) + end = grub_bfs_to_cpu16 (node.total_key_len); c = key_data[end]; key_data[end] = 0; if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) @@ -490,7 +497,8 @@ find_in_b_tree (grub_disk_t disk, ALIGN_UP (sizeof (node) + grub_bfs_to_cpu16 (node.total_key_len), 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) * 2, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), 0); if (err) return err; err = read_bfs_file (disk, sb, ino, node_off @@ -498,9 +506,11 @@ find_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node. total_key_len), 8) + - grub_bfs_to_cpu16 (node.count_keys) * 2, + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint16_t), key_values, - grub_bfs_to_cpu16 (node.count_keys) * 8, 0); + grub_bfs_to_cpu16 (node.count_keys) + * sizeof (grub_uint64_t), 0); if (err) return err; @@ -561,7 +571,8 @@ hop_level (grub_disk_t disk, return err; return grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS), 0, grub_bfs_to_cpu32 (sb->bsize), (char *) ino); } @@ -718,7 +729,8 @@ grub_bfs_dir (grub_device_t device, const char *path, struct grub_dirhook_info info; err2 = grub_disk_read (device->disk, value - << (grub_bfs_to_cpu32 (sb.log2_bsize) - 9), 0, + << (grub_bfs_to_cpu32 (sb.log2_bsize) + - GRUB_DISK_SECTOR_BITS), 0, grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); if (err2) { @@ -877,7 +889,8 @@ read_bfs_attr (grub_disk_t disk, if (err) return -1; grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - 9), 0, + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS), 0, grub_bfs_to_cpu32 (sb->bsize), (char *) &ino2); read = grub_bfs_to_cpu64 (ino2.ino.size); if (read > len) @@ -916,7 +929,7 @@ grub_bfs_uuid (grub_device_t device, char **uuid) if (err) return err; if (read_bfs_attr (device->disk, &sb, &ino.ino, "be:volume_id", - &vid, 8) == 8) + &vid, sizeof (vid)) == sizeof (vid)) *uuid = grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); } From 80f9f81424d72bea0588b48c428bb8d39a276f33 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 14:25:53 +0100 Subject: [PATCH 1310/1414] Fix a mistake in previous commit --- grub-core/fs/bfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index c16a50f39..a92f3522c 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -385,7 +385,7 @@ iterate_in_b_tree (grub_disk_t disk, grub_bfs_to_cpu16 (node.total_key_len), 8) + grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint64_t), + * sizeof (grub_uint16_t), &key_value, sizeof (grub_uint64_t), 0); if (err) return 0; From eb0b6b45f380ca4831358aa14aa25391f2d9800f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 16:10:18 +0100 Subject: [PATCH 1311/1414] Leverage BFS implementation to read AFS. * Makefile.util.def (libgrubmods): Add afs.c. * grub-core/Makefile.core.def (afs): New module * grub-core/fs/afs.c: New file. * grub-core/fs/bfs.c [MODE_AFS]: Adapt for AFS. --- ChangeLog | 11 +- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/afs.c | 3 + grub-core/fs/bfs.c | 211 +++++++++++++++++++++++++----------- 5 files changed, 168 insertions(+), 63 deletions(-) create mode 100644 grub-core/fs/afs.c diff --git a/ChangeLog b/ChangeLog index 8ff87aebd..8f44f2080 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,15 @@ 2011-10-30 Vladimir Serbinenko - * grub-core/fs/bfs.c: MAcroify and add some necessary sanity checks. + Leverage BFS implementation to read AFS. + + * Makefile.util.def (libgrubmods): Add afs.c. + * grub-core/Makefile.core.def (afs): New module + * grub-core/fs/afs.c: New file. + * grub-core/fs/bfs.c [MODE_AFS]: Adapt for AFS. + +2011-10-30 Vladimir Serbinenko + + * grub-core/fs/bfs.c: Macroify and add some necessary sanity checks. 2011-10-30 Vladimir Serbinenko diff --git a/Makefile.util.def b/Makefile.util.def index 053ff4340..a839920d5 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -55,6 +55,7 @@ library = { common = grub-core/disk/raid6_recover.c; common = grub-core/disk/raid.c; common = grub-core/fs/affs.c; + common = grub-core/fs/afs.c; common = grub-core/fs/bfs.c; common = grub-core/fs/btrfs.c; common = grub-core/fs/cpio.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c6127b28f..2b72d8429 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -970,6 +970,11 @@ module = { common = fs/affs.c; }; +module = { + name = afs; + common = fs/afs.c; +}; + module = { name = bfs; common = fs/bfs.c; diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c new file mode 100644 index 000000000..00a5e3113 --- /dev/null +++ b/grub-core/fs/afs.c @@ -0,0 +1,3 @@ +#define MODE_AFS 1 +#include "bfs.c" + diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index a92f3522c..fe8f991c4 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -31,11 +31,29 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#ifdef MODE_AFS +#define BTREE_ALIGN 4 +#define SUPERBLOCK 2 +#else +#define BTREE_ALIGN 8 +#define SUPERBLOCK 1 +#endif + #define grub_bfs_to_cpu16 grub_le_to_cpu16 #define grub_bfs_to_cpu32 grub_le_to_cpu32 #define grub_bfs_to_cpu64 grub_le_to_cpu64 +#ifdef MODE_AFS +#define grub_bfs_to_cpu_treehead grub_bfs_to_cpu32 +#else +#define grub_bfs_to_cpu_treehead grub_bfs_to_cpu16 +#endif + +#ifdef MODE_AFS +#define SUPER_BLOCK_MAGIC1 0x41465331 +#else #define SUPER_BLOCK_MAGIC1 0x42465331 +#endif #define SUPER_BLOCK_MAGIC2 0xdd121031 #define SUPER_BLOCK_MAGIC3 0x15b6830e #define POINTER_INVALID 0xffffffffffffffffULL @@ -76,7 +94,11 @@ struct grub_bfs_inode grub_uint8_t unused[20]; grub_uint32_t mode; grub_uint32_t flags; +#ifdef MODE_AFS + grub_uint8_t unused2[12]; +#else grub_uint8_t unused2[8]; +#endif grub_uint64_t mtime; grub_uint8_t unused3[8]; struct grub_bfs_extent attr; @@ -115,10 +137,17 @@ struct grub_bfs_small_data_element_header struct grub_bfs_btree_header { grub_uint32_t magic; +#ifdef MODE_AFS + grub_uint64_t root; + grub_uint32_t level; + grub_uint32_t node_size; + grub_uint32_t unused; +#else grub_uint32_t node_size; grub_uint32_t level; grub_uint32_t unused; grub_uint64_t root; +#endif grub_uint32_t unused2[2]; } __attribute__ ((packed)); @@ -127,8 +156,13 @@ struct grub_bfs_btree_node grub_uint64_t unused; grub_uint64_t right; grub_uint64_t overflow; +#ifdef MODE_AFS + grub_uint32_t count_keys; + grub_uint32_t total_key_len; +#else grub_uint16_t count_keys; grub_uint16_t total_key_len; +#endif } __attribute__ ((packed)); struct grub_bfs_data @@ -143,14 +177,30 @@ read_extent (grub_disk_t disk, const struct grub_bfs_extent *in, grub_off_t off, grub_off_t byteoff, void *buf, grub_size_t len) { +#ifdef MODE_AFS return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) - << grub_bfs_to_cpu32 (sb->log2_ag_size)) - + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - GRUB_DISK_SECTOR_BITS), byteoff, - len, buf); + << (grub_bfs_to_cpu32 (sb->log2_ag_size) + - GRUB_DISK_SECTOR_BITS)) + + ((grub_bfs_to_cpu16 (in->start) + off) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS))), + byteoff, len, buf); +#else + return grub_disk_read (disk, (((grub_bfs_to_cpu32 (in->ag) + << grub_bfs_to_cpu32 (sb->log2_ag_size)) + + grub_bfs_to_cpu16 (in->start) + off) + << (grub_bfs_to_cpu32 (sb->log2_bsize) + - GRUB_DISK_SECTOR_BITS)), + byteoff, len, buf); +#endif } +#ifdef MODE_AFS +#define RANGE_SHIFT grub_bfs_to_cpu32 (sb->log2_bsize) +#else +#define RANGE_SHIFT 0 +#endif + static grub_err_t read_bfs_file (grub_disk_t disk, const struct grub_bfs_superblock *sb, @@ -167,7 +217,7 @@ read_bfs_file (grub_disk_t disk, return grub_error (GRUB_ERR_OUT_OF_RANGE, "attempt to read past the end of file"); - if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_direct_range) << RANGE_SHIFT)) { unsigned i; grub_uint64_t pos = 0; @@ -199,16 +249,17 @@ read_bfs_file (grub_disk_t disk, } } - if (off < grub_bfs_to_cpu64 (ino->max_direct_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_direct_range) << RANGE_SHIFT)) return grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); - if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_indirect_range) << RANGE_SHIFT)) { unsigned i; struct grub_bfs_extent *entries; grub_size_t nentries; grub_err_t err; - grub_uint64_t pos = grub_bfs_to_cpu64 (ino->max_direct_range); + grub_uint64_t pos = (grub_bfs_to_cpu64 (ino->max_direct_range) + << RANGE_SHIFT); nentries = (grub_bfs_to_cpu16 (ino->indirect.len) << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); entries = grub_malloc (nentries << LOG_EXTENT_SIZE); @@ -250,7 +301,7 @@ read_bfs_file (grub_disk_t disk, grub_free (entries); } - if (off < grub_bfs_to_cpu64 (ino->max_indirect_range)) + if (off < (grub_bfs_to_cpu64 (ino->max_indirect_range) << RANGE_SHIFT)) return grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); { @@ -382,11 +433,12 @@ iterate_in_b_tree (grub_disk_t disk, return 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node.total_key_len), - 8) + - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), - &key_value, sizeof (grub_uint64_t), 0); + grub_bfs_to_cpu_treehead (node. + total_key_len), + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), &key_value, + sizeof (grub_uint64_t), 0); if (err) return 0; @@ -400,47 +452,46 @@ iterate_in_b_tree (grub_disk_t disk, if (err) return 0; { - char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; - grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; - grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + char key_data[grub_bfs_to_cpu_treehead (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu_treehead (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu_treehead (node.count_keys)]; unsigned i; grub_uint16_t start = 0, end = 0; err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + grub_bfs_to_cpu_treehead (node.total_key_len), 0); if (err) return 0; - key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node. - total_key_len), - 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), 0); + grub_bfs_to_cpu_treehead + (node.total_key_len), BTREE_ALIGN), + keylen_idx, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), 0); if (err) return 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node. - total_key_len), - 8) + - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), - key_values, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint64_t), 0); + grub_bfs_to_cpu_treehead + (node.total_key_len), + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), key_values, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint64_t), 0); if (err) return 0; - for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + for (i = 0; i < grub_bfs_to_cpu_treehead (node.count_keys); i++) { char c; start = end; end = grub_bfs_to_cpu16 (keylen_idx[i]); - if (grub_bfs_to_cpu16 (node.total_key_len) <= end) - end = grub_bfs_to_cpu16 (node.total_key_len); + if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end) + end = grub_bfs_to_cpu_treehead (node.total_key_len); c = key_data[end]; key_data[end] = 0; if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) @@ -481,47 +532,47 @@ find_in_b_tree (grub_disk_t disk, return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file `%s' not found", name); { - char key_data[grub_bfs_to_cpu16 (node.total_key_len) + 1]; - grub_uint16_t keylen_idx[grub_bfs_to_cpu16 (node.count_keys)]; - grub_uint64_t key_values[grub_bfs_to_cpu16 (node.count_keys)]; + char key_data[grub_bfs_to_cpu_treehead (node.total_key_len) + 1]; + grub_uint16_t keylen_idx[grub_bfs_to_cpu_treehead (node.count_keys)]; + grub_uint64_t key_values[grub_bfs_to_cpu_treehead (node.count_keys)]; unsigned i; grub_uint16_t start = 0, end = 0; err = read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, - grub_bfs_to_cpu16 (node.total_key_len), 0); + grub_bfs_to_cpu_treehead (node.total_key_len), 0); if (err) return err; - key_data[grub_bfs_to_cpu16 (node.total_key_len)] = 0; + key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node.total_key_len), - 8), keylen_idx, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), 0); + grub_bfs_to_cpu_treehead (node. + total_key_len), + BTREE_ALIGN), keylen_idx, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), 0); if (err) return err; err = read_bfs_file (disk, sb, ino, node_off + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu16 (node. - total_key_len), - 8) + - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint16_t), - key_values, - grub_bfs_to_cpu16 (node.count_keys) - * sizeof (grub_uint64_t), 0); + grub_bfs_to_cpu_treehead + (node.total_key_len), + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), key_values, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint64_t), 0); if (err) return err; - for (i = 0; i < grub_bfs_to_cpu16 (node.count_keys); i++) + for (i = 0; i < grub_bfs_to_cpu_treehead (node.count_keys); i++) { int cmp; char c; start = end; end = grub_bfs_to_cpu16 (keylen_idx[i]); - if (grub_bfs_to_cpu16 (node.total_key_len) <= end) - end = grub_bfs_to_cpu16 (node.total_key_len); + if (grub_bfs_to_cpu_treehead (node.total_key_len) <= end) + end = grub_bfs_to_cpu_treehead (node.total_key_len); c = key_data[end]; key_data[end] = 0; cmp = grub_strcmp (key_data + start, name); @@ -537,7 +588,7 @@ find_in_b_tree (grub_disk_t disk, break; } } - if (i < grub_bfs_to_cpu16 (node.count_keys)) + if (i < grub_bfs_to_cpu_treehead (node.count_keys)) { level--; continue; @@ -629,7 +680,9 @@ find_file (const char *path, grub_disk_t disk, "too deep nesting of symlinks"); } +#ifndef MODE_AFS if (grub_bfs_to_cpu32 (ino->flags) & LONG_SYMLINK) +#endif { grub_size_t symsize = grub_bfs_to_cpu64 (ino->size); alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) @@ -648,6 +701,7 @@ find_file (const char *path, grub_disk_t disk, } alloc[symsize] = 0; } +#ifndef MODE_AFS else { alloc = grub_malloc ((ptr2 ? grub_strlen (ptr2) : 0) @@ -662,6 +716,7 @@ find_file (const char *path, grub_disk_t disk, sizeof (ino->inplace_link)); alloc[sizeof (ino->inplace_link)] = 0; } +#endif if (alloc[0] == '/') { err = read_extent (disk, sb, &sb->root_dir, 0, 0, ino, @@ -695,9 +750,15 @@ static grub_err_t mount (grub_disk_t disk, struct grub_bfs_superblock *sb) { grub_err_t err; - err = grub_disk_read (disk, 1, 0, sizeof (*sb), sb); + err = grub_disk_read (disk, SUPERBLOCK, 0, sizeof (*sb), sb); if (err == GRUB_ERR_OUT_OF_RANGE) - return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + return grub_error (GRUB_ERR_BAD_FS, +#ifdef MODE_AFS + "not an AFS filesystem" +#else + "not a BFS filesystem" +#endif + ); if (err) return err; if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 @@ -705,7 +766,13 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 || (grub_bfs_to_cpu32 (sb->bsize) != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) - return grub_error (GRUB_ERR_BAD_FS, "not a BFS filesystem"); + return grub_error (GRUB_ERR_BAD_FS, +#ifdef MODE_AFS + "not an AFS filesystem" +#else + "not a BFS filesystem" +#endif + ); return GRUB_ERR_NONE; } @@ -739,7 +806,12 @@ grub_bfs_dir (grub_device_t device, const char *path, } info.mtimeset = 1; +#ifdef MODE_AFS + info.mtime = + grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0); +#else info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; +#endif info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR); return hook_in (name, &info); } @@ -785,7 +857,7 @@ grub_bfs_open (struct grub_file *file, const char *name) if (err) return err; if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_REG)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); data = grub_zalloc (sizeof (struct grub_bfs_data) + grub_bfs_to_cpu32 (sb.bsize)); @@ -837,6 +909,7 @@ grub_bfs_label (grub_device_t device, char **label) return GRUB_ERR_NONE; } +#ifndef MODE_AFS static grub_ssize_t read_bfs_attr (grub_disk_t disk, const struct grub_bfs_superblock *sb, @@ -935,29 +1008,43 @@ grub_bfs_uuid (grub_device_t device, char **uuid) } return GRUB_ERR_NONE; } - +#endif static struct grub_fs grub_bfs_fs = { +#ifdef MODE_AFS + .name = "afs", +#else .name = "bfs", +#endif .dir = grub_bfs_dir, .open = grub_bfs_open, .read = grub_bfs_read, .close = grub_bfs_close, .label = grub_bfs_label, +#ifndef MODE_AFS .uuid = grub_bfs_uuid, +#endif #ifdef GRUB_UTIL .reserved_first_sector = 1, #endif }; +#ifdef MODE_AFS +GRUB_MOD_INIT (afs) +#else GRUB_MOD_INIT (bfs) +#endif { COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); grub_fs_register (&grub_bfs_fs); } +#ifdef MODE_AFS +GRUB_MOD_FINI (afs) +#else GRUB_MOD_FINI (bfs) +#endif { grub_fs_unregister (&grub_bfs_fs); } From 94ef05c2652e78d2b6be32829530efa5eb9d7ac0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 19:30:04 +0100 Subject: [PATCH 1312/1414] * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type string. --- ChangeLog | 5 +++++ grub-core/loader/mips/linux.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8f44f2080..3e9f8a640 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 Vladimir Serbinenko + + * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type + string. + 2011-10-30 Vladimir Serbinenko Leverage BFS implementation to read AFS. diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 2b4875983..17c2656e2 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); const char loongson_machtypes[][60] = { [GRUB_ARCH_MACHINE_YEELOONG] = "machtype=lemote-yeeloong-2f-8.9inches", - [GRUB_ARCH_MACHINE_FULOONG2F] = "machtype=lemote-fuloong-2f-unknown", + [GRUB_ARCH_MACHINE_FULOONG2F] = "machtype=lemote-fuloong-2f-box", [GRUB_ARCH_MACHINE_FULOONG2E] = "machtype=lemote-fuloong-2e-unknown" }; #endif From 45cdd3ea372ff15b68b622e2791b61edc6d0ac21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 20:14:57 +0100 Subject: [PATCH 1313/1414] Fix JFS file name length limitations. * grub-core/fs/jfs.c (grub_jfs_inode): Fix in-place symlink length. (grub_jfs_diropen): Fix maximum filename length. (grub_jfs_getent): Fix filename length. (grub_jfs_lookup_symlink): Fix size checks. --- ChangeLog | 9 +++++++++ grub-core/fs/jfs.c | 15 +++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3e9f8a640..cfdbfaeda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-30 Vladimir Serbinenko + + Fix JFS file name length limitations. + + * grub-core/fs/jfs.c (grub_jfs_inode): Fix in-place symlink length. + (grub_jfs_diropen): Fix maximum filename length. + (grub_jfs_getent): Fix filename length. + (grub_jfs_lookup_symlink): Fix size checks. + 2011-10-30 Vladimir Serbinenko * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index c5e82bfec..cf7520bb3 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -205,7 +205,7 @@ struct grub_jfs_inode struct { grub_uint8_t unused[32]; - grub_uint8_t path[128]; + grub_uint8_t path[256]; } symlink; } __attribute__ ((packed)); } __attribute__ ((packed)); @@ -238,7 +238,10 @@ struct grub_jfs_diropen struct grub_jfs_leaf_next_dirent *next_leaf; /* The filename and inode of the last read dirent. */ - char name[255]; + /* On-disk name is at most 255 UTF-16 codepoints. + Every UTF-16 codepoint is at most 4 UTF-8 bytes. + */ + char name[256 * 4 + 1]; grub_uint32_t ino; } __attribute__ ((packed)); @@ -479,7 +482,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) struct grub_jfs_leaf_next_dirent *next_leaf; int len; int nextent; - grub_uint16_t filename[255]; + grub_uint16_t filename[256]; auto void addstr (grub_uint16_t *uname, int ulen); @@ -708,14 +711,14 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path, static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) { - grub_uint64_t size = grub_le_to_cpu64 (data->currinode.size); + grub_size_t size = grub_le_to_cpu64 (data->currinode.size); char symlink[size + 1]; if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT) return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); - if (size <= 128) - grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128); + if (size <= sizeof (data->currinode.symlink.path)) + grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size); else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0) return grub_errno; From c83a08d84ac9e35cfde2e9df2b660010073e9227 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 20:23:05 +0100 Subject: [PATCH 1314/1414] Fix iso9660 filename limitations and fix memory leaks. * grub-core/fs/iso9660.c (set_rockridge): Free sua at the end. (grub_iso9660_iterate_dir): Fix slash handling in symlinks. --- ChangeLog | 7 +++++++ grub-core/fs/iso9660.c | 46 ++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfdbfaeda..223afb1e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-30 Vladimir Serbinenko + + Fix iso9660 filename limitations and fix memory leaks. + + * grub-core/fs/iso9660.c (set_rockridge): Free sua at the end. + (grub_iso9660_iterate_dir): Fix slash handling in symlinks. + 2011-10-30 Vladimir Serbinenko Fix JFS file name length limitations. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index a2e731351..d4c52bed4 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -395,7 +395,10 @@ set_rockridge (struct grub_iso9660_data *data) (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, sua_size, sua)) - return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + { + grub_free (sua); + return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + } entry = (struct grub_iso9660_susp_entry *) sua; @@ -419,8 +422,12 @@ set_rockridge (struct grub_iso9660_data *data) extensions. */ if (grub_iso9660_susp_iterate (&rootnode, sua_pos, sua_size, susp_iterate)) - return grub_errno; + { + grub_free (sua); + return grub_errno; + } } + grub_free (sua); return GRUB_ERR_NONE; } @@ -516,12 +523,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, { struct grub_iso9660_dir dirent; grub_off_t offset = 0; - char *filename; + char *filename = 0; int filename_alloc = 0; enum grub_fshelp_filetype type; grub_off_t len; char *symlink = 0; - int addslash = 0; auto void add_part (const char *part, int len); @@ -551,23 +557,30 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename = "."; else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) filename = ".."; - else + else if (entry->len >= 5) { int size = 1; - if (filename) + char *old; + size = entry->len - 5; + old = filename; + if (filename_alloc) { size += grub_strlen (filename); - grub_realloc (filename, - grub_strlen (filename) - + entry->len); + filename = grub_realloc (filename, size + 1); } else { - size = entry->len - 5; + filename_alloc = 1; filename = grub_zalloc (size + 1); + filename[0] = 0; + } + if (!filename) + { + filename = old; + return grub_errno; } filename_alloc = 1; - grub_strncpy (filename, (char *) &entry->data[1], size); + grub_strncat (filename, (char *) &entry->data[1], size); filename[size] = '\0'; } } @@ -601,12 +614,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* The symlink is not stored as a POSIX symlink, translate it. */ while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len)) { - if (addslash) - { - add_part ("/", 1); - addslash = 0; - } - /* The current position is the `Component Flag'. */ switch (entry->data[pos] & 30) { @@ -615,10 +622,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* The data on pos + 2 is the actual data, pos + 1 is the length. Both are part of the `Component Record'. */ + if (symlink && (entry->data[pos] & 1)) + add_part ("/", 1); add_part ((char *) &entry->data[pos + 2], entry->data[pos + 1]); - if ((entry->data[pos] & 1)) - addslash = 1; break; } @@ -653,7 +660,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, for (; offset < len; offset += dirent.len) { symlink = 0; - addslash = 0; if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; From 19ee298767b7780618ea04cb556cd6211fffe780 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 30 Oct 2011 23:06:25 +0100 Subject: [PATCH 1315/1414] Handle symlinks and long names on tar and cpio. * grub-core/fs/cpio.c (ATTR_TYPE): New definition. (ATTR_FILE): Likewise. (ATTR_DIR): Likewise. (ATTR_LNK): Likewise. (grub_cpio_data) [MODE_USTAR]: New fields linkname and linkname_alloc. (grub_cpio_find_file): Fill mode, handle linkname field as well as L and K entries. (grub_cpio_mount): Zero-fill data. (handle_symlink): New function. --- ChangeLog | 14 ++ grub-core/fs/cpio.c | 351 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 307 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index 223afb1e6..543823e9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-10-30 Vladimir Serbinenko + + Handle symlinks and long names on tar and cpio. + + * grub-core/fs/cpio.c (ATTR_TYPE): New definition. + (ATTR_FILE): Likewise. + (ATTR_DIR): Likewise. + (ATTR_LNK): Likewise. + (grub_cpio_data) [MODE_USTAR]: New fields linkname and linkname_alloc. + (grub_cpio_find_file): Fill mode, handle linkname field as well as + L and K entries. + (grub_cpio_mount): Zero-fill data. + (handle_symlink): New function. + 2011-10-30 Vladimir Serbinenko Fix iso9660 filename limitations and fix memory leaks. diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index 92531390e..b43e54ec9 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -25,6 +25,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#define ATTR_TYPE 0160000 +#define ATTR_FILE 0100000 +#define ATTR_DIR 0040000 +#define ATTR_LNK 0120000 + #ifndef MODE_USTAR /* cpio support */ #define MAGIC_BCPIO 070707 @@ -74,6 +79,10 @@ struct grub_cpio_data grub_off_t hofs; grub_off_t dofs; grub_off_t size; +#ifdef MODE_USTAR + char *linkname; + grub_size_t linkname_alloc; +#endif }; static grub_dl_t my_mod; @@ -101,7 +110,8 @@ canonicalize (char *name) static grub_err_t grub_cpio_find_file (struct grub_cpio_data *data, char **name, - grub_int32_t *mtime, grub_disk_addr_t * ofs) + grub_int32_t *mtime, grub_disk_addr_t *ofs, + grub_uint32_t *mode) { #ifndef MODE_USTAR struct head hd; @@ -115,11 +125,14 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, 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 (mode) + *mode = hd.mode; if (hd.namesize & 1) hd.namesize++; - if ((*name = grub_malloc (hd.namesize)) == NULL) + *name = grub_malloc (hd.namesize + 1); + if (*name == NULL) return grub_errno; if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), @@ -128,9 +141,10 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, grub_free (*name); return grub_errno; } + (*name)[hd.namesize] = 0; if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 - && ! grub_memcmp(*name, "TRAILER!!!", 11)) + && grub_memcmp(*name, "TRAILER!!!", 11) == 0) { *ofs = 0; return GRUB_ERR_NONE; @@ -144,29 +158,118 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, (*ofs)++; #else struct head hd; + int reread = 0, have_longname = 0, have_longlink = 0; - if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; - - if (!hd.name[0]) + for (reread = 0; reread < 3; reread++) { - *ofs = 0; + if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) + return grub_errno; + + if (!hd.name[0]) + { + *ofs = 0; + return GRUB_ERR_NONE; + } + + if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) + return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); + + if (hd.typeflag == 'L') + { + grub_err_t err; + grub_size_t namesize = grub_strtoull (hd.size, NULL, 8); + *name = grub_malloc (namesize + 1); + if (*name == NULL) + return grub_errno; + err = grub_disk_read (data->disk, 0, + data->hofs + GRUB_DISK_SECTOR_SIZE, namesize, + *name); + (*name)[namesize] = 0; + if (err) + return err; + data->hofs += GRUB_DISK_SECTOR_SIZE + + ((namesize + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); + have_longname = 1; + continue; + } + + if (hd.typeflag == 'K') + { + grub_err_t err; + grub_size_t linksize = grub_strtoull (hd.size, NULL, 8); + if (data->linkname_alloc < linksize + 1) + { + char *n; + n = grub_malloc (2 * (linksize + 1)); + if (!n) + return grub_errno; + grub_free (data->linkname); + data->linkname = n; + data->linkname_alloc = 2 * (linksize + 1); + } + + err = grub_disk_read (data->disk, 0, + data->hofs + GRUB_DISK_SECTOR_SIZE, linksize, + data->linkname); + if (err) + return err; + data->linkname[linksize] = 0; + data->hofs += GRUB_DISK_SECTOR_SIZE + + ((linksize + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); + have_longlink = 1; + continue; + } + + if (!have_longname) + { + *name = grub_strdup (hd.name); + if (*name == NULL) + return grub_errno; + } + + data->size = grub_strtoull (hd.size, NULL, 8); + 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); + if (mode) + { + *mode = grub_strtoul (hd.mode, NULL, 8); + switch (hd.typeflag) + { + case '2': + *mode |= ATTR_LNK; + break; + case '0': + *mode |= ATTR_FILE; + break; + case '5': + *mode |= ATTR_DIR; + break; + } + } + if (!have_longlink) + { + if (data->linkname_alloc < 101) + { + char *n; + n = grub_malloc (101); + if (!n) + return grub_errno; + grub_free (data->linkname); + data->linkname = n; + data->linkname_alloc = 101; + } + grub_memcpy (data->linkname, hd.linkname, sizeof (hd.linkname)); + data->linkname[100] = 0; + } + + canonicalize (*name); return GRUB_ERR_NONE; } - - if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) - return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); - - if ((*name = grub_strdup (hd.name)) == NULL) - return grub_errno; - - data->size = grub_strtoull (hd.size, NULL, 8); - 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); - canonicalize (*name); #endif return GRUB_ERR_NONE; } @@ -188,7 +291,7 @@ grub_cpio_mount (grub_disk_t disk) #endif goto fail; - data = (struct grub_cpio_data *) grub_malloc (sizeof (*data)); + data = (struct grub_cpio_data *) grub_zalloc (sizeof (*data)); if (!data) goto fail; @@ -208,15 +311,105 @@ fail: } static grub_err_t -grub_cpio_dir (grub_device_t device, const char *path, +handle_symlink (struct grub_cpio_data *data, + const char *fn, char **name, + grub_uint32_t mode, int *restart) +{ + grub_size_t flen; + char *target; +#ifndef MODE_USTAR + grub_err_t err; +#endif + char *ptr; + char *lastslash; + grub_size_t prefixlen; + char *rest; + grub_size_t size; + + *restart = 0; + + if ((mode & ATTR_TYPE) != ATTR_LNK) + return GRUB_ERR_NONE; + flen = grub_strlen (fn); + if (grub_memcmp (*name, fn, flen) != 0 + || ((*name)[flen] != 0 && (*name)[flen] != '/')) + return GRUB_ERR_NONE; + rest = *name + flen; + lastslash = rest; + if (*rest) + rest++; + while (lastslash >= *name && *lastslash != '/') + lastslash--; + if (lastslash >= *name) + prefixlen = lastslash - *name; + else + prefixlen = 0; + + if (prefixlen) + prefixlen++; + +#ifdef MODE_USTAR + size = grub_strlen (data->linkname); +#else + size = data->size; +#endif + if (size == 0) + return GRUB_ERR_NONE; + target = grub_malloc (size + grub_strlen (*name) + 2); + if (!target) + return grub_errno; + +#ifdef MODE_USTAR + grub_memcpy (target + prefixlen, data->linkname, size); +#else + err = grub_disk_read (data->disk, 0, data->dofs, data->size, + target + prefixlen); + if (err) + return err; +#endif + if (target[prefixlen] == '/') + { + grub_memmove (target, target + prefixlen, data->size - 1); + ptr = target + data->size - 1; + ptr = grub_stpcpy (ptr, rest); + *ptr = 0; + grub_dprintf ("cpio", "symlink redirected %s to %s\n", + *name, target); + grub_free (*name); + *name = target; + *restart = 1; + return GRUB_ERR_NONE; + } + if (prefixlen) + { + grub_memcpy (target, *name, prefixlen); + target[prefixlen] = '/'; + } + ptr = target + prefixlen + size; + ptr = grub_stpcpy (ptr, rest); + *ptr = 0; + grub_dprintf ("cpio", "symlink redirected %s to %s\n", + *name, target); + grub_free (*name); + *name = target; + *restart = 1; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cpio_dir (grub_device_t device, const char *path_in, int (*hook) (const char *filename, const struct grub_dirhook_info *info)) { struct grub_cpio_data *data; grub_disk_addr_t ofs; - char *prev, *name; - const char *np; + char *prev, *name, *path; grub_size_t len; + int symlinknest = 0; + + path = grub_strdup (path_in + 1); + if (!path) + return grub_errno; grub_dl_ref (my_mod); @@ -224,23 +417,27 @@ grub_cpio_dir (grub_device_t device, const char *path, data = grub_cpio_mount (device->disk); if (!data) - goto fail; - - np = path + 1; - len = grub_strlen (path) - 1; + { + grub_free (path); + return grub_errno; + } + len = grub_strlen (path); data->hofs = 0; while (1) { grub_int32_t mtime; + grub_uint32_t mode; + grub_err_t err; - if (grub_cpio_find_file (data, &name, &mtime, &ofs)) + if (grub_cpio_find_file (data, &name, &mtime, &ofs, &mode)) goto fail; if (!ofs) break; - if (grub_memcmp (np, name, len) == 0) + if (grub_memcmp (path, name, len) == 0 + && (name[len] == 0 || name[len] == '/' || len == 0)) { char *p, *n; @@ -265,14 +462,35 @@ grub_cpio_dir (grub_device_t device, const char *path, prev = name; } else - grub_free (name); + { + int restart; + err = handle_symlink (data, name, &path, mode, &restart); + grub_free (name); + if (err) + goto fail; + if (restart) + { + len = grub_strlen (path); + if (++symlinknest == 8) + { + grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + goto fail; + } + ofs = 0; + } + } } data->hofs = ofs; } fail: + grub_free (path); grub_free (prev); +#ifdef MODE_USTAR + grub_free (data->linkname); +#endif grub_free (data); grub_dl_unref (my_mod); @@ -281,23 +499,33 @@ fail: } static grub_err_t -grub_cpio_open (grub_file_t file, const char *name) +grub_cpio_open (grub_file_t file, const char *name_in) { struct grub_cpio_data *data; grub_disk_addr_t ofs; char *fn; - int i, j; + char *name = grub_strdup (name_in + 1); + int symlinknest = 0; + + if (!name) + return grub_errno; grub_dl_ref (my_mod); data = grub_cpio_mount (file->device->disk); if (!data) - goto fail; + { + grub_free (name); + return grub_errno; + } data->hofs = 0; while (1) { - if (grub_cpio_find_file (data, &fn, NULL, &ofs)) + grub_uint32_t mode; + int restart; + + if (grub_cpio_find_file (data, &fn, NULL, &ofs, &mode)) goto fail; if (!ofs) @@ -306,33 +534,31 @@ grub_cpio_open (grub_file_t file, const char *name) break; } - /* Compare NAME and FN by hand in order to cope with duplicate - slashes. */ - i = 0; - j = 0; - while (name[i] == '/') - i++; - while (1) + if (handle_symlink (data, fn, &name, mode, &restart)) { - if (name[i] != fn[j]) - goto no_match; - - if (name[i] == '\0') - break; - - while (name[i] == '/' && name[i+1] == '/') - i++; - - i++; - j++; + grub_free (fn); + goto fail; } - if (name[i] != fn[j]) + if (restart) + { + ofs = 0; + if (++symlinknest == 8) + { + grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + goto fail; + } + goto no_match; + } + + if (grub_strcmp (name, fn) != 0) goto no_match; file->data = data; file->size = data->size; grub_free (fn); + grub_free (name); return GRUB_ERR_NONE; @@ -343,8 +569,11 @@ grub_cpio_open (grub_file_t file, const char *name) } fail: - +#ifdef MODE_USTAR + grub_free (data->linkname); +#endif grub_free (data); + grub_free (name); grub_dl_unref (my_mod); @@ -364,7 +593,13 @@ grub_cpio_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_cpio_close (grub_file_t file) { - grub_free (file->data); + struct grub_cpio_data *data; + + data = file->data; +#ifdef MODE_USTAR + grub_free (data->linkname); +#endif + grub_free (data); grub_dl_unref (my_mod); From 46bc1dc244f7e6461cc2d59f41a2181722c6c384 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:40:30 +0100 Subject: [PATCH 1316/1414] * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of long symlinks. --- ChangeLog | 8 ++++++++ grub-core/fs/ufs.c | 13 ++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 543823e9c..825524c09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-31 Vladimir Serbinenko + + * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of + long symlinks. + 2011-10-30 Vladimir Serbinenko Handle symlinks and long names on tar and cpio. @@ -11,6 +16,9 @@ L and K entries. (grub_cpio_mount): Zero-fill data. (handle_symlink): New function. + (grub_cpio_dir): Handle symlinks. + (grub_cpio_open): Likewise. + (grub_cpio_close) [MODE_USTAR]: Free linkname. 2011-10-30 Vladimir Serbinenko diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index 435fec6a5..ea7a7455f 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -394,21 +394,16 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode) static grub_err_t grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) { - char symlink[INODE_SIZE (data)]; + char symlink[INODE_SIZE (data) + 1]; if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT) return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); - if (INODE_NBLOCKS (data) == 0) + if (INODE_SIZE (data) <= sizeof (data->inode.symlink)) grub_strcpy (symlink, (char *) INODE (data, symlink)); else - { - grub_disk_read (data->disk, - (INODE_DIRBLOCKS (data, 0) - << grub_le_to_cpu32 (data->sblock.log2_blksz)), - 0, INODE_SIZE (data), symlink); - symlink[INODE_SIZE (data)] = '\0'; - } + grub_ufs_read_file (data, 0, 0, INODE_SIZE (data), symlink); + symlink[INODE_SIZE (data)] = '\0'; /* The symlink is an absolute path, go back to the root inode. */ if (symlink[0] == '/') From 87661123b23d12bed46d90c3d6c11af7780beb88 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:50:43 +0100 Subject: [PATCH 1317/1414] Use shifts in UFS. * grub-core/fs/ufs.c (UFS_LOG_BLKSZ): New macro. (grub_ufs_data): New field log2_blksz. (grub_ufs_read_file): Use shifts. (grub_ufs_mount): Check block size and logarithm it. --- ChangeLog | 9 +++++++++ grub-core/fs/ufs.c | 23 ++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 825524c09..79b930c1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-31 Vladimir Serbinenko + + Use shifts in UFS. + + * grub-core/fs/ufs.c (UFS_LOG_BLKSZ): New macro. + (grub_ufs_data): New field log2_blksz. + (grub_ufs_read_file): Use shifts. + (grub_ufs_mount): Check block size and logarithm it. + 2011-10-31 Vladimir Serbinenko * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index ea7a7455f..bfcb7148f 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -50,6 +50,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* Calculate in which group the inode can be found. */ #define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize)) +#define UFS_LOG_BLKSZ(sblock) (data->log2_blksz) #define INODE(data,field) data->inode. field #ifdef MODE_UFS2 @@ -214,6 +215,7 @@ struct grub_ufs_data struct grub_ufs_inode inode; int ino; int linknest; + int log2_blksz; }; static grub_dl_t my_mod; @@ -295,10 +297,9 @@ grub_ufs_read_file (struct grub_ufs_data *data, if (len + pos > INODE_SIZE (data)) len = INODE_SIZE (data) - pos; - blockcnt = grub_divmod64 ((len + pos + UFS_BLKSZ (sblock) - 1), - UFS_BLKSZ (sblock), 0); + blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) >> UFS_LOG_BLKSZ (sblock); - for (i = grub_divmod64 (pos, UFS_BLKSZ (sblock), 0); i < blockcnt; i++) + for (i = pos >> UFS_LOG_BLKSZ (sblock); i < blockcnt; i++) { grub_disk_addr_t blknr; grub_off_t blockoff; @@ -306,7 +307,7 @@ grub_ufs_read_file (struct grub_ufs_data *data, int skipfirst = 0; - grub_divmod64 (pos, UFS_BLKSZ (sblock), &blockoff); + blockoff = pos & (UFS_BLKSZ (sblock) - 1); blknr = grub_ufs_get_file_block (data, i); if (grub_errno) @@ -315,14 +316,14 @@ grub_ufs_read_file (struct grub_ufs_data *data, /* Last block. */ if (i == blockcnt - 1) { - grub_divmod64 (len + pos, UFS_BLKSZ (sblock), &blockend); + blockend = (len + pos) & (UFS_BLKSZ (sblock) - 1); if (!blockend) blockend = UFS_BLKSZ (sblock); } /* First block. */ - if (i == grub_divmod64 (pos, UFS_BLKSZ (sblock), 0)) + if (i == (pos >> UFS_LOG_BLKSZ (sblock))) { skipfirst = blockoff; blockend -= skipfirst; @@ -536,8 +537,16 @@ grub_ufs_mount (grub_disk_t disk) if (grub_errno) goto fail; - if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC) + /* No need to byteswap bsize in this check. It works the same on both + endiannesses. */ + if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC + && data->sblock.bsize != 0 + && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0)) { + for (data->log2_blksz = 0; + (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sblock.bsize); + data->log2_blksz++); + data->disk = disk; data->linknest = 0; return data; From ce109e843cd605acc2e69a1449b723a8edc6c873 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 10:52:39 +0100 Subject: [PATCH 1318/1414] Read label on UFS1. * grub-core/fs/ufs.c (grub_ufs_label): Remove MODE_UFS2 condition. (grub_ufs_fs): Always set .label. --- ChangeLog | 7 +++++++ grub-core/fs/ufs.c | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79b930c1e..211a5f9ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-10-31 Vladimir Serbinenko + + Read label on UFS1. + + * grub-core/fs/ufs.c (grub_ufs_label): Remove MODE_UFS2 condition. + (grub_ufs_fs): Always set .label. + 2011-10-31 Vladimir Serbinenko Use shifts in UFS. diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index bfcb7148f..e951d6ce3 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -705,8 +705,6 @@ grub_ufs_close (grub_file_t file) return GRUB_ERR_NONE; } - -#ifdef MODE_UFS2 static grub_err_t grub_ufs_label (grub_device_t device, char **label) { @@ -726,7 +724,6 @@ grub_ufs_label (grub_device_t device, char **label) return grub_errno; } -#endif static grub_err_t grub_ufs_uuid (grub_device_t device, char **uuid) @@ -790,9 +787,7 @@ static struct grub_fs grub_ufs_fs = .open = grub_ufs_open, .read = grub_ufs_read, .close = grub_ufs_close, -#ifdef MODE_UFS2 .label = grub_ufs_label, -#endif .uuid = grub_ufs_uuid, .mtime = grub_ufs_mtime, .next = 0 From 7c01e783dcff1365057ea917e9095a2cb7b9d271 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 Oct 2011 13:56:52 +0100 Subject: [PATCH 1319/1414] * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and don't report potentially unavialiable fields in debug output. (find_path): Fix double-free and memory leak. --- ChangeLog | 6 ++++++ grub-core/fs/btrfs.c | 17 +++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 211a5f9ca..27c18655a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-31 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and + don't report potentially unavialiable fields in debug output. + (find_path): Fix double-free and memory leak. + 2011-10-31 Vladimir Serbinenko Read label on UFS1. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 93642f789..16e034661 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -992,6 +992,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, grub_error (GRUB_ERR_BAD_FS, "extent not found"); return -1; } + if ((grub_ssize_t) elemsize < ((char *) &data->extent->inl + - (char *) data->extent)) + { + grub_error (GRUB_ERR_BAD_FS, "extent descriptor is too short"); + return -1; + } data->extstart = grub_le_to_cpu64 (key_out.offset); data->extsize = elemsize; data->extent = grub_malloc (elemsize); @@ -1012,12 +1018,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, data->extend = data->extstart + grub_le_to_cpu64 (data->extent->filled); - grub_dprintf ("btrfs", "extent 0x%" PRIxGRUB_UINT64_T "+0x%" - PRIxGRUB_UINT64_T " (0x%" - PRIxGRUB_UINT64_T ")\n", + grub_dprintf ("btrfs", "regular extent 0x%" PRIxGRUB_UINT64_T "+0x%" + PRIxGRUB_UINT64_T "\n", grub_le_to_cpu64 (key_out.offset), - grub_le_to_cpu64 (data->extent->size), - grub_le_to_cpu64 (data->extent->filled)); + grub_le_to_cpu64 (data->extent->size)); if (data->extend <= pos) { grub_error (GRUB_ERR_BAD_FS, "extent not found"); @@ -1309,7 +1313,6 @@ find_path (struct grub_btrfs_data *data, grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, grub_strlen (path) + 1); grub_free (path_alloc); - grub_free (origpath); path = path_alloc = tmp; if (path[0] == '/') { @@ -1385,6 +1388,8 @@ find_path (struct grub_btrfs_data *data, } grub_free (direl); + grub_free (origpath); + grub_free (path_alloc); return GRUB_ERR_NONE; } From ce8ca56ed996ddeff86141f40a2d09dd8046d5c3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 1 Nov 2011 20:05:28 +0100 Subject: [PATCH 1320/1414] Fix RAIDZ(2). * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member ashift. (fill_vdev_info_real): Set ashift. (read_device): Rewrite RAIDZ part based on reverse engineering. --- ChangeLog | 8 +++++ grub-core/fs/zfs/zfs.c | 70 +++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27c18655a..e112868f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-01 Vladimir Serbinenko + + Fix RAIDZ(2). + + * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member ashift. + (fill_vdev_info_real): Set ashift. + (read_device): Rewrite RAIDZ part based on reverse engineering. + 2011-10-31 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9bd68222a..c7fd13018 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -152,6 +152,7 @@ struct grub_zfs_device_desc /* Valid only for RAIDZ. */ unsigned nparity; + unsigned ashift; /* Valid only for leaf devices. */ grub_device_t dev; @@ -516,6 +517,9 @@ fill_vdev_info_real (struct grub_zfs_data *data, if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); fill->nparity = par; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "ashift", &par)) + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz ashift"); + fill->ashift = par; } nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); @@ -882,38 +886,76 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, } case DEVICE_RAIDZ: { - grub_uint64_t sector; - grub_uint32_t bsize; unsigned c = 0; + grub_uint64_t high; + grub_uint64_t devn; + grub_uint64_t redundancy_strip = 0, m; + grub_uint64_t redundancy_strip2 = 0; + grub_uint32_t s; - bsize = (asize + desc->nparity) / desc->n_children; - sector = offset >> 9; + /* (4,1) -> 2, (3,1) -> 1 */ + if (desc->nparity == 1) + s = asize + desc->n_children - 2; + else + s = asize + desc->n_children - 3; + high = grub_divmod64 ((offset >> desc->ashift), + desc->n_children, &m); + + if (desc->nparity == 1) + { + redundancy_strip = m; + redundancy_strip += ((offset >> (desc->ashift + 11)) & 1); + if (redundancy_strip == desc->n_children) + redundancy_strip = 0; + redundancy_strip2 = redundancy_strip; + } + else + { + redundancy_strip = m; + redundancy_strip2 = m + 1; + if (redundancy_strip2 == desc->n_children) + redundancy_strip2 = 0; + } + grub_dprintf ("zfs", "rs = %x, %llx\n", + (int) redundancy_strip, + (unsigned long long) high); while (len > 0) { grub_size_t csize; - grub_uint64_t high; - grub_uint64_t devn; + grub_uint32_t bsize; grub_err_t err; - high = grub_divmod64 (sector + (asize > 2) + c, desc->n_children, - &devn); - csize = bsize << 9; + bsize = s / desc->n_children; + + while (1) + { + high = grub_divmod64 ((offset >> desc->ashift) + c, + desc->n_children, &devn); + if (devn != redundancy_strip && devn != redundancy_strip2) + break; + c++; + } + csize = bsize << desc->ashift; if (csize > len) csize = len; + grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T - "+%d+%u -> (0x%" PRIxGRUB_UINT64_T ", 0x%" + "+%u (%d, %d) -> (0x%" PRIxGRUB_UINT64_T ", 0x%" PRIxGRUB_UINT64_T ")\n", - sector,(asize > 2), c, high, devn); - err = read_device (high << 9, &desc->children[devn], + offset >> desc->ashift, c, asize, bsize, high, + devn); + err = read_device ((high << desc->ashift) + | (offset & ((1 << desc->ashift) - 1)), + &desc->children[devn], bsize, csize, buf); if (err) return err; c++; + s--; buf = (char *) buf + csize; len -= csize; } - return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); } From aca5aefc7c7d3a1fccfbd49cb98f360af7e69e93 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Nov 2011 20:48:04 +0100 Subject: [PATCH 1321/1414] Fix RAIDZ(2) for >= 5 devices. * grub-core/fs/zfs/zfs.c (read_device): Fix length formula. Remove asize argument. All users updated. --- ChangeLog | 7 +++++++ grub-core/fs/zfs/zfs.c | 42 ++++++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index e112868f0..08bad81c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-02 Vladimir Serbinenko + + Fix RAIDZ(2) for >= 5 devices. + + * grub-core/fs/zfs/zfs.c (read_device): Fix length formula. Remove + asize argument. All users updated. + 2011-11-01 Vladimir Serbinenko Fix RAIDZ(2). diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index c7fd13018..1c9b240ab 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -852,7 +852,7 @@ scan_devices (struct grub_zfs_data *data) static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - grub_uint32_t asize, grub_size_t len, void *buf) + grub_size_t len, void *buf) { switch (desc->type) { @@ -876,7 +876,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, "non-positive number of mirror children"); for (i = 0; i < desc->n_children; i++) { - err = read_device (offset, &desc->children[i], asize, + err = read_device (offset, &desc->children[i], len, buf); if (!err) break; @@ -893,28 +893,32 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_uint64_t redundancy_strip2 = 0; grub_uint32_t s; - /* (4,1) -> 2, (3,1) -> 1 */ - if (desc->nparity == 1) - s = asize + desc->n_children - 2; - else - s = asize + desc->n_children - 3; + if (desc->nparity < 1 || desc->nparity > 2) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "raidz%d is not supported", desc->nparity); + + s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) + + (desc->n_children - desc->nparity) - 1); + high = grub_divmod64 ((offset >> desc->ashift), desc->n_children, &m); - if (desc->nparity == 1) + + switch (desc->nparity) { + case 1: redundancy_strip = m; redundancy_strip += ((offset >> (desc->ashift + 11)) & 1); if (redundancy_strip == desc->n_children) redundancy_strip = 0; redundancy_strip2 = redundancy_strip; - } - else - { + break; + case 2: redundancy_strip = m; redundancy_strip2 = m + 1; if (redundancy_strip2 == desc->n_children) redundancy_strip2 = 0; + break; } grub_dprintf ("zfs", "rs = %x, %llx\n", (int) redundancy_strip, @@ -924,8 +928,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t csize; grub_uint32_t bsize; grub_err_t err; - bsize = s / desc->n_children; - + bsize = s / (desc->n_children - desc->nparity); + while (1) { high = grub_divmod64 ((offset >> desc->ashift) + c, @@ -934,21 +938,24 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, break; c++; } + csize = bsize << desc->ashift; if (csize > len) csize = len; grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T - "+%u (%d, %d) -> (0x%" PRIxGRUB_UINT64_T ", 0x%" + "+%u (%" PRIxGRUB_SIZE ", %" PRIxGRUB_UINT32_T + ") -> (0x%" PRIxGRUB_UINT64_T ", 0x%" PRIxGRUB_UINT64_T ")\n", - offset >> desc->ashift, c, asize, bsize, high, + offset >> desc->ashift, c, len, bsize, high, devn); err = read_device ((high << desc->ashift) | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], - bsize, csize, buf); + csize, buf); if (err) return err; + c++; s--; buf = (char *) buf + csize; @@ -976,8 +983,7 @@ read_dva (const dva_t *dva, for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) { - err = read_device (offset, &data->devices_attached[i], - dva->dva_word[0] & 0xffffff, len, buf); + err = read_device (offset, &data->devices_attached[i], len, buf); if (!err) return GRUB_ERR_NONE; break; From 177440046d0f5129dfa2513835a42cfb86fdc2c7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Nov 2011 23:28:25 +0100 Subject: [PATCH 1322/1414] * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single drive failure on both raidz and raidz2. --- ChangeLog | 5 +++ grub-core/fs/zfs/zfs.c | 100 +++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08bad81c6..047c156c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-02 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single + drive failure on both raidz and raidz2. + 2011-11-02 Vladimir Serbinenko Fix RAIDZ(2) for >= 5 devices. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1c9b240ab..1bfbed72c 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -850,6 +850,14 @@ scan_devices (struct grub_zfs_data *data) return GRUB_ERR_NONE; } +static inline void +xor (grub_uint64_t *a, const grub_uint64_t *b, grub_size_t s) +{ + s /= sizeof (grub_uint64_t); + while (s--) + *a++ ^= *b++; +} + static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t len, void *buf) @@ -889,40 +897,26 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, unsigned c = 0; grub_uint64_t high; grub_uint64_t devn; - grub_uint64_t redundancy_strip = 0, m; - grub_uint64_t redundancy_strip2 = 0; - grub_uint32_t s; + grub_uint64_t m; + grub_uint32_t s, orig_s; + void *orig_buf = buf; + grub_size_t orig_len = len; + void *recovery_buf = NULL; + grub_size_t recovery_len = 0; if (desc->nparity < 1 || desc->nparity > 2) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "raidz%d is not supported", desc->nparity); - s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) - + (desc->n_children - desc->nparity) - 1); + orig_s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) + + (desc->n_children - desc->nparity) - 1); + s = orig_s; high = grub_divmod64 ((offset >> desc->ashift), desc->n_children, &m); - - switch (desc->nparity) - { - case 1: - redundancy_strip = m; - redundancy_strip += ((offset >> (desc->ashift + 11)) & 1); - if (redundancy_strip == desc->n_children) - redundancy_strip = 0; - redundancy_strip2 = redundancy_strip; - break; - case 2: - redundancy_strip = m; - redundancy_strip2 = m + 1; - if (redundancy_strip2 == desc->n_children) - redundancy_strip2 = 0; - break; - } - grub_dprintf ("zfs", "rs = %x, %llx\n", - (int) redundancy_strip, - (unsigned long long) high); + if (desc->nparity == 2) + c = 2; while (len > 0) { grub_size_t csize; @@ -930,15 +924,12 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_err_t err; bsize = s / (desc->n_children - desc->nparity); - while (1) - { - high = grub_divmod64 ((offset >> desc->ashift) + c, - desc->n_children, &devn); - if (devn != redundancy_strip && devn != redundancy_strip2) - break; - c++; - } + if (desc->nparity == 1 + && ((offset >> (desc->ashift + 11)) & 1) == c) + c++; + high = grub_divmod64 ((offset >> desc->ashift) + c, + desc->n_children, &devn); csize = bsize << desc->ashift; if (csize > len) csize = len; @@ -953,6 +944,13 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], csize, buf); + /* No raidz2 recovery yet. */ + if (err && recovery_len == 0) + { + recovery_buf = buf; + recovery_len = csize; + grub_errno = err = 0; + } if (err) return err; @@ -961,8 +959,42 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, buf = (char *) buf + csize; len -= csize; } + if (recovery_buf) + { + grub_err_t err; + high = grub_divmod64 ((offset >> desc->ashift) + + + ((desc->nparity == 1) + && ((offset >> (desc->ashift + 11)) & 1)), + desc->n_children, &devn); + err = read_device ((high << desc->ashift) + | (offset & ((1 << desc->ashift) - 1)), + &desc->children[devn], + recovery_len, recovery_buf); + if (err) + return err; + buf = orig_buf; + len = orig_len; + s = orig_s; + while (len > 0) + { + grub_size_t csize; + csize = ((s / (desc->n_children - desc->nparity)) + << desc->ashift); + if (csize > len) + csize = len; + + if (buf != recovery_buf) + xor (recovery_buf, buf, + csize < recovery_len ? csize : recovery_len); + + s--; + buf = (char *) buf + csize; + len -= csize; + } + } + return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; } return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); } From cf5ba824ea0d09e43b11af0d36e7267ec323c157 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 07:29:35 +0100 Subject: [PATCH 1323/1414] * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. --- ChangeLog | 4 ++++ grub-core/fs/zfs/zfs.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 047c156c7..f6f5eaeeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-03 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. + 2011-11-02 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 1bfbed72c..ef352a770 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -904,7 +904,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, void *recovery_buf = NULL; grub_size_t recovery_len = 0; - if (desc->nparity < 1 || desc->nparity > 2) + if (desc->nparity < 1 || desc->nparity > 3) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "raidz%d is not supported", desc->nparity); @@ -914,9 +914,10 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, high = grub_divmod64 ((offset >> desc->ashift), desc->n_children, &m); - if (desc->nparity == 2) c = 2; + if (desc->nparity == 3) + c = 3; while (len > 0) { grub_size_t csize; From f92ece7d45946f04b5dacda73efe99c2df3888c9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 14:52:59 +0100 Subject: [PATCH 1324/1414] * grub-core/fs/nilfs2.c (grub_nilfs2_mtime): Use correct superblock field. --- grub-core/fs/nilfs2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index a8bbe9566..35a040b97 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -1152,7 +1152,7 @@ grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) if (!data) *tm = 0; else - *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime); + *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_wtime); grub_dl_unref (my_mod); From 7d0ac9316382378b389c15b0d103296df8e640dd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 14:57:34 +0100 Subject: [PATCH 1325/1414] Make reiserfs label retrieval similar to other *_label functions. * grub-core/fs/reiserfs.c (grub_reiserfs_superblock): New field label. (REISERFS_MAX_LABEL_LENGTH): Removed. (REISERFS_LABEL_OFFSET): Likewise. (grub_reiserfs_label): Rewritten. --- ChangeLog | 14 ++++++++++++++ grub-core/fs/reiserfs.c | 25 +++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6f5eaeeb..84ad4f9ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-03 Vladimir Serbinenko + + Make reiserfs label retrieval similar to other *_label functions. + + * grub-core/fs/reiserfs.c (grub_reiserfs_superblock): New field label. + (REISERFS_MAX_LABEL_LENGTH): Removed. + (REISERFS_LABEL_OFFSET): Likewise. + (grub_reiserfs_label): Rewritten. + +2011-11-03 Vladimir Serbinenko + + * grub-core/fs/nilfs2.c (grub_nilfs2_mtime): Use correct superblock + field. + 2011-11-03 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c index d5bc52d14..639de8d74 100644 --- a/grub-core/fs/reiserfs.c +++ b/grub-core/fs/reiserfs.c @@ -57,8 +57,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB" /* If the 3rd bit of an item state is set, then it's visible. */ #define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04) -#define REISERFS_MAX_LABEL_LENGTH 16 -#define REISERFS_LABEL_OFFSET 0x64 #define S_IFLNK 0xA000 @@ -109,6 +107,7 @@ struct grub_reiserfs_superblock grub_uint32_t inode_generation; grub_uint8_t unused[4]; grub_uint16_t uuid[8]; + char label[16]; } __attribute__ ((packed)); struct grub_reiserfs_journal_header @@ -1323,14 +1322,24 @@ grub_reiserfs_dir (grub_device_t device, const char *path, static grub_err_t grub_reiserfs_label (grub_device_t device, char **label) { - *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH); - if (*label) + struct grub_reiserfs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_reiserfs_mount (disk); + if (data) { - grub_disk_read (device->disk, - REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE, - REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH, - *label); + *label = grub_strndup (data->superblock.label, + sizeof (data->superblock.label)); } + else + *label = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + return grub_errno; } From 9d9b3d2f0260a7782dfe5f91e3240cde4cf132ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 15:00:45 +0100 Subject: [PATCH 1326/1414] * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field as well. --- ChangeLog | 5 +++++ grub-core/fs/ufs.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84ad4f9ec..9ec293dda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-03 Vladimir Serbinenko + + * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field + as well. + 2011-11-03 Vladimir Serbinenko Make reiserfs label retrieval similar to other *_label functions. diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index e951d6ce3..cd2994895 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -761,11 +761,13 @@ grub_ufs_mtime (grub_device_t device, grub_int32_t *tm) if (!data) *tm = 0; else + { + *tm = grub_le_to_cpu32 (data->sblock.mtime); #ifdef MODE_UFS2 - *tm = grub_le_to_cpu64 (data->sblock.mtime2); -#else - *tm = grub_le_to_cpu32 (data->sblock.mtime); + if (*tm < (grub_int64_t) grub_le_to_cpu64 (data->sblock.mtime2)) + *tm = grub_le_to_cpu64 (data->sblock.mtime2); #endif + } grub_dl_unref (my_mod); From 158dc1ea2604c8d9f17ec6c59f90c91760756057 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 15:13:30 +0100 Subject: [PATCH 1327/1414] XZ CRC64 and SHA256 support. * Makefile.util.def (libgrubmods): Add crc64.c. * grub-core/Makefile.core.def (crc64): New module. * grub-core/lib/crc64.c: New file. * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_hash) [!GRUB_EMBED_DECOMPRESSOR]: Rename crc32_context to hash_context. Fix the type. (MAX_HASH_SIZE): New define. (xz_dec) [!GRUB_EMBED_DECOMPRESSOR]: Add generic hash fields. (dec_block) [!GRUB_EMBED_DECOMPRESSOR]: Handle non-crc32 hashes. (index_update) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. (dec_index) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. (crc32_validate) [!GRUB_EMBED_DECOMPRESSOR]: Rename to ... (hash_validate) [!GRUB_EMBED_DECOMPRESSOR]: ... this. Handle non-crc32 hashes. (hashes) [!GRUB_EMBED_DECOMPRESSOR]: New variable. (dec_stream_header): Handle non-crc32 hashes. (dec_stream_footer): Likewise. (dec_block_header): Likewise. (dec_main): Likewise. (xz_dec_init): Likewise. (xz_dec_reset): Likewise. (xz_dec_end): Likewise. * util/import_gcry.py: Add CRC64 line. --- ChangeLog | 28 ++ Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/lib/crc64.c | 111 ++++++++ grub-core/lib/xzembed/xz_dec_stream.c | 355 +++++++++++++++++--------- util/import_gcry.py | 1 + 6 files changed, 387 insertions(+), 114 deletions(-) create mode 100644 grub-core/lib/crc64.c diff --git a/ChangeLog b/ChangeLog index 9ec293dda..983b7e9e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2011-11-03 Vladimir Serbinenko + + XZ CRC64 and SHA256 support. + + * Makefile.util.def (libgrubmods): Add crc64.c. + * grub-core/Makefile.core.def (crc64): New module. + * grub-core/lib/crc64.c: New file. + * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_hash) + [!GRUB_EMBED_DECOMPRESSOR]: Rename crc32_context to hash_context. + Fix the type. + (MAX_HASH_SIZE): New define. + (xz_dec) [!GRUB_EMBED_DECOMPRESSOR]: Add generic hash fields. + (dec_block) [!GRUB_EMBED_DECOMPRESSOR]: Handle non-crc32 hashes. + (index_update) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. + (dec_index) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. + (crc32_validate) [!GRUB_EMBED_DECOMPRESSOR]: Rename to ... + (hash_validate) [!GRUB_EMBED_DECOMPRESSOR]: ... this. + Handle non-crc32 hashes. + (hashes) [!GRUB_EMBED_DECOMPRESSOR]: New variable. + (dec_stream_header): Handle non-crc32 hashes. + (dec_stream_footer): Likewise. + (dec_block_header): Likewise. + (dec_main): Likewise. + (xz_dec_init): Likewise. + (xz_dec_reset): Likewise. + (xz_dec_end): Likewise. + * util/import_gcry.py: Add CRC64 line. + 2011-11-03 Vladimir Serbinenko * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field diff --git a/Makefile.util.def b/Makefile.util.def index a839920d5..17894b1d2 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -93,6 +93,7 @@ library = { common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/crc.c; common = grub-core/lib/adler32.c; + common = grub-core/lib/crc64.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; common = grub-core/partmap/acorn.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2b72d8429..b2e8e7aa2 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1698,3 +1698,8 @@ module = { name = adler32; common = lib/adler32.c; }; + +module = { + name = crc64; + common = lib/crc64.c; +}; diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c new file mode 100644 index 000000000..92c398d1e --- /dev/null +++ b/grub-core/lib/crc64.c @@ -0,0 +1,111 @@ +/* crc64.c - crc64 function */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,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 + +static grub_uint64_t crc64_table [256]; + +static void +init_crc64_table (void) +{ + auto grub_uint64_t reflect (grub_uint64_t ref, int len); + grub_uint64_t reflect (grub_uint64_t ref, int len) + { + grub_uint64_t result = 0; + int i; + + for (i = 1; i <= len; i++) + { + if (ref & 1) + result |= 1ULL << (len - i); + ref >>= 1; + } + + return result; + } + + grub_uint64_t polynomial = 0x42f0e1eba9ea3693ULL; + int i, j; + + for(i = 0; i < 256; i++) + { + crc64_table[i] = reflect(i, 8) << 56; + for (j = 0; j < 8; j++) + { + crc64_table[i] = (crc64_table[i] << 1) ^ + (crc64_table[i] & (1ULL << 63) ? polynomial : 0); + } + crc64_table[i] = reflect(crc64_table[i], 64); + } +} + +static void +crc64_init (void *context) +{ + if (! crc64_table[1]) + init_crc64_table (); + *(grub_uint64_t *) context = 0; +} + +static void +crc64_write (void *context, const void *buf, grub_size_t size) +{ + unsigned i; + const grub_uint8_t *data = buf; + grub_uint64_t crc = ~grub_le_to_cpu64 (*(grub_uint64_t *) context); + + for (i = 0; i < size; i++) + { + crc = (crc >> 8) ^ crc64_table[(crc & 0xFF) ^ *data]; + data++; + } + + *(grub_uint64_t *) context = grub_cpu_to_le64 (~crc); +} + +static grub_uint8_t * +crc64_read (void *context) +{ + return context; +} + +static void +crc64_final (void *context __attribute__ ((unused))) +{ +} + +gcry_md_spec_t _gcry_digest_spec_crc64 = + { + "CRC64", 0, 0, 0, 8, + crc64_init, crc64_write, crc64_final, crc64_read, + sizeof (grub_uint64_t), + .blocksize = 64 + }; + +GRUB_MOD_INIT(crc64) +{ + grub_md_register (&_gcry_digest_spec_crc64); +} + +GRUB_MOD_FINI(crc64) +{ + grub_md_unregister (&_gcry_digest_spec_crc64); +} diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index 3bf201d50..383c29a2f 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -32,10 +32,13 @@ struct xz_dec_hash { vli_type unpadded; vli_type uncompressed; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t *crc32_context; + uint64_t *hash_context; #endif }; +/* Enough for up to 512 bits. */ +#define MAX_HASH_SIZE 64 + struct xz_dec { /* Position in dec_main() */ enum { @@ -62,11 +65,22 @@ struct xz_dec { size_t out_start; /* CRC32 value in Block or Index */ - uint32_t crc32_temp; /* need for crc32_validate*/ - uint8_t *crc32_context; +#ifndef GRUB_EMBED_DECOMPRESSOR + uint8_t hash_value[MAX_HASH_SIZE]; /* need for crc32_validate*/ +#endif + int have_hash_value; +#ifndef GRUB_EMBED_DECOMPRESSOR + uint64_t *hash_context; + uint64_t *crc32_context; +#endif - /* True if CRC32 is calculated from uncompressed data */ - bool has_crc32; + /* Hash function calculated from uncompressed data */ +#ifndef GRUB_EMBED_DECOMPRESSOR + const gcry_md_spec_t *hash; + const gcry_md_spec_t *crc32; +#endif + grub_size_t hash_size; + grub_uint8_t hash_id; /* True if we are operating in single-call mode. */ bool single_call; @@ -250,9 +264,12 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) return XZ_DATA_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - if (s->has_crc32) - GRUB_MD_CRC32->write(s->crc32_context,b->out + s->out_start, - b->out_pos - s->out_start); + if (s->hash) + s->hash->write(s->hash_context,b->out + s->out_start, + b->out_pos - s->out_start); + if (s->crc32) + s->crc32->write(s->crc32_context,b->out + s->out_start, + b->out_pos - s->out_start); #endif if (ret == XZ_STREAM_END) { @@ -268,14 +285,15 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) s->block.hash.unpadded += s->block_header.size + s->block.compressed; - if (s->has_crc32) - s->block.hash.unpadded += 4; + s->block.hash.unpadded += s->hash_size; s->block.hash.uncompressed += s->block.uncompressed; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->block.hash.crc32_context, - (const uint8_t *)&s->block.hash, 2 * sizeof(vli_type)); + if (s->hash) + s->hash->write(s->block.hash.hash_context, + (const uint8_t *)&s->block.hash, + 2 * sizeof(vli_type)); #endif ++s->block.count; @@ -290,7 +308,10 @@ static void index_update(struct xz_dec *s, const struct xz_buf *b) size_t in_used = b->in_pos - s->in_start; s->index.size += in_used; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->crc32_context,b->in + s->in_start, in_used); + if (s->hash) + s->hash->write(s->hash_context,b->in + s->in_start, in_used); + if (s->crc32) + s->crc32->write(s->crc32_context,b->in + s->in_start, in_used); #endif } @@ -337,8 +358,9 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) s->index.hash.uncompressed += s->vli; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->index.hash.crc32_context, - (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); + if (s->hash) + s->hash->write(s->index.hash.hash_context, + (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); #endif --s->index.count; @@ -354,13 +376,30 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) * Validate that the next four input bytes match the value of s->crc32. * s->pos must be zero when starting to validate the first byte. */ -static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b) +static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, + int crc32) { #ifndef GRUB_EMBED_DECOMPRESSOR - if(s->crc32_temp == 0) + const gcry_md_spec_t *hash = crc32 ? s->crc32 : s->hash; + grub_uint64_t *hash_context = crc32 ? s->crc32_context + : s->hash_context; + if(!s->have_hash_value && hash + && sizeof (s->hash_value) >= hash->mdlen) { - GRUB_MD_CRC32->final(s->crc32_context); - s->crc32_temp = get_unaligned_be32(GRUB_MD_CRC32->read(s->crc32_context)); + hash->final(hash_context); + grub_memcpy (s->hash_value, hash->read(hash_context), + hash->mdlen); + s->have_hash_value = 1; + if (s->hash_id == 1 || crc32) + { + grub_uint8_t t; + t = s->hash_value[0]; + s->hash_value[0] = s->hash_value[3]; + s->hash_value[3] = t; + t = s->hash_value[1]; + s->hash_value[1] = s->hash_value[2]; + s->hash_value[2] = t; + } } #endif @@ -369,23 +408,38 @@ static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b) return XZ_OK; #ifndef GRUB_EMBED_DECOMPRESSOR - if (((s->crc32_temp >> s->pos) & 0xFF) != b->in[b->in_pos++]) + if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos++]) return XZ_DATA_ERROR; #endif s->pos += 8; - } while (s->pos < 32); + } while (s->pos < (crc32 ? 32 : s->hash_size * 8)); #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->init(s->crc32_context); + if (s->hash) + s->hash->init(s->hash_context); + if (s->crc32) + s->crc32->init(s->crc32_context); #endif - s->crc32_temp = 0; + s->have_hash_value = 0; s->pos = 0; return XZ_STREAM_END; } +#ifndef GRUB_EMBED_DECOMPRESSOR +static struct +{ + const char *name; + grub_size_t size; +} hashes[] = { + [0x01] = { "CRC32", 4}, + [0x04] = { "CRC64", 8}, + [0x0A] = { "SHA256", 32}, +}; +#endif + /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ static enum xz_ret dec_stream_header(struct xz_dec *s) { @@ -393,17 +447,27 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) return XZ_FORMAT_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + if (s->crc32) + { + uint64_t hash_context[(s->crc32->contextsize + 7) / 8]; + uint8_t resulthash[s->crc32->mdlen]; + uint8_t readhash[4]; - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context,s->temp.buf + HEADER_MAGIC_SIZE, 2); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf + HEADER_MAGIC_SIZE, 2); + s->crc32->final(hash_context); - uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context)); - uint32_t readcrc = get_unaligned_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2); + grub_memcpy (resulthash, s->crc32->read(hash_context), + s->crc32->mdlen); + readhash[0] = s->temp.buf[HEADER_MAGIC_SIZE + 5]; + readhash[1] = s->temp.buf[HEADER_MAGIC_SIZE + 4]; + readhash[2] = s->temp.buf[HEADER_MAGIC_SIZE + 3]; + readhash[3] = s->temp.buf[HEADER_MAGIC_SIZE + 2]; - if(resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif /* @@ -411,10 +475,77 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) * only none (Check ID = 0) and CRC32 (Check ID = 1). */ if (s->temp.buf[HEADER_MAGIC_SIZE] != 0 - || s->temp.buf[HEADER_MAGIC_SIZE + 1] > 1) + || s->temp.buf[HEADER_MAGIC_SIZE + 1] >= ARRAY_SIZE (hashes) + || (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name == 0 + && s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0)) return XZ_OPTIONS_ERROR; - s->has_crc32 = s->temp.buf[HEADER_MAGIC_SIZE + 1]; + s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1]; + +#ifndef GRUB_EMBED_DECOMPRESSOR + if (s->crc32) + { + s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL); + if (s->crc32_context == NULL) + return XZ_MEMLIMIT_ERROR; + s->crc32->init(s->crc32_context); + } +#endif + + if (s->temp.buf[HEADER_MAGIC_SIZE + 1]) + { + s->hash_size = hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].size; +#ifndef GRUB_EMBED_DECOMPRESSOR + s->hash = grub_crypto_lookup_md_by_name (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name); + if (s->hash) + { + if (s->hash->mdlen != s->hash_size) + return XZ_OPTIONS_ERROR; + s->hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL); + if (s->hash_context == NULL) + { + kfree(s->crc32_context); + return XZ_MEMLIMIT_ERROR; + } + + s->index.hash.hash_context = kmalloc(s->hash->contextsize, + GFP_KERNEL); + if (s->index.hash.hash_context == NULL) + { + kfree(s->hash_context); + kfree(s->crc32_context); + return XZ_MEMLIMIT_ERROR; + } + + s->block.hash.hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL); + if (s->block.hash.hash_context == NULL) + { + kfree(s->index.hash.hash_context); + kfree(s->hash_context); + kfree(s->crc32_context); + return XZ_MEMLIMIT_ERROR; + } + + s->hash->init(s->hash_context); + s->hash->init(s->index.hash.hash_context); + s->hash->init(s->block.hash.hash_context); + } +#else + s->hash = 0; +#endif +#if 1 + if (!s->hash) + return XZ_OPTIONS_ERROR; +#endif + } + else + { + s->hash = 0; + s->hash_size = 0; + } + + s->have_hash_value = 0; + return XZ_OK; } @@ -426,19 +557,30 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) return XZ_DATA_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + if (s->crc32) + { + uint64_t hash_context[(s->crc32->contextsize + 7) / 8]; + uint8_t resulthash[s->crc32->mdlen]; + uint8_t readhash[4]; - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context, s->temp.buf + 4, 6); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf + 4, 6); + s->crc32->final(hash_context); - uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context)); - uint32_t readcrc = get_unaligned_le32(s->temp.buf); + grub_memcpy (resulthash, s->crc32->read(hash_context), + s->crc32->mdlen); + readhash[0] = s->temp.buf[3]; + readhash[1] = s->temp.buf[2]; + readhash[2] = s->temp.buf[1]; + readhash[3] = s->temp.buf[0]; - if(resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif + /* * Validate Backward Size. Note that we never added the size of the * Index CRC32 field to s->index.size, thus we use s->index.size / 4 @@ -447,7 +589,7 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) if ((s->index.size >> 2) != get_le32(s->temp.buf + 4)) return XZ_DATA_ERROR; - if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->has_crc32) + if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id) return XZ_DATA_ERROR; /* @@ -468,17 +610,27 @@ static enum xz_ret dec_block_header(struct xz_dec *s) */ s->temp.size -= 4; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + if (s->crc32) + { + uint64_t hash_context[(s->crc32->contextsize + 7) / 8]; + uint8_t resulthash[s->crc32->mdlen]; + uint8_t readhash[4]; - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context, s->temp.buf, s->temp.size); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf, s->temp.size); + s->crc32->final(hash_context); - uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context)); - uint32_t readcrc = get_unaligned_le32(s->temp.buf + s->temp.size); + grub_memcpy (resulthash, s->crc32->read(hash_context), + s->crc32->mdlen); + readhash[3] = s->temp.buf[s->temp.size]; + readhash[2] = s->temp.buf[s->temp.size + 1]; + readhash[1] = s->temp.buf[s->temp.size + 2]; + readhash[0] = s->temp.buf[s->temp.size + 3]; - if (resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif s->temp.pos = 2; @@ -659,11 +811,9 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_CHECK; case SEQ_BLOCK_CHECK: - if (s->has_crc32) { - ret = crc32_validate(s, b); - if (ret != XZ_STREAM_END) - return ret; - } + ret = hash_validate(s, b, 0); + if (ret != XZ_STREAM_END) + return ret; s->sequence = SEQ_BLOCK_START; break; @@ -691,24 +841,31 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) index_update(s, b); #ifndef GRUB_EMBED_DECOMPRESSOR - /* Compare the hashes to validate the Index field. */ - GRUB_MD_CRC32->final(s->block.hash.crc32_context); - GRUB_MD_CRC32->final(s->index.hash.crc32_context); - uint32_t block_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->block.hash.crc32_context); - uint32_t index_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->index.hash.crc32_context); - - if (s->block.hash.unpadded != s->index.hash.unpadded - || s->block.hash.uncompressed != s->index.hash.uncompressed - || block_crc != index_crc) + if (s->hash) { - return XZ_DATA_ERROR; + uint8_t block_hash[s->hash->mdlen]; + uint8_t index_hash[s->hash->mdlen]; + /* Compare the hashes to validate the Index field. */ + s->hash->final(s->block.hash.hash_context); + s->hash->final(s->index.hash.hash_context); + grub_memcpy (block_hash, + s->hash->read(s->block.hash.hash_context), + s->hash->mdlen); + grub_memcpy (index_hash, + s->hash->read(s->index.hash.hash_context), + s->hash->mdlen); + + if (s->block.hash.unpadded != s->index.hash.unpadded + || s->block.hash.uncompressed != s->index.hash.uncompressed + || grub_memcmp (block_hash, index_hash, s->hash->mdlen) != 0) + return XZ_DATA_ERROR; } #endif s->sequence = SEQ_INDEX_CRC32; case SEQ_INDEX_CRC32: - ret = crc32_validate(s, b); + ret = hash_validate(s, b, 1); if (ret != XZ_STREAM_END) return ret; @@ -802,46 +959,12 @@ struct xz_dec * xz_dec_init(uint32_t dict_max) return NULL; #endif + memset (s, 0, sizeof (*s)); + #ifndef GRUB_EMBED_DECOMPRESSOR - /* prepare CRC32 calculators */ - if(GRUB_MD_CRC32 == NULL) - { - kfree(s); - return NULL; - } - - s->crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL); - if (s->crc32_context == NULL) - { - kfree(s); - return NULL; - } - - s->index.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL); - if (s->index.hash.crc32_context == NULL) - { - kfree(s->crc32_context); - kfree(s); - return NULL; - } - - s->block.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL); - if (s->block.hash.crc32_context == NULL) - { - kfree(s->index.hash.crc32_context); - kfree(s->crc32_context); - kfree(s); - return NULL; - } - - - GRUB_MD_CRC32->init(s->crc32_context); - GRUB_MD_CRC32->init(s->index.hash.crc32_context); - GRUB_MD_CRC32->init(s->block.hash.crc32_context); + s->crc32 = grub_crypto_lookup_md_by_name ("CRC32"); #endif - s->crc32_temp = 0; - s->single_call = dict_max == 0; #ifdef XZ_DEC_BCJ @@ -876,28 +999,31 @@ void xz_dec_reset(struct xz_dec *s) { #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t *t; - t = s->block.hash.crc32_context; + uint64_t *t; + t = s->block.hash.hash_context; #endif memzero(&s->block, sizeof(s->block)); #ifndef GRUB_EMBED_DECOMPRESSOR - s->block.hash.crc32_context = t; - t = s->index.hash.crc32_context; + s->block.hash.hash_context = t; + t = s->index.hash.hash_context; #endif memzero(&s->index, sizeof(s->index)); #ifndef GRUB_EMBED_DECOMPRESSOR - s->index.hash.crc32_context = t; + s->index.hash.hash_context = t; #endif } s->temp.pos = 0; s->temp.size = STREAM_HEADER_SIZE; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->init(s->crc32_context); - GRUB_MD_CRC32->init(s->index.hash.crc32_context); - GRUB_MD_CRC32->init(s->block.hash.crc32_context); + if (s->hash) + { + s->hash->init(s->hash_context); + s->hash->init(s->index.hash.hash_context); + s->hash->init(s->block.hash.hash_context); + } #endif - s->crc32_temp = 0; + s->have_hash_value = 0; } void xz_dec_end(struct xz_dec *s) @@ -905,8 +1031,9 @@ void xz_dec_end(struct xz_dec *s) if (s != NULL) { xz_dec_lzma2_end(s->lzma2); #ifndef GRUB_EMBED_DECOMPRESSOR - kfree(s->index.hash.crc32_context); - kfree(s->block.hash.crc32_context); + kfree(s->index.hash.hash_context); + kfree(s->block.hash.hash_context); + kfree(s->hash_context); kfree(s->crc32_context); #endif #ifdef XZ_DEC_BCJ diff --git a/util/import_gcry.py b/util/import_gcry.py index 7591d8f0e..ec34d16b5 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -83,6 +83,7 @@ cryptolist.write ("AES-192: gcry_rijndael\n"); cryptolist.write ("AES-256: gcry_rijndael\n"); cryptolist.write ("ADLER32: adler32\n"); +cryptolist.write ("CRC64: crc64\n"); for cipher_file in cipher_files: infile = os.path.join (cipher_dir_in, cipher_file) From 9cc3581d7d06d3d56a1e1b54316bef66362513f5 Mon Sep 17 00:00:00 2001 From: crocket Date: Thu, 3 Nov 2011 15:21:47 +0100 Subject: [PATCH 1328/1414] * util/grub.d/10_linux.in: Add Slackware initrd naming. --- ChangeLog | 4 ++++ util/grub.d/10_linux.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 983b7e9e5..81f5d942d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-03 crocket + + * util/grub.d/10_linux.in: Add Slackware initrd naming. + 2011-11-03 Vladimir Serbinenko XZ CRC64 and SHA256 support. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index c3565096b..fe4f0e730 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -156,7 +156,7 @@ while [ "x$list" != "x" ] ; do linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" initrd= - for i in "initrd.img-${version}" "initrd-${version}.img" \ + for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ "initrd-${version}" "initramfs-${version}.img" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ "initrd-${alt_version}" "initramfs-${alt_version}.img" \ From 1e51cabd7bf407917363d24fbe53c44ee0e925bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 3 Nov 2011 16:04:26 +0100 Subject: [PATCH 1329/1414] * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is NULL. --- ChangeLog | 5 +++++ grub-core/gettext/gettext.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81f5d942d..ceca3fddb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-03 Vladimir Serbinenko + + * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is + NULL. + 2011-11-03 crocket * util/grub.d/10_linux.in: Add Slackware initrd naming. diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index cca8b901f..8581b1ff3 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -296,6 +296,9 @@ grub_gettext_init_ext (const char *locale) { char *locale_dir; + if (!locale) + return; + locale_dir = grub_env_get ("locale_dir"); if (locale_dir == NULL) { @@ -370,8 +373,6 @@ grub_cmd_translate (grub_command_t cmd __attribute__ ((unused)), GRUB_MOD_INIT (gettext) { - (void) mod; /* To stop warning. */ - const char *lang; lang = grub_env_get ("lang"); From 182c872a7bedb2c2c228cbee1e7022616aa8416b Mon Sep 17 00:00:00 2001 From: Philipp Matthias Hahn Date: Thu, 3 Nov 2011 16:49:02 +0100 Subject: [PATCH 1330/1414] * util/grub-mkrescue.in: Fix handling xorriso option. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ceca3fddb..028bffe5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-03 Philipp Matthias Hahn + + * util/grub-mkrescue.in: Fix handling xorriso option. + 2011-11-03 Vladimir Serbinenko * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4c96dd42b..eff77088f 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -129,7 +129,7 @@ do --xorriso) xorriso=`argument $option "$@"`; shift ;; --xorriso=*) - xorriso=`echo "${option}/" | sed 's/--xorriso=//'` ;; + xorriso=`echo "${option}" | sed 's/--xorriso=//'` ;; *) source="${source} ${option} $@"; break ;; From dbd3a32e4325699e997de191b9c265c301a888bd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:15:29 +0100 Subject: [PATCH 1331/1414] * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole disk. * grub-core/disk/lvm.c (do_lvm_scan): Likewise. --- ChangeLog | 6 ++++++ grub-core/disk/lvm.c | 4 ++-- grub-core/disk/raid.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 028bffe5c..89974cff6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-04 Vladimir Serbinenko + + * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole + disk. + * grub-core/disk/lvm.c (do_lvm_scan): Likewise. + 2011-11-03 Philipp Matthias Hahn * util/grub-mkrescue.in: Fix handling xorriso option. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 7c65db4ab..4020fc427 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -157,8 +157,8 @@ do_lvm_scan (const char *scan_for) && pv->disk->dev->id == disk->dev->id && grub_partition_get_start (pv->disk->partition) == grub_partition_get_start (disk->partition) - && grub_partition_get_len (pv->disk->partition) - == grub_partition_get_len (disk->partition)) + && grub_disk_get_size (pv->disk) + == grub_disk_get_size (disk)) { grub_disk_close (disk); return 0; diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c index 07249eabc..e4c53e73b 100644 --- a/grub-core/disk/raid.c +++ b/grub-core/disk/raid.c @@ -123,8 +123,8 @@ scan_devices (const char *arname) && m->device->dev->id == m->device->dev->id && grub_partition_get_start (m->device->partition) == grub_partition_get_start (disk->partition) - && grub_partition_get_len (m->device->partition) - == grub_partition_get_len (disk->partition)) + && grub_disk_get_size (m->device) + == grub_disk_get_size (disk)) { grub_disk_close (disk); return 0; From 8bec9a284bf2bc3f492fc1ba62b0f199998f81b2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:18:30 +0100 Subject: [PATCH 1332/1414] * include/grub/kernel.h (grub_module_header): Make type into uint32 as expected by grub-mkimage and it's more clear since there is no implicit padding. --- ChangeLog | 6 ++++++ include/grub/kernel.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 89974cff6..52bd2608d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-04 Vladimir Serbinenko + + * include/grub/kernel.h (grub_module_header): Make type into uint32 as + expected by grub-mkimage and it's more clear since there is no implicit + padding. + 2011-11-04 Vladimir Serbinenko * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 2ff6b2469..f9fc817db 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -34,7 +34,7 @@ enum struct grub_module_header { /* The type of object. */ - grub_uint8_t type; + grub_uint32_t type; /* The size of object (including this header). */ grub_uint32_t size; }; From 09e2763fb150684377d0633f0de92591f4dbe93b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:22:38 +0100 Subject: [PATCH 1333/1414] * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector for the right device. --- ChangeLog | 5 +++++ grub-core/disk/raid6_recover.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52bd2608d..f8813f259 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-04 Vladimir Serbinenko + + * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector + for the right device. + 2011-11-04 Vladimir Serbinenko * include/grub/kernel.h (grub_module_header): Make type into uint32 as diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index 25b50eb6b..54dc612ee 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -122,7 +122,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, { if ((array->members[pos].device) && (! grub_disk_read (array->members[pos].device, - array->members[i].start_sector + sector, + array->members[pos].start_sector + sector, 0, size, buf))) { grub_raid_block_xor (pbuf, buf, size); @@ -154,7 +154,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, /* One bad device */ if ((array->members[p].device) && (! grub_disk_read (array->members[p].device, - array->members[i].start_sector + sector, + array->members[p].start_sector + sector, 0, size, buf))) { grub_raid_block_xor (buf, pbuf, size); @@ -169,7 +169,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, grub_errno = GRUB_ERR_NONE; if (grub_disk_read (array->members[q].device, - array->members[i].start_sector + sector, 0, size, buf)) + array->members[q].start_sector + sector, 0, size, buf)) goto quit; grub_raid_block_xor (buf, qbuf, size); @@ -188,14 +188,14 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, } if (grub_disk_read (array->members[p].device, - array->members[i].start_sector + sector, + array->members[p].start_sector + sector, 0, size, buf)) goto quit; grub_raid_block_xor (pbuf, buf, size); if (grub_disk_read (array->members[q].device, - array->members[i].start_sector + sector, + array->members[q].start_sector + sector, 0, size, buf)) goto quit; From 11ee4389e27c9e776d598bc90f452cd3918982ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:27:50 +0100 Subject: [PATCH 1334/1414] Use a power of generator representation of GF(256) multiplication group to save space time and complexity. * grub-core/disk/raid6_recover.c (raid6_table1): Removed. (raid6_table2): Likewise. (powx): New array. (powx_inv): Likewise. (poly): New const. (grub_raid_block_mul): Replace with ... (grub_raid_block_mulx): ...this. (grub_raid6_init_table): Rewritten. (grub_raid6_recover): Use power of generator representation. --- ChangeLog | 15 +++++++ grub-core/disk/raid6_recover.c | 81 ++++++++++++---------------------- 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8813f259..b9e32f0e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2011-11-04 Vladimir Serbinenko + + Use a power of generator representation of GF(256) multiplication group + to save space time and complexity. + + * grub-core/disk/raid6_recover.c (raid6_table1): Removed. + (raid6_table2): Likewise. + (powx): New array. + (powx_inv): Likewise. + (poly): New const. + (grub_raid_block_mul): Replace with ... + (grub_raid_block_mulx): ...this. + (grub_raid6_init_table): Rewritten. + (grub_raid6_recover): Use power of generator representation. + 2011-11-04 Vladimir Serbinenko * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c index 54dc612ee..e91992547 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -26,67 +26,40 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_uint8_t raid6_table1[256][256]; -static grub_uint8_t raid6_table2[256][256]; +/* x**y. */ +static grub_uint8_t powx[255 * 2]; +/* Such an s that x**s = y */ +static int powx_inv[256]; +static const grub_uint8_t poly = 0x1d; static void -grub_raid_block_mul (grub_uint8_t mul, char *buf, int size) +grub_raid_block_mulx (int mul, char *buf, int size) { int i; grub_uint8_t *p; p = (grub_uint8_t *) buf; for (i = 0; i < size; i++, p++) - *p = raid6_table1[mul][*p]; + if (*p) + *p = powx[mul + powx_inv[*p]]; } static void grub_raid6_init_table (void) { - int i, j; + int i; - for (i = 0; i < 256; i++) - raid6_table1[i][1] = raid6_table1[1][i] = i; - - for (i = 2; i < 256; i++) - for (j = i; j < 256; j++) - { - int n; - grub_uint8_t c; - - n = i >> 1; - - c = raid6_table1[n][j]; - c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0); - if (i & 1) - c ^= j; - - raid6_table1[j][i] = raid6_table1[i][j] = c; - } - - raid6_table2[0][0] = 1; - for (i = 1; i < 256; i++) - raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2]; - - for (i = 0; i < 254; i++) - for (j = 0; j < 254; j++) - { - grub_uint8_t c, n; - int k; - - if (i == j) - continue; - - k = i - j; - if (k < 0) - k += 255; - - c = n = raid6_table2[k][k] ^ 1; - for (k = 0; k < 253; k++) - c = raid6_table1[c][n]; - - raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c]; - } + grub_uint8_t cur = 1; + for (i = 0; i < 255; i++) + { + powx[i] = cur; + powx[i + 255] = cur; + powx_inv[cur] = i; + if (cur & 0x80) + cur = (cur << 1) ^ poly; + else + cur <<= 1; + } } static grub_err_t @@ -126,7 +99,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, 0, size, buf))) { grub_raid_block_xor (pbuf, buf, size); - grub_raid_block_mul (raid6_table2[i][i], buf, size); + grub_raid_block_mulx (i, buf, size); grub_raid_block_xor (qbuf, buf, size); } else @@ -173,13 +146,13 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, goto quit; grub_raid_block_xor (buf, qbuf, size); - grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf, + grub_raid_block_mulx (255 - bad1, buf, size); } else { /* Two bad devices */ - grub_uint8_t c; + int c; if ((! array->members[p].device) || (! array->members[q].device)) { @@ -201,11 +174,11 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, grub_raid_block_xor (qbuf, buf, size); - c = raid6_table2[bad2][bad1]; - grub_raid_block_mul (c, qbuf, size); + c = (255 - bad1 + (255 - powx_inv[(powx[bad2 - bad1 + 255] ^ 1)])) % 255; + grub_raid_block_mulx (c, qbuf, size); - c = raid6_table1[raid6_table2[bad2][bad2]][c]; - grub_raid_block_mul (c, pbuf, size); + c = (bad2 + c) % 255; + grub_raid_block_mulx (c, pbuf, size); grub_raid_block_xor (pbuf, qbuf, size); grub_memcpy (buf, pbuf, size); From 95f2e86095d8349af0936a820270ecba972fa636 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:36:08 +0100 Subject: [PATCH 1335/1414] Support second redundancy strip on raidz(2,3). * grub-core/fs/zfs/zfs.c (powx): New array. (powx_inv): Likewise. (poly): New const. (xor_out): New function. (gf_mul): Likewise. (recovery): Likewise. (read_device): Use second redundancy strip. --- ChangeLog | 12 +++ grub-core/fs/zfs/zfs.c | 208 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 197 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9e32f0e0..a75ec3705 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-11-04 Vladimir Serbinenko + + Support second redundancy strip on raidz(2,3). + + * grub-core/fs/zfs/zfs.c (powx): New array. + (powx_inv): Likewise. + (poly): New const. + (xor_out): New function. + (gf_mul): Likewise. + (recovery): Likewise. + (read_device): Use second redundancy strip. + 2011-11-04 Vladimir Serbinenko Use a power of generator representation of GF(256) multiplication group diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index ef352a770..4c92425dd 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -858,6 +858,92 @@ xor (grub_uint64_t *a, const grub_uint64_t *b, grub_size_t s) *a++ ^= *b++; } +/* x**y. */ +static grub_uint8_t powx[255 * 2]; +/* Such an s that x**s = y */ +static int powx_inv[256]; +static const grub_uint8_t poly = 0x1d; + +/* perform the operation a ^= b * (x ** (known_idx * recovery_pow) ) */ +static inline void +xor_out (void *a_in, const void *b_in, grub_size_t s, + int known_idx, int recovery_pow) +{ + int add; + grub_uint8_t *a = a_in; + const grub_uint8_t *b = b_in; + + /* Simple xor. */ + if (known_idx == 0 || recovery_pow == 0) + { + xor (a_in, b_in, s); + return; + } + add = (known_idx * recovery_pow) % 255; + for (;s--; b++, a++) + if (*b) + *a ^= powx[powx_inv[*b] + add]; +} + +static inline grub_uint8_t +gf_mul (grub_uint8_t a, grub_uint8_t b) +{ + if (a == 0 || b == 0) + return 0; + return powx[powx_inv[a] + powx_inv[b]]; +} + +static inline void +recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, + const unsigned *powers, + const int *idx) +{ + /* Now we have */ + /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/ + /* Since nbufs <= 3 let's be lazy. */ + switch (nbufs) + { + /* Easy: r_0 = bufs[0] / (x << (powers[i] * idx[j])). */ + case 1: + { + int add; + grub_uint8_t *a; + if (powers[0] == 0 || idx[0] == 0) + return; + add = 255 - ((powers[0] * idx[0]) % 255); + for (a = bufs[0]; s--; a++) + if (*a) + *a = powx[powx_inv[*a] + add]; + return; + } + /* b_0 = r_0 * (x ** (powers[0] * idx[0])) + r_1 * (x ** (powers[0] * idx[1])) + b_1 = r_0 * (x ** (powers[1] * idx[0])) + r_1 * (x ** (powers[1] * idx[1])) + */ + case 2: + { + grub_uint8_t det, det_inv; + grub_uint8_t det0, det1; + unsigned i; + /* The determinant is: */ + det = (powx[(powers[0] * idx[0] + powers[1] * idx[1]) % 255] + ^ powx[(powers[0] * idx[1] + powers[1] * idx[0]) % 255]); + det_inv = powx[255 - powx_inv[det]]; + for (i = 0; i < s; i++) + { + det0 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[1]) % 255]) + ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[1]) % 255])); + det1 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[0]) % 255]) + ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[0]) % 255])); + + bufs[0][i] = gf_mul (det0, det_inv); + bufs[1][i] = gf_mul (det1, det_inv); + } + break; + } + } + +} + static grub_err_t read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_size_t len, void *buf) @@ -901,8 +987,11 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_uint32_t s, orig_s; void *orig_buf = buf; grub_size_t orig_len = len; - void *recovery_buf = NULL; - grub_size_t recovery_len = 0; + grub_uint8_t *recovery_buf[4]; + grub_size_t recovery_len[4]; + int recovery_idx[4]; + unsigned failed_devices = 0; + int idx, orig_idx; if (desc->nparity < 1 || desc->nparity > 3) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, @@ -918,6 +1007,12 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, c = 2; if (desc->nparity == 3) c = 3; + if (((len + (1 << desc->ashift) - 1) >> desc->ashift) + >= (desc->n_children - desc->nparity)) + idx = (desc->n_children - desc->nparity - 1); + else + idx = ((len + (1 << desc->ashift) - 1) >> desc->ashift) - 1; + orig_idx = idx; while (len > 0) { grub_size_t csize; @@ -945,38 +1040,84 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], csize, buf); - /* No raidz2 recovery yet. */ - if (err && recovery_len == 0) + /* No raidz3 recovery yet. */ + if (err + && failed_devices < desc->nparity + && failed_devices < 2) { - recovery_buf = buf; - recovery_len = csize; + recovery_buf[failed_devices] = buf; + recovery_len[failed_devices] = csize; + recovery_idx[failed_devices] = idx; + failed_devices++; grub_errno = err = 0; } if (err) return err; c++; + idx--; s--; buf = (char *) buf + csize; len -= csize; } - if (recovery_buf) + if (failed_devices) { - grub_err_t err; - high = grub_divmod64 ((offset >> desc->ashift) - + - ((desc->nparity == 1) - && ((offset >> (desc->ashift + 11)) & 1)), - desc->n_children, &devn); - err = read_device ((high << desc->ashift) - | (offset & ((1 << desc->ashift) - 1)), - &desc->children[devn], - recovery_len, recovery_buf); - if (err) - return err; + unsigned redundancy_pow[4]; + unsigned cur_redundancy_pow = 0; + unsigned n_redundancy = 0; + unsigned i, j; + + /* Compute mul. x**s has a period of 255. */ + if (powx[0] == 0) + { + grub_uint8_t cur = 1; + for (i = 0; i < 255; i++) + { + powx[i] = cur; + powx[i + 255] = cur; + powx_inv[cur] = i; + if (cur & 0x80) + cur = (cur << 1) ^ poly; + else + cur <<= 1; + } + } + + /* Read redundancy data. */ + for (n_redundancy = 0, cur_redundancy_pow = 0; + n_redundancy < failed_devices; + cur_redundancy_pow++) + { + grub_err_t err; + high = grub_divmod64 ((offset >> desc->ashift) + + cur_redundancy_pow + + ((desc->nparity == 1) + && ((offset >> (desc->ashift + 11)) + & 1)), + desc->n_children, &devn); + err = read_device ((high << desc->ashift) + | (offset & ((1 << desc->ashift) - 1)), + &desc->children[devn], + recovery_len[n_redundancy], + recovery_buf[n_redundancy]); + /* Ignore error if we may still have enough devices. */ + if (err && n_redundancy + desc->nparity - cur_redundancy_pow - 1 + >= failed_devices) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + if (err) + return err; + redundancy_pow[n_redundancy] = cur_redundancy_pow; + n_redundancy++; + } + /* Now xor-our the parts we already know. */ buf = orig_buf; len = orig_len; s = orig_s; + idx = orig_idx; + while (len > 0) { grub_size_t csize; @@ -985,14 +1126,35 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, if (csize > len) csize = len; - if (buf != recovery_buf) - xor (recovery_buf, buf, - csize < recovery_len ? csize : recovery_len); + for (j = 0; j < failed_devices; j++) + if (buf == recovery_buf[j]) + break; + + if (j == failed_devices) + for (j = 0; j < failed_devices; j++) + xor_out (recovery_buf[j], buf, + csize < recovery_len[j] ? csize : recovery_len[j], + idx, redundancy_pow[j]); s--; buf = (char *) buf + csize; len -= csize; - } + idx--; + } + for (i = 0; i < failed_devices + && recovery_len[i] == recovery_len[0]; + i++); + /* Since the chunks have variable length handle the last block + separately. */ + if (i != failed_devices) + { + grub_uint8_t *tmp_recovery_buf[4]; + for (j = 0; j < i; j++) + tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[j] - 1; + recovery (tmp_recovery_buf, 1, i, redundancy_pow, recovery_idx); + } + recovery (recovery_buf, recovery_len[failed_devices - 1], + failed_devices, redundancy_pow, recovery_idx); } return GRUB_ERR_NONE; } From 8622923b662282f534ee88307065bc9ded80a023 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 13:44:56 +0100 Subject: [PATCH 1336/1414] Support case-insensitive ZFS subvolumes. * grub-core/fs/zfs/zfs.c (mzap_lookup): New parameter case_insensitive. All users updated. (zap_hash): Likewise. (name_cmp): New function. (zap_leaf_array_equal): New parameter case_insensitive. All users updated. (zap_leaf_lookup): Likewise. (fzap_lookup): Likewise. (zap_lookup): Likewise. (dnode_get_path): New parameter case_insensitive. Retrieve case sensitiviness of a volume. All users updated. (dnode_get_fullpath): New parameter case_insensitive. All users updated. (grub_zfs_dir): Set info.case_insensitiveness. --- ChangeLog | 19 +++++++ grub-core/fs/zfs/zfs.c | 112 ++++++++++++++++++++++++++++++----------- 2 files changed, 101 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index a75ec3705..48c43467b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2011-11-04 Vladimir Serbinenko + + Support case-insensitive ZFS subvolumes. + + * grub-core/fs/zfs/zfs.c (mzap_lookup): New parameter case_insensitive. + All users updated. + (zap_hash): Likewise. + (name_cmp): New function. + (zap_leaf_array_equal): New parameter case_insensitive. + All users updated. + (zap_leaf_lookup): Likewise. + (fzap_lookup): Likewise. + (zap_lookup): Likewise. + (dnode_get_path): New parameter case_insensitive. Retrieve case + sensitiviness of a volume. All users updated. + (dnode_get_fullpath): New parameter case_insensitive. + All users updated. + (grub_zfs_dir): Set info.case_insensitiveness. + 2011-11-04 Vladimir Serbinenko Support second redundancy strip on raidz(2,3). diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4c92425dd..9c06574e9 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1448,7 +1448,8 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, */ static grub_err_t mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, - int objsize, char *name, grub_uint64_t * value) + int objsize, char *name, grub_uint64_t * value, + int case_insensitive) { int i, chunks; mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; @@ -1456,7 +1457,8 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, chunks = objsize / MZAP_ENT_LEN - 1; for (i = 0; i < chunks; i++) { - if (grub_strcmp (mzap_ent[i].mze_name, name) == 0) + if (case_insensitive ? (grub_strcasecmp (mzap_ent[i].mze_name, name) == 0) + : (grub_strcmp (mzap_ent[i].mze_name, name) == 0)) { *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian); return GRUB_ERR_NONE; @@ -1489,7 +1491,8 @@ mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, } static grub_uint64_t -zap_hash (grub_uint64_t salt, const char *name) +zap_hash (grub_uint64_t salt, const char *name, + int case_insensitive) { static grub_uint64_t table[256]; const grub_uint8_t *cp; @@ -1507,8 +1510,12 @@ zap_hash (grub_uint64_t salt, const char *name) } } - for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) - crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; + if (case_insensitive) + for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) + crc = (crc >> 8) ^ table[(crc ^ grub_toupper (c)) & 0xFF]; + else + for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) + crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; /* * Only use 28 bits, since we need 4 bits in the cookie for the @@ -1526,10 +1533,34 @@ zap_hash (grub_uint64_t salt, const char *name) * array_len is actual len in bytes (not encoded le_value_length). * buf is null-terminated. */ + +static inline int +name_cmp (const char *s1, const char *s2, grub_size_t n, + int case_insensitive) +{ + const char *t1 = (const char *) s1; + const char *t2 = (const char *) s2; + + if (!case_insensitive) + return grub_memcmp (t1, t2, n); + + while (n--) + { + if (grub_toupper (*t1) != grub_toupper (*t2)) + return (int) grub_toupper (*t1) - (int) grub_toupper (*t2); + + t1++; + t2++; + } + + return 0; +} + /* XXX */ static int zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, - int blksft, int chunk, int array_len, const char *buf) + int blksft, int chunk, int array_len, const char *buf, + int case_insensitive) { int bseen = 0; @@ -1541,7 +1572,8 @@ zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) return (0); - if (grub_memcmp (la->la_array, buf + bseen, toread) != 0) + if (name_cmp ((char *) la->la_array, buf + bseen, toread, + case_insensitive) != 0) break; chunk = grub_zfs_to_cpu16 (la->la_next, endian); bseen += toread; @@ -1582,7 +1614,8 @@ zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, static grub_err_t zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, grub_uint64_t h, - const char *name, grub_uint64_t * value) + const char *name, grub_uint64_t * value, + int case_insensitive) { grub_uint16_t chunk; struct zap_leaf_entry *le; @@ -1614,7 +1647,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, if (zap_leaf_array_equal (l, endian, blksft, grub_zfs_to_cpu16 (le->le_name_chunk,endian), grub_zfs_to_cpu16 (le->le_name_length, endian), - name)) + name, case_insensitive)) { struct zap_leaf_array *la; @@ -1658,7 +1691,8 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) /* XXX */ static grub_err_t fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, - char *name, grub_uint64_t * value, struct grub_zfs_data *data) + char *name, grub_uint64_t * value, struct grub_zfs_data *data, + int case_insensitive) { void *l; grub_uint64_t hash, idx, blkid; @@ -1671,7 +1705,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, if (err) return err; - hash = zap_hash (zap->zap_salt, name); + hash = zap_hash (zap->zap_salt, name, case_insensitive); /* get block id from index */ if (zap->zap_ptrtbl.zt_numblks != 0) @@ -1687,7 +1721,8 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, if (err) return err; - err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value); + err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value, + case_insensitive); grub_free (l); return err; } @@ -1806,7 +1841,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, */ static grub_err_t zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, - struct grub_zfs_data *data) + struct grub_zfs_data *data, int case_insensitive) { grub_uint64_t block_type; int size; @@ -1829,7 +1864,8 @@ zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, if (block_type == ZBT_MICRO) { grub_dprintf ("zfs", "micro zap\n"); - err = (mzap_lookup (zapbuf, endian, size, name, val)); + err = mzap_lookup (zapbuf, endian, size, name, val, + case_insensitive); grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; @@ -1838,7 +1874,8 @@ zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ - err = (fzap_lookup (zap_dnode, zapbuf, name, val, data)); + err = fzap_lookup (zap_dnode, zapbuf, name, val, data, + case_insensitive); grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; @@ -1964,9 +2001,9 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, */ static grub_err_t dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, - struct grub_zfs_data *data) + struct grub_zfs_data *data, int *case_insensitive) { - grub_uint64_t objnum, version; + grub_uint64_t objnum, version, insensitivity; char *cname, ch; grub_err_t err = GRUB_ERR_NONE; char *path, *path_buf; @@ -1991,19 +2028,31 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, return err; } - err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, data); + err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, + data, 0); if (err) { grub_free (dn_new); return err; } + if (version > ZPL_VERSION) { grub_free (dn_new); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); } - - err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data); + + err = zap_lookup (&(dnode_path->dn), "casesensitivity", &insensitivity, + data, 0); + if (err == GRUB_ERR_FILE_NOT_FOUND) + { + grub_errno = GRUB_ERR_NONE; + insensitivity = 0; + } + if (case_insensitive) + *case_insensitive = insensitivity; + + err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data, 0); if (err) { grub_free (dn_new); @@ -2064,7 +2113,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (path_buf); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } - err = zap_lookup (&(dnode_path->dn), cname, &objnum, data); + err = zap_lookup (&(dnode_path->dn), cname, &objnum, data, insensitivity); if (err) break; @@ -2296,7 +2345,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, grub_dprintf ("zfs", "alive\n"); - err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data); + err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data, 0); if (err) return err; @@ -2331,7 +2380,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, if (err) return err; - err = zap_lookup (mdn, cname, &objnum, data); + err = zap_lookup (mdn, cname, &objnum, data, 0); if (err) return err; @@ -2374,7 +2423,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) static grub_err_t dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_uint64_t *mdnobj, dnode_end_t * dn, int *isfs, - struct grub_zfs_data *data) + struct grub_zfs_data *data, int *case_insensitive) { char *fsname, *snapname; const char *ptr_at, *filename; @@ -2452,7 +2501,7 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, err = dnode_get (&(data->mos), snapobj, DMU_OT_DSL_DS_SNAP_MAP, mdn, data); if (!err) - err = zap_lookup (mdn, snapname, &headobj, data); + err = zap_lookup (mdn, snapname, &headobj, data, 0); if (!err) err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); if (err) @@ -2476,7 +2525,7 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_free (snapname); return GRUB_ERR_NONE; } - err = dnode_get_path (mdn, filename, dn, data); + err = dnode_get_path (mdn, filename, dn, data, case_insensitive); grub_free (fsname); grub_free (snapname); return err; @@ -2916,7 +2965,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) return grub_errno; err = dnode_get_fullpath (fsfilename, &(data->mdn), 0, - &(data->dnode), &isfs, data); + &(data->dnode), &isfs, data, NULL); if (err) { zfs_unmount (data); @@ -3080,7 +3129,7 @@ grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, return grub_errno; err = dnode_get_fullpath (fsfilename, &(data->mdn), mdnobj, - &(data->dnode), &isfs, data); + &(data->dnode), &isfs, data, NULL); zfs_unmount (data); return err; } @@ -3118,7 +3167,7 @@ fill_fs_info (struct grub_dirhook_info *info, return; } - err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data); + err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data, 0); if (err) { grub_dprintf ("zfs", "failed here\n"); @@ -3175,6 +3224,7 @@ grub_zfs_dir (grub_device_t device, const char *path, struct grub_zfs_data *data; grub_err_t err; int isfs; + int case_insensitive = 0; auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val); @@ -3219,6 +3269,7 @@ grub_zfs_dir (grub_device_t device, const char *path, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); info.mtimeset = 1; info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + info.case_insensitive = case_insensitive; } if (dn.dn.dn_bonustype == DMU_OT_ZNODE) @@ -3273,7 +3324,8 @@ grub_zfs_dir (grub_device_t device, const char *path, data = zfs_mount (device); if (! data) return grub_errno; - err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data); + err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data, + &case_insensitive); if (err) { zfs_unmount (data); From c2fd16cacb3edf41efe3b0ffa266c54c8af9af6f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 4 Nov 2011 15:19:23 +0100 Subject: [PATCH 1337/1414] Support third redundancy strip on raidz3. * grub-core/fs/zfs/zfs.c (recovery): Add Gauss for general case. Return error on singularity. All users updated. (read_device): Don't stop on 3rd failure on raidz3. --- ChangeLog | 8 +++ grub-core/fs/zfs/zfs.c | 140 +++++++++++++++++++++++++++++++++-------- 2 files changed, 123 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48c43467b..70dc4e4f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-04 Vladimir Serbinenko + + Support third redundancy strip on raidz3. + + * grub-core/fs/zfs/zfs.c (recovery): Add Gauss for general case. + Return error on singularity. All users updated. + (read_device): Don't stop on 3rd failure on raidz3. + 2011-11-04 Vladimir Serbinenko Support case-insensitive ZFS subvolumes. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9c06574e9..f892290a1 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -893,14 +893,15 @@ gf_mul (grub_uint8_t a, grub_uint8_t b) return powx[powx_inv[a] + powx_inv[b]]; } -static inline void +static inline grub_err_t recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, const unsigned *powers, const int *idx) { + grub_dprintf ("zfs", "recovering %u bufers\n", nbufs); /* Now we have */ /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/ - /* Since nbufs <= 3 let's be lazy. */ + /* Let's invert the matrix in question. */ switch (nbufs) { /* Easy: r_0 = bufs[0] / (x << (powers[i] * idx[j])). */ @@ -909,39 +910,126 @@ recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, int add; grub_uint8_t *a; if (powers[0] == 0 || idx[0] == 0) - return; + return GRUB_ERR_NONE; add = 255 - ((powers[0] * idx[0]) % 255); for (a = bufs[0]; s--; a++) if (*a) *a = powx[powx_inv[*a] + add]; - return; + return GRUB_ERR_NONE; } - /* b_0 = r_0 * (x ** (powers[0] * idx[0])) + r_1 * (x ** (powers[0] * idx[1])) - b_1 = r_0 * (x ** (powers[1] * idx[0])) + r_1 * (x ** (powers[1] * idx[1])) - */ + /* Case 2x2: Let's use the determinant formula. */ case 2: { grub_uint8_t det, det_inv; - grub_uint8_t det0, det1; + grub_uint8_t matrixinv[2][2]; unsigned i; /* The determinant is: */ det = (powx[(powers[0] * idx[0] + powers[1] * idx[1]) % 255] ^ powx[(powers[0] * idx[1] + powers[1] * idx[0]) % 255]); + if (det == 0) + return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix"); det_inv = powx[255 - powx_inv[det]]; + matrixinv[0][0] = gf_mul (powx[(powers[1] * idx[1]) % 255], det_inv); + matrixinv[1][1] = gf_mul (powx[(powers[0] * idx[0]) % 255], det_inv); + matrixinv[0][1] = gf_mul (powx[(powers[0] * idx[1]) % 255], det_inv); + matrixinv[1][0] = gf_mul (powx[(powers[1] * idx[0]) % 255], det_inv); for (i = 0; i < s; i++) { - det0 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[1]) % 255]) - ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[1]) % 255])); - det1 = (gf_mul (bufs[0][i], powx[(powers[1] * idx[0]) % 255]) - ^ gf_mul (bufs[1][i], powx[(powers[0] * idx[0]) % 255])); + grub_uint8_t b0, b1; + b0 = bufs[0][i]; + b1 = bufs[1][i]; - bufs[0][i] = gf_mul (det0, det_inv); - bufs[1][i] = gf_mul (det1, det_inv); + bufs[0][i] = (gf_mul (b0, matrixinv[0][0]) + ^ gf_mul (b1, matrixinv[0][1])); + bufs[1][i] = (gf_mul (b0, matrixinv[1][0]) + ^ gf_mul (b1, matrixinv[1][1])); } - break; + return GRUB_ERR_NONE; } - } - + /* Otherwise use Gauss. */ + default: + { + grub_uint8_t matrix1[nbufs][nbufs], matrix2[nbufs][nbufs]; + int i, j, k; + + for (i = 0; i < nbufs; i++) + for (j = 0; j < nbufs; j++) + matrix1[i][j] = powx[(powers[i] * idx[j]) % 255]; + for (i = 0; i < nbufs; i++) + for (j = 0; j < nbufs; j++) + matrix2[i][j] = 0; + for (i = 0; i < nbufs; i++) + matrix2[i][i] = 1; + + for (i = 0; i < nbufs; i++) + { + grub_uint8_t mul; + for (j = i; j < nbufs; j++) + if (matrix1[i][j]) + break; + if (j == nbufs) + return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix"); + if (j != i) + { + int xchng; + xchng = j; + for (j = 0; j < nbufs; j++) + { + grub_uint8_t t; + t = matrix1[xchng][j]; + matrix1[xchng][j] = matrix1[i][j]; + matrix1[i][j] = t; + } + for (j = 0; j < nbufs; j++) + { + grub_uint8_t t; + t = matrix2[xchng][j]; + matrix2[xchng][j] = matrix2[i][j]; + matrix2[i][j] = t; + } + } + mul = powx[255 - powx_inv[matrix1[i][i]]]; + for (j = 0; j < nbufs; j++) + matrix1[i][j] = gf_mul (matrix1[i][j], mul); + for (j = 0; j < nbufs; j++) + matrix2[i][j] = gf_mul (matrix2[i][j], mul); + for (j = i + 1; j < nbufs; j++) + { + mul = matrix1[j][i]; + for (k = 0; k < nbufs; k++) + matrix1[j][k] ^= gf_mul (matrix1[i][k], mul); + for (k = 0; k < nbufs; k++) + matrix2[j][k] ^= gf_mul (matrix2[i][k], mul); + } + } + for (i = nbufs - 1; i >= 0; i--) + { + for (j = 0; j < i; j++) + { + grub_uint8_t mul; + mul = matrix1[j][i]; + for (k = 0; k < nbufs; k++) + matrix1[j][k] ^= gf_mul (matrix1[i][k], mul); + for (k = 0; k < nbufs; k++) + matrix2[j][k] ^= gf_mul (matrix2[i][k], mul); + } + } + + for (i = 0; i < (int) s; i++) + { + grub_uint8_t b[nbufs]; + for (j = 0; j < nbufs; j++) + b[j] = bufs[j][i]; + for (j = 0; j < nbufs; j++) + { + bufs[j][i] = 0; + for (k = 0; k < nbufs; k++) + bufs[j][i] ^= gf_mul (matrix2[j][k], b[k]); + } + } + return GRUB_ERR_NONE; + } + } } static grub_err_t @@ -1040,10 +1128,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, | (offset & ((1 << desc->ashift) - 1)), &desc->children[devn], csize, buf); - /* No raidz3 recovery yet. */ - if (err - && failed_devices < desc->nparity - && failed_devices < 2) + if (err && failed_devices < desc->nparity) { recovery_buf[failed_devices] = buf; recovery_len[failed_devices] = csize; @@ -1066,6 +1151,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, unsigned cur_redundancy_pow = 0; unsigned n_redundancy = 0; unsigned i, j; + grub_err_t err; /* Compute mul. x**s has a period of 255. */ if (powx[0] == 0) @@ -1088,7 +1174,6 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, n_redundancy < failed_devices; cur_redundancy_pow++) { - grub_err_t err; high = grub_divmod64 ((offset >> desc->ashift) + cur_redundancy_pow + ((desc->nparity == 1) @@ -1151,10 +1236,15 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, grub_uint8_t *tmp_recovery_buf[4]; for (j = 0; j < i; j++) tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[j] - 1; - recovery (tmp_recovery_buf, 1, i, redundancy_pow, recovery_idx); + err = recovery (tmp_recovery_buf, 1, i, redundancy_pow, + recovery_idx); + if (err) + return err; } - recovery (recovery_buf, recovery_len[failed_devices - 1], - failed_devices, redundancy_pow, recovery_idx); + err = recovery (recovery_buf, recovery_len[failed_devices - 1], + failed_devices, redundancy_pow, recovery_idx); + if (err) + return err; } return GRUB_ERR_NONE; } From 455377d93d6feb32f661d48adeea62fa4dfe4143 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Nov 2011 12:15:07 +0100 Subject: [PATCH 1338/1414] * util/grub-install.in: Fix condition for config_opt. --- ChangeLog | 4 ++++ util/grub-install.in | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70dc4e4f3..75cac6a4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-05 Vladimir Serbinenko + + * util/grub-install.in: Fix condition for config_opt. + 2011-11-04 Vladimir Serbinenko Support third redundancy strip on raidz3. diff --git a/util/grub-install.in b/util/grub-install.in index fdbe10e76..26a2523f8 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -577,10 +577,9 @@ else for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg" done + config_opt="-c ${grubdir}/load.cfg " fi - config_opt="-c ${grubdir}/load.cfg " - prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1 fi From c7ba4f6984a646e8d9f5647fe94fef756cd59f42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Nov 2011 14:47:25 +0100 Subject: [PATCH 1339/1414] Support BtrFS embedding. * grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. (grub_btrfs_fs) [GRUB_UTIL]: Set embed. * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. * util/grub-setup.c (setup): Use fs embedding if available. Add additional sanity check. --- ChangeLog | 10 ++++++++++ grub-core/fs/btrfs.c | 30 ++++++++++++++++++++++++++++++ include/grub/fs.h | 9 +++++++++ util/grub-setup.c | 32 +++++++++++++++++++++++++------- 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 75cac6a4e..8c125fa97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-05 Vladimir Serbinenko + + Support BtrFS embedding. + + * grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. + (grub_btrfs_fs) [GRUB_UTIL]: Set embed. + * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. + * util/grub-setup.c (setup): Use fs embedding if available. + Add additional sanity check. + 2011-11-05 Vladimir Serbinenko * util/grub-install.in: Fix condition for config_opt. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 16e034661..3dc680034 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1596,6 +1596,35 @@ grub_btrfs_label (grub_device_t device, char **label) return grub_errno; } +#ifdef GRUB_UTIL +static grub_err_t +grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), + unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) +{ + unsigned i; + + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "BtrFS curently supports only PC-BIOS embedding"); + + if (64 * 2 - 1 < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "Your core.img is unusually large. " + "It won't fit in the embedding area."); + + *nsectors = 64 * 2 - 1; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = i + 1; + + return GRUB_ERR_NONE; +} +#endif + static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .dir = grub_btrfs_dir, @@ -1605,6 +1634,7 @@ static struct grub_fs grub_btrfs_fs = { .uuid = grub_btrfs_uuid, .label = grub_btrfs_label, #ifdef GRUB_UTIL + .embed = grub_btrfs_embed, .reserved_first_sector = 1, #endif }; diff --git a/include/grub/fs.h b/include/grub/fs.h index 2c39332a9..dd274e151 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -25,6 +25,10 @@ #include #include +/* For embedding types. */ +#ifdef GRUB_UTIL +#include +#endif /* Forward declaration is required, because of mutual reference. */ struct grub_file; @@ -74,6 +78,11 @@ struct grub_fs grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); #ifdef GRUB_UTIL + /* Determine sectors available for embedding. */ + grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors); + /* Whether this filesystem reserves first sector for DOS-style boot. */ int reserved_first_sector; #endif diff --git a/util/grub-setup.c b/util/grub-setup.c index 99de26f76..d3f6fe8b8 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -408,29 +408,44 @@ setup (const char *dir, free (tmp_img); - if (! dest_partmap) + if (! dest_partmap && ! fs) { grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); goto unable_to_embed; } - if (multiple_partmaps || fs) + if (multiple_partmaps || (dest_partmap && fs)) { grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet.")); goto unable_to_embed; } - if (!dest_partmap->embed) + if (dest_partmap && !dest_partmap->embed) { grub_util_warn ("Partition style '%s' doesn't support embeding", dest_partmap->name); goto unable_to_embed; } + if (fs && !fs->embed) + { + grub_util_warn ("File system '%s' doesn't support embeding", + fs->name); + goto unable_to_embed; + } + nsec = core_sectors; - err = dest_partmap->embed (dest_dev->disk, &nsec, - GRUB_EMBED_PCBIOS, §ors); - if (nsec > 2 * core_sectors) - nsec = 2 * core_sectors; + if (dest_partmap) + err = dest_partmap->embed (dest_dev->disk, &nsec, + GRUB_EMBED_PCBIOS, §ors); + else + err = fs->embed (dest_dev, &nsec, + GRUB_EMBED_PCBIOS, §ors); + if (!err && nsec < core_sectors) + { + err = grub_error (GRUB_ERR_OUT_OF_RANGE, + "Your embedding area is unusually small. " + "core.img won't fit in it."); + } if (err) { @@ -439,6 +454,9 @@ setup (const char *dir, goto unable_to_embed; } + if (nsec > 2 * core_sectors) + nsec = 2 * core_sectors; + /* Clean out the blocklists. */ block = first_block; while (block->len) From b632b404e08a3b04f5264fd688354934bf7bd3e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Nov 2011 14:50:53 +0100 Subject: [PATCH 1340/1414] Support zle compression on ZFS. * grub-core/fs/zfs/zfs.c (zle_decompress): New function. (decomp_table): Add zle. * include/grub/zfs/zio.h (zio_compress): Add zle. --- ChangeLog | 8 ++++++++ grub-core/fs/zfs/zfs.c | 34 ++++++++++++++++++++++++++++++++++ include/grub/zfs/zio.h | 1 + 3 files changed, 43 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8c125fa97..9e9f315f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-05 Vladimir Serbinenko + + Support zle compression on ZFS. + + * grub-core/fs/zfs/zfs.c (zle_decompress): New function. + (decomp_table): Add zle. + * include/grub/zfs/zio.h (zio_compress): Add zle. + 2011-11-05 Vladimir Serbinenko Support BtrFS embedding. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index f892290a1..9658dea0d 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -199,6 +199,39 @@ zlib_decompress (void *s, void *d, return GRUB_ERR_NONE; } +static grub_err_t +zle_decompress (void *s, void *d, + grub_size_t slen, grub_size_t dlen) +{ + grub_uint8_t *iptr, *optr; + grub_size_t clen; + for (iptr = s, optr = d; iptr < (grub_uint8_t *) s + slen + && optr < (grub_uint8_t *) d + dlen;) + { + if (*iptr & 0x80) + clen = ((*iptr) & 0x7f) + 0x41; + else + clen = ((*iptr) & 0x3f) + 1; + if ((grub_ssize_t) clen > (grub_uint8_t *) d + dlen - optr) + clen = (grub_uint8_t *) d + dlen - optr; + if (*iptr & 0x40 || *iptr & 0x80) + { + grub_memset (optr, 0, clen); + iptr++; + optr += clen; + continue; + } + if ((grub_ssize_t) clen > (grub_uint8_t *) s + slen - iptr - 1) + clen = (grub_uint8_t *) s + slen - iptr - 1; + grub_memcpy (optr, iptr + 1, clen); + optr += clen; + iptr += clen + 1; + } + if (optr < (grub_uint8_t *) d + dlen) + grub_memset (optr, 0, (grub_uint8_t *) d + dlen - optr); + return GRUB_ERR_NONE; +} + static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ @@ -214,6 +247,7 @@ static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"gzip-7", zlib_decompress}, /* ZIO_COMPRESS_GZIP7 */ {"gzip-8", zlib_decompress}, /* ZIO_COMPRESS_GZIP8 */ {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ + {"zle", zle_decompress}, /* ZIO_COMPRESS_ZLE */ }; static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 3dafb4028..29451593f 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -86,6 +86,7 @@ enum zio_compress { ZIO_COMPRESS_GZIP7, ZIO_COMPRESS_GZIP8, ZIO_COMPRESS_GZIP9, + ZIO_COMPRESS_ZLE, ZIO_COMPRESS_FUNCTIONS }; From 1bc7cc1b4d850e2ed4d0562798a41f411623c1e1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 13:18:27 +0100 Subject: [PATCH 1341/1414] First part of zfs-crypto. CCM support with 0-filled keys --- grub-core/fs/zfs/zfs.c | 422 ++++++++++++++++++++++++++++++------- grub-core/lib/crypto.c | 5 +- include/grub/crypto.h | 4 +- include/grub/zfs/dmu.h | 1 + include/grub/zfs/dsl_dir.h | 4 +- include/grub/zfs/zio.h | 1 + 6 files changed, 360 insertions(+), 77 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9658dea0d..9da4d70e2 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -52,6 +52,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -124,6 +125,23 @@ static grub_dl_t my_mod; #define NBBY 8 #endif +enum grub_zfs_algo + { + GRUB_ZFS_ALGO_CCM, + GRUB_ZFS_ALGO_GCM, + }; + +struct grub_zfs_key +{ + grub_uint64_t algo; + grub_uint8_t enc_nonce[13]; + grub_uint8_t unused[3]; + grub_uint8_t enc_key[48]; + grub_uint8_t unknown_purpose_nonce[13]; + grub_uint8_t unused2[3]; + grub_uint8_t unknown_purpose_key[48]; +}; + extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, @@ -161,6 +179,14 @@ struct grub_zfs_device_desc int original; }; +struct subvolume +{ + dnode_end_t mdn; + grub_uint64_t obj; + grub_uint64_t case_insensitive; + grub_crypto_cipher_handle_t cipher; +}; + struct grub_zfs_data { /* cache for a file block of the currently zfs_open()-ed file */ @@ -176,8 +202,8 @@ struct grub_zfs_data grub_zfs_endian_t dnode_endian; dnode_end_t mos; - dnode_end_t mdn; dnode_end_t dnode; + struct subvolume subvol; struct grub_zfs_device_desc *devices_attached; unsigned n_devices_attached; @@ -292,6 +318,7 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { {fletcher_4, 1, 0, "fletcher4"}, {zio_checksum_SHA256, 1, 0, "SHA256"}, {NULL, 0, 0, "zilog2"}, + {zio_checksum_SHA256, 1, 0, "SHA256+MAC"}, }; /* @@ -302,7 +329,8 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { */ static grub_err_t zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, - grub_zfs_endian_t endian, char *buf, grub_size_t size) + grub_zfs_endian_t endian, + char *buf, grub_size_t size) { zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; zio_checksum_info_t *ci = &zio_checksum_table[checksum]; @@ -312,7 +340,7 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, { grub_dprintf ("zfs", "unknown checksum function %d\n", checksum); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unknown checksum function %d", checksum); + "unknown checksum function %d", checksum); } if (ci->ci_eck) @@ -326,10 +354,8 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, else ci->ci_func (buf, size, endian, &actual_cksum); - if ((actual_cksum.zc_word[0] != zc.zc_word[0]) - || (actual_cksum.zc_word[1] != zc.zc_word[1]) - || (actual_cksum.zc_word[2] != zc.zc_word[2]) - || (actual_cksum.zc_word[3] != zc.zc_word[3])) + if (grub_memcmp (&actual_cksum, &zc, + checksum != ZIO_CHECKSUM_SHA256_MAC ? 32 : 20) != 0) { grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name); grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n", @@ -1410,16 +1436,67 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, return err; } +static grub_err_t +grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned l, unsigned m) +{ + grub_uint8_t iv[16]; + grub_uint8_t mul[16]; + grub_uint32_t mac[4]; + unsigned i, j; + grub_err_t err; + + grub_memcpy (iv + 1, nonce, 15 - l); + + iv[0] = (l - 1) | (((m-2) / 2) << 3); + for (j = 0; j < l; j++) + iv[15 - j] = psize >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); + if (err) + return err; + + iv[0] = l - 1; + + for (i = 0; i < (psize + 15) / 16; i++) + { + grub_size_t csize; + csize = 16; + if (csize > psize - 16 * i) + csize = psize - 16 * i; + for (j = 0; j < l; j++) + iv[15 - j] = (i + 1) >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); + grub_crypto_xor (mac, mac, out + 16 * i, csize); + err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); + if (err) + return err; + } + for (j = 0; j < l; j++) + iv[15 - j] = 0; + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + if (mac_out) + grub_crypto_xor (mac_out, mac, mul, m); + return GRUB_ERR_NONE; +} + /* * Read in a block of data, verify its checksum, decompress if needed, * and put the uncompressed data in buf. */ static grub_err_t -zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, +zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, grub_size_t *size, struct grub_zfs_data *data) { grub_size_t lsize, psize; - unsigned int comp; + unsigned int comp, encrypted; char *compbuf = NULL; grub_err_t err; zio_cksum_t zc = bp->blk_cksum; @@ -1429,6 +1506,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0xff; + encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3); lsize = (BP_IS_HOLE(bp) ? 0 : (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) << SPA_MINBLOCKSHIFT)); @@ -1447,7 +1525,7 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, if (comp != ZIO_COMPRESS_OFF) { - compbuf = grub_malloc (psize); + compbuf = grub_malloc (ALIGN_UP (psize, 16)); if (! compbuf) return grub_errno; } @@ -1462,8 +1540,10 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, *buf = NULL; return err; } + grub_memset (compbuf, 0, ALIGN_UP (psize, 16) - psize); - err = zio_checksum_verify (zc, checksum, endian, compbuf, psize); + err = zio_checksum_verify (zc, checksum, endian, + compbuf, psize); if (err) { grub_dprintf ("zfs", "incorrect checksum\n"); @@ -1472,6 +1552,45 @@ zio_read (blkptr_t * bp, grub_zfs_endian_t endian, void **buf, return err; } + if (encrypted) + { + grub_uint32_t mac[4]; + unsigned i; + grub_uint32_t sw[4]; + + grub_memcpy (sw, &(bp)->blk_dva[encrypted], 16); + for (i = 0; i < 4; i++) + sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); + + if (!data->subvol.cipher) + { + grub_free (compbuf); + *buf = NULL; + return grub_error (GRUB_ERR_ACCESS_DENIED, + "no decryption key available");; + } + err = grub_ccm_decrypt (data->subvol.cipher, + (grub_uint8_t *) compbuf, + (grub_uint8_t *) compbuf, + psize, mac, + sw + 1, 3, 12); + if (err) + { + grub_free (compbuf); + *buf = NULL; + return err; + } + + for (i = 0; i < 3; i++) + if (grub_zfs_to_cpu32 (((grub_uint32_t *) &zc + 5)[i], endian) + != grub_be_to_cpu32 (mac[i])) + { + grub_free (compbuf); + *buf = NULL; + return grub_error (GRUB_ERR_BAD_FS, "MAC verification failed"); + } + } + if (comp != ZIO_COMPRESS_OFF) { *buf = grub_malloc (lsize); @@ -1572,7 +1691,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, */ static grub_err_t mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, - int objsize, char *name, grub_uint64_t * value, + int objsize, const char *name, grub_uint64_t * value, int case_insensitive) { int i, chunks; @@ -1799,8 +1918,8 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); - if (zap->zap_flags != 0) - return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags"); + /* if (zap->zap_flags != 0) + return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags");*/ if (zap->zap_salt == 0) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); @@ -1854,9 +1973,11 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, /* XXX */ static int fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, - int NESTED_FUNC_ATTR (*hook) (const char *name, - grub_uint64_t val), - struct grub_zfs_data *data) + int NESTED_FUNC_ATTR (*hook) (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize), + struct grub_zfs_data *data) { zap_leaf_phys_t *l; void *l_in; @@ -1918,9 +2039,9 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, for (chunk = 0; chunk < ZAP_LEAF_NUMCHUNKS (blksft); chunk++) { char *buf; - struct zap_leaf_array *la; struct zap_leaf_entry *le; - grub_uint64_t val; + char *val; + grub_size_t val_length; le = ZAP_LEAF_ENTRY (l, blksft, chunk); /* Verify the chunk entry */ @@ -1940,24 +2061,28 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, } buf[le->le_name_length] = 0; - if (le->le_int_size != 8 - || grub_zfs_to_cpu16 (le->le_value_length, endian) != 1) - continue; + val_length = ((int) le->le_value_length + * (int) le->le_int_size); + val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian)); + if (zap_leaf_array_get (l, endian, blksft, + grub_zfs_to_cpu16 (le->le_value_chunk, + endian), + val_length, val)) + { + grub_free (buf); + grub_free (val); + continue; + } - /* get the uint64_t property value */ - la = &ZAP_LEAF_CHUNK (l, blksft, - grub_zfs_to_cpu16 (le->le_value_chunk, - endian)).l_array; - val = grub_be_to_cpu64 (la->la_array64); - if (hook (buf, val)) + if (hook (buf, val, le->le_value_length, le->le_int_size)) return 1; grub_free (buf); + grub_free (val); } } return 0; } - /* * Read in the data of a zap object and find the value for a matching * property name. @@ -2008,9 +2133,68 @@ zap_lookup (dnode_end_t * zap_dnode, char *name, grub_uint64_t * val, return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); } +static int +zap_iterate_u64 (dnode_end_t * zap_dnode, + int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_uint64_t val), + struct grub_zfs_data *data) +{ + grub_uint64_t block_type; + int size; + void *zapbuf; + grub_err_t err; + int ret; + grub_zfs_endian_t endian; + + auto int NESTED_FUNC_ATTR transform (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + + int NESTED_FUNC_ATTR transform (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize) + { + if (elemsize != sizeof (grub_uint64_t) || nelem != 1) + return 0; + return hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in)); + } + + /* Read in the first block of the zap object data. */ + size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; + err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); + if (err) + return 0; + block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); + + grub_dprintf ("zfs", "zap iterate\n"); + + if (block_type == ZBT_MICRO) + { + grub_dprintf ("zfs", "micro zap\n"); + ret = mzap_iterate (zapbuf, endian, size, hook); + grub_free (zapbuf); + return ret; + } + else if (block_type == ZBT_HEADER) + { + grub_dprintf ("zfs", "fat zap\n"); + /* this is a fat zap */ + ret = fzap_iterate (zap_dnode, zapbuf, transform, data); + grub_free (zapbuf); + return ret; + } + grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + return 0; +} + static int zap_iterate (dnode_end_t * zap_dnode, - int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t val), + int NESTED_FUNC_ATTR (*hook) (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize), struct grub_zfs_data *data) { grub_uint64_t block_type; @@ -2031,12 +2215,10 @@ zap_iterate (dnode_end_t * zap_dnode, if (block_type == ZBT_MICRO) { - grub_dprintf ("zfs", "micro zap\n"); - ret = mzap_iterate (zapbuf, endian, size, hook); - grub_free (zapbuf); - return ret; + grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected"); + return 0; } - else if (block_type == ZBT_HEADER) + if (block_type == ZBT_HEADER) { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ @@ -2124,10 +2306,10 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, * */ static grub_err_t -dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, - struct grub_zfs_data *data, int *case_insensitive) +dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, + struct grub_zfs_data *data) { - grub_uint64_t objnum, version, insensitivity; + grub_uint64_t objnum, version; char *cname, ch; grub_err_t err = GRUB_ERR_NONE; char *path, *path_buf; @@ -2144,7 +2326,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, dn_new->next = 0; dnode_path = root = dn_new; - err = dnode_get (mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + err = dnode_get (&subvol->mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, &(dnode_path->dn), data); if (err) { @@ -2166,15 +2348,14 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); } - err = zap_lookup (&(dnode_path->dn), "casesensitivity", &insensitivity, + err = zap_lookup (&(dnode_path->dn), "casesensitivity", + &subvol->case_insensitive, data, 0); if (err == GRUB_ERR_FILE_NOT_FOUND) { grub_errno = GRUB_ERR_NONE; - insensitivity = 0; + subvol->case_insensitive = 0; } - if (case_insensitive) - *case_insensitive = insensitivity; err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data, 0); if (err) @@ -2183,7 +2364,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, return err; } - err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); + err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data); if (err) { grub_free (dn_new); @@ -2237,7 +2418,8 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, grub_free (path_buf); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } - err = zap_lookup (&(dnode_path->dn), cname, &objnum, data, insensitivity); + err = zap_lookup (&(dnode_path->dn), cname, &objnum, + data, subvol->case_insensitive); if (err) break; @@ -2251,7 +2433,7 @@ dnode_get_path (dnode_end_t * mdn, const char *path_in, dnode_end_t * dn, dnode_path = dn_new; objnum = ZFS_DIRENT_OBJ (objnum); - err = dnode_get (mdn, objnum, 0, &(dnode_path->dn), data); + err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data); if (err) break; @@ -2545,15 +2727,93 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) } static grub_err_t -dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, - grub_uint64_t *mdnobj, dnode_end_t * dn, int *isfs, - struct grub_zfs_data *data, int *case_insensitive) +dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + dnode_end_t * dn, int *isfs, + struct grub_zfs_data *data) { char *fsname, *snapname; const char *ptr_at, *filename; grub_uint64_t headobj; + grub_uint64_t keychainobj; grub_err_t err; + auto int NESTED_FUNC_ATTR iterate_zap_key (const char *name, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + int NESTED_FUNC_ATTR iterate_zap_key (const char *name __attribute__ ((unused)), + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize) + { + const struct grub_zfs_key *key = val_in; + grub_crypto_cipher_handle_t cipher; + grub_uint8_t wrapping_key[32], decrypted[32], mac[32]; + unsigned keylen; + + if (elemsize != 1 || nelem != sizeof (*key)) + { + grub_dprintf ("zfs", "Unexpected key length %" PRIuGRUB_SIZE + " x %" PRIuGRUB_SIZE "\n", nelem, elemsize); + return 0; + } + + if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) + == 0) + keylen = 16; + else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) + keylen = 24; + else + keylen = 32; + + grub_memset (wrapping_key, 0, sizeof (wrapping_key)); + + cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (cipher, wrapping_key, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + return 0; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + return 0; + } + subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!subvol->cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + + return 0; + } + ptr_at = grub_strchr (fullpath, '@'); if (! ptr_at) { @@ -2605,29 +2865,47 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_head_dataset_obj, dn->endian); - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); - err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &subvol->mdn, + data); if (err) { grub_free (fsname); grub_free (snapname); return err; } - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); + + keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); + if (keychainobj) + { + dnode_end_t keychain_dn; + err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, + &keychain_dn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + zap_iterate (&keychain_dn, iterate_zap_key, data); + } + if (snapname) { grub_uint64_t snapobj; - snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_snapnames_zapobj, mdn->endian); + snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&subvol->mdn.dn))->ds_snapnames_zapobj, subvol->mdn.endian); err = dnode_get (&(data->mos), snapobj, - DMU_OT_DSL_DS_SNAP_MAP, mdn, data); + DMU_OT_DSL_DS_SNAP_MAP, &subvol->mdn, data); if (!err) - err = zap_lookup (mdn, snapname, &headobj, data, 0); + err = zap_lookup (&subvol->mdn, snapname, &headobj, data, 0); if (!err) - err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, mdn, data); + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, + &subvol->mdn, data); if (err) { grub_free (fsname); @@ -2636,12 +2914,11 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, } } - if (mdnobj) - *mdnobj = headobj; + subvol->obj = headobj; - make_mdn (mdn, data); + make_mdn (&subvol->mdn, data); - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); + grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); if (*isfs) { @@ -2649,7 +2926,7 @@ dnode_get_fullpath (const char *fullpath, dnode_end_t * mdn, grub_free (snapname); return GRUB_ERR_NONE; } - err = dnode_get_path (mdn, filename, dn, data, case_insensitive); + err = dnode_get_path (subvol, filename, dn, data); grub_free (fsname); grub_free (snapname); return err; @@ -3088,8 +3365,8 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) if (! data) return grub_errno; - err = dnode_get_fullpath (fsfilename, &(data->mdn), 0, - &(data->dnode), &isfs, data, NULL); + err = dnode_get_fullpath (fsfilename, &(data->subvol), + &(data->dnode), &isfs, data); if (err) { zfs_unmount (data); @@ -3252,8 +3529,9 @@ grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, if (! data) return grub_errno; - err = dnode_get_fullpath (fsfilename, &(data->mdn), mdnobj, - &(data->dnode), &isfs, data, NULL); + err = dnode_get_fullpath (fsfilename, &(data->subvol), + &(data->dnode), &isfs, data); + *mdnobj = data->subvol.obj; zfs_unmount (data); return err; } @@ -3348,7 +3626,6 @@ grub_zfs_dir (grub_device_t device, const char *path, struct grub_zfs_data *data; grub_err_t err; int isfs; - int case_insensitive = 0; auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val); @@ -3361,7 +3638,7 @@ grub_zfs_dir (grub_device_t device, const char *path, dnode_end_t dn; grub_memset (&info, 0, sizeof (info)); - dnode_get (&(data->mdn), val, 0, &dn, data); + dnode_get (&(data->subvol.mdn), val, 0, &dn, data); if (dn.dn.dn_bonustype == DMU_OT_SA) { @@ -3393,7 +3670,7 @@ grub_zfs_dir (grub_device_t device, const char *path, hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); info.mtimeset = 1; info.mtime = grub_zfs_to_cpu64 (*(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); - info.case_insensitive = case_insensitive; + info.case_insensitive = data->subvol.case_insensitive; } if (dn.dn.dn_bonustype == DMU_OT_ZNODE) @@ -3448,8 +3725,7 @@ grub_zfs_dir (grub_device_t device, const char *path, data = zfs_mount (device); if (! data) return grub_errno; - err = dnode_get_fullpath (path, &(data->mdn), 0, &(data->dnode), &isfs, data, - &case_insensitive); + err = dnode_get_fullpath (path, &(data->subvol), &(data->dnode), &isfs, data); if (err) { zfs_unmount (data); @@ -3475,7 +3751,7 @@ grub_zfs_dir (grub_device_t device, const char *path, return err; } - zap_iterate (&dn, iterate_zap_fs, data); + zap_iterate_u64 (&dn, iterate_zap_fs, data); err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data); if (err) @@ -3494,7 +3770,7 @@ grub_zfs_dir (grub_device_t device, const char *path, return err; } - zap_iterate (&dn, iterate_zap_snap, data); + zap_iterate_u64 (&dn, iterate_zap_snap, data); } else { @@ -3503,7 +3779,7 @@ grub_zfs_dir (grub_device_t device, const char *path, zfs_unmount (data); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); } - zap_iterate (&(data->dnode), iterate_zap, data); + zap_iterate_u64 (&(data->dnode), iterate_zap, data); } zfs_unmount (data); return grub_errno; diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 8876cc326..f858be9c6 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -210,9 +210,10 @@ grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher, gcry_err_code_t grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size) + void *out, const void *in, grub_size_t size) { - grub_uint8_t *inptr, *outptr, *end; + const grub_uint8_t *inptr; + grub_uint8_t *outptr, *end; if (!cipher->cipher->encrypt) return GPG_ERR_NOT_SUPPORTED; if (size % cipher->cipher->blocksize != 0) diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 10368d99f..573893a3e 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -203,7 +203,7 @@ grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher, gcry_err_code_t grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher, - void *out, void *in, grub_size_t size); + void *out, const void *in, grub_size_t size); gcry_err_code_t grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher, void *out, void *in, grub_size_t size, @@ -251,11 +251,13 @@ extern gcry_md_spec_t _gcry_digest_spec_sha1; extern gcry_md_spec_t _gcry_digest_spec_sha256; extern gcry_md_spec_t _gcry_digest_spec_sha512; extern gcry_md_spec_t _gcry_digest_spec_crc32; +extern gcry_cipher_spec_t _gcry_cipher_spec_aes; #define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5) #define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1) #define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256) #define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512) #define GRUB_MD_CRC32 ((const gcry_md_spec_t *) &_gcry_digest_spec_crc32) +#define GRUB_CIPHER_AES ((const gcry_cipher_spec_t *) &_gcry_cipher_spec_aes) /* Implement PKCS#5 PBKDF2 as per RFC 2898. The PRF to use is HMAC variant of digest supplied by MD. Inputs are the password P of length PLEN, diff --git a/include/grub/zfs/dmu.h b/include/grub/zfs/dmu.h index bee317e8a..8fc6dc5b5 100644 --- a/include/grub/zfs/dmu.h +++ b/include/grub/zfs/dmu.h @@ -88,6 +88,7 @@ typedef enum dmu_object_type { DMU_OT_SA_MASTER_NODE, /* ZAP */ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ + DMU_OT_DSL_KEYCHAIN = 54, DMU_OT_NUMTYPES } dmu_object_type_t; diff --git a/include/grub/zfs/dsl_dir.h b/include/grub/zfs/dsl_dir.h index 41d77c790..6542a77fe 100644 --- a/include/grub/zfs/dsl_dir.h +++ b/include/grub/zfs/dsl_dir.h @@ -42,7 +42,9 @@ typedef struct dsl_dir_phys { grub_uint64_t dd_reserved; grub_uint64_t dd_props_zapobj; grub_uint64_t dd_deleg_zapobj; /* dataset permissions */ - grub_uint64_t dd_pad[20]; /* pad out to 256 bytes for good measure */ + grub_uint64_t unused[7]; + grub_uint64_t keychain; + grub_uint64_t unused2[12]; } dsl_dir_phys_t; #endif /* _SYS_DSL_DIR_H */ diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 29451593f..8b645c063 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -65,6 +65,7 @@ enum zio_checksum { ZIO_CHECKSUM_FLETCHER_4, ZIO_CHECKSUM_SHA256, ZIO_CHECKSUM_ZILOG2, + ZIO_CHECKSUM_SHA256_MAC, ZIO_CHECKSUM_FUNCTIONS }; From 2cdc899567c4db45ab0a3a5eae2aa91faa7cff92 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 14:44:29 +0100 Subject: [PATCH 1342/1414] ZFS crypto key adding --- grub-core/fs/zfs/zfs.c | 114 +++++++++++++++++++++++-------------- grub-core/fs/zfs/zfsinfo.c | 67 ++++++++++++++++++++++ include/grub/zfs/zfs.h | 2 + util/grub-fstest.c | 26 +++++++++ 4 files changed, 165 insertions(+), 44 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 9da4d70e2..4008d17f4 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010,2011 Free Software Foundation, Inc. * Copyright 2010 Sun Microsystems, Inc. * * GRUB is free software; you can redistribute it and/or modify @@ -142,6 +142,12 @@ struct grub_zfs_key grub_uint8_t unknown_purpose_key[48]; }; +struct grub_zfs_wrap_key +{ + struct grub_zfs_wrap_key *next; + grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; +}; + extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, @@ -216,6 +222,21 @@ struct grub_zfs_data grub_uint64_t guid; }; +static struct grub_zfs_wrap_key *zfs_wrap_keys; + +grub_err_t +grub_zfs_add_key (grub_uint8_t *key_in) +{ + struct grub_zfs_wrap_key *key; + key = grub_malloc (sizeof (*key)); + if (!key) + return grub_errno; + grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); + key->next = zfs_wrap_keys; + zfs_wrap_keys = key; + return GRUB_ERR_NONE; +} + static grub_err_t zlib_decompress (void *s, void *d, grub_size_t slen, grub_size_t dlen) @@ -2747,9 +2768,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_size_t elemsize) { const struct grub_zfs_key *key = val_in; - grub_crypto_cipher_handle_t cipher; - grub_uint8_t wrapping_key[32], decrypted[32], mac[32]; unsigned keylen; + struct grub_zfs_wrap_key *wrap_key; if (elemsize != 1 || nelem != sizeof (*key)) { @@ -2766,51 +2786,57 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, else keylen = 32; - grub_memset (wrapping_key, 0, sizeof (wrapping_key)); + for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) + { + grub_crypto_cipher_handle_t cipher; + grub_uint8_t decrypted[32], mac[32]; + cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (cipher, + (const grub_uint8_t *) wrap_key->key, + keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } - cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - err = grub_crypto_cipher_set_key (cipher, wrapping_key, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } + err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); + if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) + != 0)) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } - err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; + err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!subvol->cipher) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } return 0; } - - err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - return 0; - } - subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!subvol->cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - return 0; } diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 8c073fab5..dfc238d11 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -21,10 +21,12 @@ #include #include #include +#include #include #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -389,14 +391,78 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, return GRUB_ERR_NONE; } +static const struct grub_arg_option options[] = + { + {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, + {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, + {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint8_t buf[1024]; + grub_ssize_t real_size; + + if (argc > 0) + { + grub_file_t file; + file = grub_file_open (args[0]); + if (!file) + return grub_errno; + real_size = grub_file_read (file, buf, 1024); + if (real_size < 0) + return grub_errno; + } + if (ctxt->state[0].set + || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) + { + grub_err_t err; + if (real_size < GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + + if (ctxt->state[1].set) + { + int i; + grub_err_t err; + if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); + for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) + { + char c1 = grub_tolower (buf[2 * i]) - '0'; + char c2 = grub_tolower (buf[2 * i + 1]) - '0'; + if (c1 > 9) + c1 += '0' - 'a' + 10; + if (c2 > 9) + c2 += '0' - 'a' + 10; + buf[i] = (c1 << 4) | c2; + } + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + return GRUB_ERR_NONE; +} static grub_command_t cmd_info, cmd_bootfs; +static grub_extcmd_t cmd_key; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, "zfsinfo DEVICE", "Print ZFS info about DEVICE."); + cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, + "zfskey [-h|-p|-r] [FILE]", + "Import ZFS wrapping key stored in FILE.", + options); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, "zfs-bootfs FILESYSTEM [VARIABLE]", "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); @@ -406,4 +472,5 @@ GRUB_MOD_FINI (zfsinfo) { grub_unregister_command (cmd_info); grub_unregister_command (cmd_bootfs); + grub_unregister_extcmd (cmd_key); } diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index d7029903a..62b72776e 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -121,5 +121,7 @@ char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, grub_size_t index); int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, const char *name); +grub_err_t grub_zfs_add_key (grub_uint8_t *key_in); +#define GRUB_ZFS_MAX_KEYLEN 32 #endif /* ! GRUB_ZFS_HEADER */ diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 996d71c3a..0d0801187 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -438,6 +439,7 @@ static struct argp_option options[] = { {"diskcount", 'c', "N", 0, N_("N input files."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, + {"zfs-key-file", 'K', N_("KEY_FILENAME"), 0, N_("Load zfs crypto key."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {"uncompress", 'u', NULL, OPTION_ARG_OPTIONAL, N_("Uncompress data."), 2}, {0, 0, 0, 0, 0, 0} @@ -462,6 +464,30 @@ argp_parser (int key, char *arg, struct argp_state *state) root = arg; return 0; + case 'K': + { + FILE *f; + ssize_t real_size; + grub_uint8_t buf[GRUB_ZFS_MAX_KEYLEN]; + f = fopen (arg, "rb"); + if (!f) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + return 0; + } + real_size = fread (buf, 1, GRUB_ZFS_MAX_KEYLEN, f); + if (real_size < 0) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + fclose (f); + return 0; + } + if (real_size < GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); + grub_zfs_add_key (buf); + } + return 0; + case 'C': mount_crypt = 1; return 0; From f003a8c5e75df1c0b01511195e62f2afe317aa58 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 15:18:25 +0100 Subject: [PATCH 1343/1414] Move ZFS crypto to separate module --- Makefile.util.def | 1 + grub-core/Makefile.core.def | 5 + grub-core/fs/zfs/zfs.c | 255 ++++++---------------------- grub-core/fs/zfs/zfscrypt.c | 324 ++++++++++++++++++++++++++++++++++++ grub-core/fs/zfs/zfsinfo.c | 67 -------- grub-core/lib/crypto.c | 8 - include/grub/crypto.h | 8 +- include/grub/zfs/spa.h | 24 ++- include/grub/zfs/zfs.h | 21 +++ 9 files changed, 415 insertions(+), 298 deletions(-) create mode 100644 grub-core/fs/zfs/zfscrypt.c diff --git a/Makefile.util.def b/Makefile.util.def index 17894b1d2..15a309367 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -82,6 +82,7 @@ library = { common = grub-core/fs/ufs2.c; common = grub-core/fs/ufs.c; common = grub-core/fs/xfs.c; + common = grub-core/fs/zfs/zfscrypt.c; common = grub-core/fs/zfs/zfs.c; common = grub-core/fs/zfs/zfsinfo.c; common = grub-core/fs/zfs/zfs_lzjb.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index b2e8e7aa2..9590188fb 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1116,6 +1116,11 @@ module = { common = fs/zfs/zfs_fletcher.c; }; +module = { + name = zfscrypt; + common = fs/zfs/zfscrypt.c; +}; + module = { name = zfsinfo; common = fs/zfs/zfsinfo.c; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4008d17f4..3558bd8bb 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -125,29 +125,6 @@ static grub_dl_t my_mod; #define NBBY 8 #endif -enum grub_zfs_algo - { - GRUB_ZFS_ALGO_CCM, - GRUB_ZFS_ALGO_GCM, - }; - -struct grub_zfs_key -{ - grub_uint64_t algo; - grub_uint8_t enc_nonce[13]; - grub_uint8_t unused[3]; - grub_uint8_t enc_key[48]; - grub_uint8_t unknown_purpose_nonce[13]; - grub_uint8_t unused2[3]; - grub_uint8_t unknown_purpose_key[48]; -}; - -struct grub_zfs_wrap_key -{ - struct grub_zfs_wrap_key *next; - grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; -}; - extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, @@ -222,20 +199,13 @@ struct grub_zfs_data grub_uint64_t guid; }; -static struct grub_zfs_wrap_key *zfs_wrap_keys; - -grub_err_t -grub_zfs_add_key (grub_uint8_t *key_in) -{ - struct grub_zfs_wrap_key *key; - key = grub_malloc (sizeof (*key)); - if (!key) - return grub_errno; - grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); - key->next = zfs_wrap_keys; - zfs_wrap_keys = key; - return GRUB_ERR_NONE; -} +grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + void *nonce, + char *buf, grub_size_t size, + const grub_uint32_t *expected_mac, + grub_zfs_endian_t endian) = NULL; +grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, + grub_size_t keysize) = NULL; static grub_err_t zlib_decompress (void *s, void *d, @@ -409,14 +379,16 @@ static int vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) { grub_zfs_endian_t ub1_endian, ub2_endian; - if (grub_zfs_to_cpu64 (ub1->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) - ub1_endian = LITTLE_ENDIAN; + if (grub_zfs_to_cpu64 (ub1->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) + == UBERBLOCK_MAGIC) + ub1_endian = GRUB_ZFS_LITTLE_ENDIAN; else - ub1_endian = BIG_ENDIAN; - if (grub_zfs_to_cpu64 (ub2->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC) - ub2_endian = LITTLE_ENDIAN; + ub1_endian = GRUB_ZFS_BIG_ENDIAN; + if (grub_zfs_to_cpu64 (ub2->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) + == UBERBLOCK_MAGIC) + ub2_endian = GRUB_ZFS_LITTLE_ENDIAN; else - ub2_endian = BIG_ENDIAN; + ub2_endian = GRUB_ZFS_BIG_ENDIAN; if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) @@ -448,20 +420,23 @@ uberblock_verify (uberblock_phys_t * ub, grub_uint64_t offset) { uberblock_t *uber = &ub->ubp_uberblock; grub_err_t err; - grub_zfs_endian_t endian = UNKNOWN_ENDIAN; + grub_zfs_endian_t endian = GRUB_ZFS_UNKNOWN_ENDIAN; zio_cksum_t zc; - if (grub_zfs_to_cpu64 (uber->ub_magic, LITTLE_ENDIAN) == UBERBLOCK_MAGIC - && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) > 0 - && grub_zfs_to_cpu64 (uber->ub_version, LITTLE_ENDIAN) <= SPA_VERSION) - endian = LITTLE_ENDIAN; + if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) + == UBERBLOCK_MAGIC + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_LITTLE_ENDIAN) > 0 + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_LITTLE_ENDIAN) + <= SPA_VERSION) + endian = GRUB_ZFS_LITTLE_ENDIAN; - if (grub_zfs_to_cpu64 (uber->ub_magic, BIG_ENDIAN) == UBERBLOCK_MAGIC - && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) > 0 - && grub_zfs_to_cpu64 (uber->ub_version, BIG_ENDIAN) <= SPA_VERSION) - endian = BIG_ENDIAN; + if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_BIG_ENDIAN) == UBERBLOCK_MAGIC + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_BIG_ENDIAN) > 0 + && grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_BIG_ENDIAN) + <= SPA_VERSION) + endian = GRUB_ZFS_BIG_ENDIAN; - if (endian == UNKNOWN_ENDIAN) + if (endian == GRUB_ZFS_UNKNOWN_ENDIAN) return grub_error (GRUB_ERR_BAD_FS, "invalid uberblock magic"); grub_memset (&zc, 0, sizeof (zc)); @@ -1382,7 +1357,7 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, zio_gb = grub_malloc (SPA_GANGBLOCKSIZE); if (!zio_gb) return grub_errno; - grub_dprintf ("zfs", endian == LITTLE_ENDIAN ? "little-endian gang\n" + grub_dprintf ("zfs", endian == GRUB_ZFS_LITTLE_ENDIAN ? "little-endian gang\n" :"big-endian gang\n"); err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE); @@ -1457,57 +1432,6 @@ zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, return err; } -static grub_err_t -grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, - grub_uint8_t *out, const grub_uint8_t *in, - grub_size_t psize, - void *mac_out, const void *nonce, - unsigned l, unsigned m) -{ - grub_uint8_t iv[16]; - grub_uint8_t mul[16]; - grub_uint32_t mac[4]; - unsigned i, j; - grub_err_t err; - - grub_memcpy (iv + 1, nonce, 15 - l); - - iv[0] = (l - 1) | (((m-2) / 2) << 3); - for (j = 0; j < l; j++) - iv[15 - j] = psize >> (8 * j); - err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); - if (err) - return err; - - iv[0] = l - 1; - - for (i = 0; i < (psize + 15) / 16; i++) - { - grub_size_t csize; - csize = 16; - if (csize > psize - 16 * i) - csize = psize - 16 * i; - for (j = 0; j < l; j++) - iv[15 - j] = (i + 1) >> (8 * j); - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); - grub_crypto_xor (mac, mac, out + 16 * i, csize); - err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); - if (err) - return err; - } - for (j = 0; j < l; j++) - iv[15 - j] = 0; - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - if (mac_out) - grub_crypto_xor (mac_out, mac, mul, m); - return GRUB_ERR_NONE; -} - /* * Read in a block of data, verify its checksum, decompress if needed, * and put the uncompressed data in buf. @@ -1575,41 +1499,18 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (encrypted) { - grub_uint32_t mac[4]; - unsigned i; - grub_uint32_t sw[4]; - - grub_memcpy (sw, &(bp)->blk_dva[encrypted], 16); - for (i = 0; i < 4; i++) - sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); - - if (!data->subvol.cipher) - { - grub_free (compbuf); - *buf = NULL; - return grub_error (GRUB_ERR_ACCESS_DENIED, - "no decryption key available");; - } - err = grub_ccm_decrypt (data->subvol.cipher, - (grub_uint8_t *) compbuf, - (grub_uint8_t *) compbuf, - psize, mac, - sw + 1, 3, 12); + if (!grub_zfs_decrypt) + err = grub_error (GRUB_ERR_BAD_FS, "zfscrypto module not loaded"); + else + err = grub_zfs_decrypt (data->subvol.cipher, &(bp)->blk_dva[encrypted], + compbuf, psize, ((grub_uint32_t *) &zc + 5), + endian); if (err) { grub_free (compbuf); *buf = NULL; return err; } - - for (i = 0; i < 3; i++) - if (grub_zfs_to_cpu32 (((grub_uint32_t *) &zc + 5)[i], endian) - != grub_be_to_cpu32 (mac[i])) - { - grub_free (compbuf); - *buf = NULL; - return grub_error (GRUB_ERR_BAD_FS, "MAC verification failed"); - } } if (comp != ZIO_COMPRESS_OFF) @@ -2767,76 +2668,14 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_size_t nelem, grub_size_t elemsize) { - const struct grub_zfs_key *key = val_in; - unsigned keylen; - struct grub_zfs_wrap_key *wrap_key; - - if (elemsize != 1 || nelem != sizeof (*key)) + if (elemsize != 1) { - grub_dprintf ("zfs", "Unexpected key length %" PRIuGRUB_SIZE - " x %" PRIuGRUB_SIZE "\n", nelem, elemsize); + grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", + elemsize); return 0; } - if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) - == 0) - keylen = 16; - else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) - keylen = 24; - else - keylen = 32; - - for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) - { - grub_crypto_cipher_handle_t cipher; - grub_uint8_t decrypted[32], mac[32]; - cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - err = grub_crypto_cipher_set_key (cipher, - (const grub_uint8_t *) wrap_key->key, - keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); - if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) - != 0)) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - - err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - subvol->cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!subvol->cipher) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - err = grub_crypto_cipher_set_key (subvol->cipher, decrypted, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - return 0; - } + subvol->cipher = grub_zfs_load_key (val_in, nelem); return 0; } @@ -2904,7 +2743,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); - if (keychainobj) + if (grub_zfs_load_key && keychainobj) { dnode_end_t keychain_dn; err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, @@ -2918,7 +2757,6 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, zap_iterate (&keychain_dn, iterate_zap_key, data); } - if (snapname) { grub_uint64_t snapobj; @@ -3221,6 +3059,7 @@ zfs_unmount (struct grub_zfs_data *data) grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); + grub_crypto_cipher_close (data->subvol.cipher); grub_free (data); } @@ -3236,7 +3075,7 @@ zfs_mount (grub_device_t dev) grub_err_t err; objset_phys_t *osp = 0; grub_size_t ospsize; - grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; if (! dev->disk) @@ -3267,8 +3106,8 @@ zfs_mount (grub_device_t dev) ub = &(data->current_uberblock); ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? LITTLE_ENDIAN : BIG_ENDIAN); + GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); err = zio_read (&ub->ub_rootbp, ub_endian, (void **) &osp, &ospsize, data); @@ -3357,7 +3196,7 @@ static grub_err_t zfs_mtime (grub_device_t device, grub_int32_t *mt) { struct grub_zfs_data *data; - grub_zfs_endian_t ub_endian = UNKNOWN_ENDIAN; + grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; *mt = 0; @@ -3368,8 +3207,8 @@ zfs_mtime (grub_device_t device, grub_int32_t *mt) ub = &(data->current_uberblock); ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? LITTLE_ENDIAN : BIG_ENDIAN); + GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC + ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian); zfs_unmount (data); diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c new file mode 100644 index 000000000..251538041 --- /dev/null +++ b/grub-core/fs/zfs/zfscrypt.c @@ -0,0 +1,324 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +enum grub_zfs_algo + { + GRUB_ZFS_ALGO_CCM, + GRUB_ZFS_ALGO_GCM, + }; + +struct grub_zfs_key +{ + grub_uint64_t algo; + grub_uint8_t enc_nonce[13]; + grub_uint8_t unused[3]; + grub_uint8_t enc_key[48]; + grub_uint8_t unknown_purpose_nonce[13]; + grub_uint8_t unused2[3]; + grub_uint8_t unknown_purpose_key[48]; +}; + +struct grub_zfs_wrap_key +{ + struct grub_zfs_wrap_key *next; + grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; +}; + +static struct grub_zfs_wrap_key *zfs_wrap_keys; + +grub_err_t +grub_zfs_add_key (grub_uint8_t *key_in) +{ + struct grub_zfs_wrap_key *key; + key = grub_malloc (sizeof (*key)); + if (!key) + return grub_errno; + grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); + key->next = zfs_wrap_keys; + zfs_wrap_keys = key; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned l, unsigned m) +{ + grub_uint8_t iv[16]; + grub_uint8_t mul[16]; + grub_uint32_t mac[4]; + unsigned i, j; + grub_err_t err; + + grub_memcpy (iv + 1, nonce, 15 - l); + + iv[0] = (l - 1) | (((m-2) / 2) << 3); + for (j = 0; j < l; j++) + iv[15 - j] = psize >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); + if (err) + return err; + + iv[0] = l - 1; + + for (i = 0; i < (psize + 15) / 16; i++) + { + grub_size_t csize; + csize = 16; + if (csize > psize - 16 * i) + csize = psize - 16 * i; + for (j = 0; j < l; j++) + iv[15 - j] = (i + 1) >> (8 * j); + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); + grub_crypto_xor (mac, mac, out + 16 * i, csize); + err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); + if (err) + return err; + } + for (j = 0; j < l; j++) + iv[15 - j] = 0; + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + if (mac_out) + grub_crypto_xor (mac_out, mac, mul, m); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, + char *buf, grub_size_t size, + const grub_uint32_t *expected_mac, + grub_zfs_endian_t endian) +{ + grub_uint32_t mac[4]; + unsigned i; + grub_uint32_t sw[4]; + grub_err_t err; + + grub_memcpy (sw, nonce, 16); + for (i = 0; i < 4; i++) + sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); + + if (!cipher) + return grub_error (GRUB_ERR_ACCESS_DENIED, + "no decryption key available");; + err = grub_ccm_decrypt (cipher, + (grub_uint8_t *) buf, + (grub_uint8_t *) buf, + size, mac, + sw + 1, 3, 12); + if (err) + return err; + + for (i = 0; i < 3; i++) + if (grub_zfs_to_cpu32 (expected_mac[i], endian) + != grub_be_to_cpu32 (mac[i])) + return grub_error (GRUB_ERR_BAD_FS, "MAC verification failed"); + return GRUB_ERR_NONE; +} + +static grub_crypto_cipher_handle_t +grub_zfs_load_key_real (const struct grub_zfs_key *key, + grub_size_t keysize) +{ + unsigned keylen; + struct grub_zfs_wrap_key *wrap_key; + grub_crypto_cipher_handle_t ret = NULL; + grub_err_t err; + + if (keysize != sizeof (*key)) + { + grub_dprintf ("zfs", "Unexpected key size %" PRIuGRUB_SIZE "\n", keysize); + return 0; + } + + if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) + == 0) + keylen = 16; + else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) + keylen = 24; + else + keylen = 32; + + for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) + { + grub_crypto_cipher_handle_t cipher; + grub_uint8_t decrypted[32], mac[32]; + cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!cipher) + { + grub_errno = GRUB_ERR_NONE; + return 0; + } + err = grub_crypto_cipher_set_key (cipher, + (const grub_uint8_t *) wrap_key->key, + keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); + if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) + != 0)) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + + err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); + if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) + { + grub_dprintf ("zfs", "key loading failed\n"); + grub_errno = GRUB_ERR_NONE; + continue; + } + ret = grub_crypto_cipher_open (GRUB_CIPHER_AES); + if (!ret) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + err = grub_crypto_cipher_set_key (ret, decrypted, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + grub_crypto_cipher_close (ret); + continue; + } + return ret; + } + return NULL; +} + +static const struct grub_arg_option options[] = + { + {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, + {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, + {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint8_t buf[1024]; + grub_ssize_t real_size; + + if (argc > 0) + { + grub_file_t file; + file = grub_file_open (args[0]); + if (!file) + return grub_errno; + real_size = grub_file_read (file, buf, 1024); + if (real_size < 0) + return grub_errno; + } + if (ctxt->state[0].set + || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) + { + grub_err_t err; + if (real_size < GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + + if (ctxt->state[1].set) + { + int i; + grub_err_t err; + if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) + grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); + for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) + { + char c1 = grub_tolower (buf[2 * i]) - '0'; + char c2 = grub_tolower (buf[2 * i + 1]) - '0'; + if (c1 > 9) + c1 += '0' - 'a' + 10; + if (c2 > 9) + c2 += '0' - 'a' + 10; + buf[i] = (c1 << 4) | c2; + } + err = grub_zfs_add_key (buf); + if (err) + return err; + return GRUB_ERR_NONE; + } + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd_key; + +GRUB_MOD_INIT(zfscrypto) +{ + grub_zfs_decrypt = grub_zfs_decrypt_real; + grub_zfs_load_key = grub_zfs_load_key_real; + cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, + "zfskey [-h|-p|-r] [FILE]", + "Import ZFS wrapping key stored in FILE.", + options); +} + +GRUB_MOD_FINI(zfscrypto) +{ + grub_zfs_decrypt = 0; + grub_zfs_load_key = 0; + grub_unregister_extcmd (cmd_key); +} diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index dfc238d11..3ed2448b0 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -391,78 +390,13 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, return GRUB_ERR_NONE; } -static const struct grub_arg_option options[] = - { - {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, - {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, - {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint8_t buf[1024]; - grub_ssize_t real_size; - - if (argc > 0) - { - grub_file_t file; - file = grub_file_open (args[0]); - if (!file) - return grub_errno; - real_size = grub_file_read (file, buf, 1024); - if (real_size < 0) - return grub_errno; - } - if (ctxt->state[0].set - || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) - { - grub_err_t err; - if (real_size < GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); - err = grub_zfs_add_key (buf); - if (err) - return err; - return GRUB_ERR_NONE; - } - - if (ctxt->state[1].set) - { - int i; - grub_err_t err; - if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); - for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) - { - char c1 = grub_tolower (buf[2 * i]) - '0'; - char c2 = grub_tolower (buf[2 * i + 1]) - '0'; - if (c1 > 9) - c1 += '0' - 'a' + 10; - if (c2 > 9) - c2 += '0' - 'a' + 10; - buf[i] = (c1 << 4) | c2; - } - err = grub_zfs_add_key (buf); - if (err) - return err; - return GRUB_ERR_NONE; - } - return GRUB_ERR_NONE; -} - static grub_command_t cmd_info, cmd_bootfs; -static grub_extcmd_t cmd_key; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, "zfsinfo DEVICE", "Print ZFS info about DEVICE."); - cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, - "zfskey [-h|-p|-r] [FILE]", - "Import ZFS wrapping key stored in FILE.", - options); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, "zfs-bootfs FILESYSTEM [VARIABLE]", "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); @@ -472,5 +406,4 @@ GRUB_MOD_FINI (zfsinfo) { grub_unregister_command (cmd_info); grub_unregister_command (cmd_bootfs); - grub_unregister_extcmd (cmd_key); } diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index f858be9c6..4dec5c694 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -169,14 +169,6 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher, return cipher->cipher->setkey (cipher->ctx, key, keylen); } - -void -grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher) -{ - grub_free (cipher); -} - - void grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size) { diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 573893a3e..b8a5b3a22 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -26,6 +26,7 @@ #include #include #include +#include typedef enum { @@ -191,8 +192,11 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher, const unsigned char *key, unsigned keylen); -void -grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher); +static inline void +grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher) +{ + grub_free (cipher); +} void grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size); diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h index 22ee03b15..0e29fa44a 100644 --- a/include/grub/zfs/spa.h +++ b/include/grub/zfs/spa.h @@ -20,26 +20,24 @@ #ifndef GRUB_ZFS_SPA_HEADER #define GRUB_ZFS_SPA_HEADER 1 -typedef enum grub_zfs_endian - { - UNKNOWN_ENDIAN = -2, - LITTLE_ENDIAN = -1, - BIG_ENDIAN = 0 - } grub_zfs_endian_t; - -#define grub_zfs_to_cpu16(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu16(x) \ +#define grub_zfs_to_cpu16(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_be_to_cpu16(x) \ : grub_le_to_cpu16(x)) -#define grub_cpu_to_zfs16(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be16(x) \ +#define grub_cpu_to_zfs16(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_cpu_to_be16(x) \ : grub_cpu_to_le16(x)) -#define grub_zfs_to_cpu32(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu32(x) \ +#define grub_zfs_to_cpu32(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_be_to_cpu32(x) \ : grub_le_to_cpu32(x)) -#define grub_cpu_to_zfs32(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be32(x) \ +#define grub_cpu_to_zfs32(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ + grub_cpu_to_be32(x) \ : grub_cpu_to_le32(x)) -#define grub_zfs_to_cpu64(x,a) (((a) == BIG_ENDIAN) ? grub_be_to_cpu64(x) \ +#define grub_zfs_to_cpu64(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) \ + ? grub_be_to_cpu64(x) \ : grub_le_to_cpu64(x)) -#define grub_cpu_to_zfs64(x,a) (((a) == BIG_ENDIAN) ? grub_cpu_to_be64(x) \ +#define grub_cpu_to_zfs64(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? grub_cpu_to_be64(x) \ : grub_cpu_to_le64(x)) /* diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 62b72776e..6c280bfe2 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -24,6 +24,14 @@ #include #include +#include + +typedef enum grub_zfs_endian + { + GRUB_ZFS_UNKNOWN_ENDIAN = -2, + GRUB_ZFS_LITTLE_ENDIAN = -1, + GRUB_ZFS_BIG_ENDIAN = 0 + } grub_zfs_endian_t; /* * On-disk version number. @@ -124,4 +132,17 @@ int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, grub_err_t grub_zfs_add_key (grub_uint8_t *key_in); #define GRUB_ZFS_MAX_KEYLEN 32 +extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + void *nonce, + char *buf, grub_size_t size, + const grub_uint32_t *expected_mac, + grub_zfs_endian_t endian); + +struct grub_zfs_key; + +extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, + grub_size_t keysize); + + + #endif /* ! GRUB_ZFS_HEADER */ From ed746949afec9a9ab8c231e3ed4e49cefbe7c4f6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 16:30:52 +0100 Subject: [PATCH 1344/1414] ZFS passphrase support --- grub-core/fs/zfs/zfs.c | 36 +++++++++++++++++++--- grub-core/fs/zfs/zfscrypt.c | 61 ++++++++++++++++++++++++------------- include/grub/zfs/zfs.h | 9 ++++-- util/grub-fstest.c | 20 ++++++++---- 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 3558bd8bb..0e9869d3f 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -205,7 +205,8 @@ grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, const grub_uint32_t *expected_mac, grub_zfs_endian_t endian) = NULL; grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, - grub_size_t keysize) = NULL; + grub_size_t keysize, + grub_uint64_t salt) = NULL; static grub_err_t zlib_decompress (void *s, void *d, @@ -1500,7 +1501,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (encrypted) { if (!grub_zfs_decrypt) - err = grub_error (GRUB_ERR_BAD_FS, "zfscrypto module not loaded"); + err = grub_error (GRUB_ERR_BAD_FS, "zfscrypt module not loaded"); else err = grub_zfs_decrypt (data->subvol.cipher, &(bp)->blk_dva[encrypted], compbuf, psize, ((grub_uint32_t *) &zc + 5), @@ -2657,8 +2658,10 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, const char *ptr_at, *filename; grub_uint64_t headobj; grub_uint64_t keychainobj; + grub_uint64_t salt; grub_err_t err; + auto int NESTED_FUNC_ATTR iterate_zap_key (const char *name, const void *val_in, grub_size_t nelem, @@ -2675,7 +2678,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, return 0; } - subvol->cipher = grub_zfs_load_key (val_in, nelem); + subvol->cipher = grub_zfs_load_key (val_in, nelem, salt); return 0; } @@ -2745,7 +2748,32 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); if (grub_zfs_load_key && keychainobj) { - dnode_end_t keychain_dn; + dnode_end_t keychain_dn, props_dn; + grub_uint64_t propsobj; + propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_props_zapobj, dn->endian); + + err = dnode_get (&(data->mos), propsobj, DMU_OT_DSL_PROPS, + &props_dn, data); + if (err) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + + err = zap_lookup (&props_dn, "salt", &salt, data, 0); + if (err == GRUB_ERR_FILE_NOT_FOUND) + { + err = 0; + grub_errno = 0; + salt = 0; + } + if (err) + { + grub_dprintf ("zfs", "failed here\n"); + return err; + } + err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, &keychain_dn, data); if (err) diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 251538041..d8c7181f0 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -64,19 +64,27 @@ struct grub_zfs_key struct grub_zfs_wrap_key { struct grub_zfs_wrap_key *next; - grub_uint64_t key[GRUB_ZFS_MAX_KEYLEN / 8]; + grub_size_t keylen; + int is_passphrase; + grub_uint64_t key[0]; }; static struct grub_zfs_wrap_key *zfs_wrap_keys; grub_err_t -grub_zfs_add_key (grub_uint8_t *key_in) +grub_zfs_add_key (grub_uint8_t *key_in, + grub_size_t keylen, + int passphrase) { struct grub_zfs_wrap_key *key; - key = grub_malloc (sizeof (*key)); + if (!passphrase && keylen > 32) + keylen = 32; + key = grub_malloc (sizeof (*key) + keylen); if (!key) return grub_errno; - grub_memcpy (key->key, key_in, GRUB_ZFS_MAX_KEYLEN); + key->is_passphrase = passphrase; + key->keylen = keylen; + grub_memcpy (key->key, key_in, keylen); key->next = zfs_wrap_keys; zfs_wrap_keys = key; return GRUB_ERR_NONE; @@ -168,7 +176,8 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, static grub_crypto_cipher_handle_t grub_zfs_load_key_real (const struct grub_zfs_key *key, - grub_size_t keysize) + grub_size_t keysize, + grub_uint64_t salt) { unsigned keylen; struct grub_zfs_wrap_key *wrap_key; @@ -192,15 +201,25 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) { grub_crypto_cipher_handle_t cipher; - grub_uint8_t decrypted[32], mac[32]; + grub_uint8_t decrypted[32], mac[32], wrap_key_real[32]; cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); if (!cipher) { grub_errno = GRUB_ERR_NONE; return 0; } - err = grub_crypto_cipher_set_key (cipher, - (const grub_uint8_t *) wrap_key->key, + grub_memset (wrap_key_real, 0, sizeof (wrap_key_real)); + if (!wrap_key->is_passphrase) + grub_memcpy(wrap_key_real, wrap_key->key, + wrap_key->keylen < keylen ? wrap_key->keylen : keylen); + else + grub_crypto_pbkdf2 (GRUB_MD_SHA1, + (const grub_uint8_t *) wrap_key->key, + wrap_key->keylen, + (const grub_uint8_t *) &salt, sizeof (salt), + 1000, wrap_key_real, keylen); + + err = grub_crypto_cipher_set_key (cipher, wrap_key_real, keylen); if (err) { @@ -268,25 +287,19 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) if (real_size < 0) return grub_errno; } - if (ctxt->state[0].set - || (argc > 0 && !ctxt->state[1].set && !ctxt->state[2].set)) + else { - grub_err_t err; - if (real_size < GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); - err = grub_zfs_add_key (buf); - if (err) - return err; - return GRUB_ERR_NONE; + grub_printf ("Enter ZFS password: "); + if (!grub_password_get ((char *) buf, 1023)) + return grub_errno; + real_size = grub_strlen ((char *) buf); } if (ctxt->state[1].set) { int i; grub_err_t err; - if (real_size < 2 * GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, '0', 2 * GRUB_ZFS_MAX_KEYLEN - real_size); - for (i = 0; i < GRUB_ZFS_MAX_KEYLEN; i++) + for (i = 0; i < real_size / 2; i++) { char c1 = grub_tolower (buf[2 * i]) - '0'; char c2 = grub_tolower (buf[2 * i + 1]) - '0'; @@ -296,12 +309,16 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) c2 += '0' - 'a' + 10; buf[i] = (c1 << 4) | c2; } - err = grub_zfs_add_key (buf); + err = grub_zfs_add_key (buf, real_size / 2, 0); if (err) return err; return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; + + return grub_zfs_add_key (buf, real_size, + ctxt->state[2].set + || (argc == 0 && !ctxt->state[0].set + && !ctxt->state[1].set)); } static grub_extcmd_t cmd_key; diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index 6c280bfe2..db8e915bf 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -129,8 +129,10 @@ char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, grub_size_t index); int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, const char *name); -grub_err_t grub_zfs_add_key (grub_uint8_t *key_in); -#define GRUB_ZFS_MAX_KEYLEN 32 +grub_err_t +grub_zfs_add_key (grub_uint8_t *key_in, + grub_size_t keylen, + int passphrase); extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, void *nonce, @@ -141,7 +143,8 @@ extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, struct grub_zfs_key; extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, - grub_size_t keysize); + grub_size_t keysize, + grub_uint64_t salt); diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 0d0801187..f90755e86 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -439,7 +439,7 @@ static struct argp_option options[] = { {"diskcount", 'c', "N", 0, N_("N input files."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, - {"zfs-key-file", 'K', N_("KEY_FILENAME"), 0, N_("Load zfs crypto key."), 2}, + {"zfs-key", 'K', N_("FILE|prompt"), 0, N_("Load zfs crypto key."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {"uncompress", 'u', NULL, OPTION_ARG_OPTIONAL, N_("Uncompress data."), 2}, {0, 0, 0, 0, 0, 0} @@ -465,26 +465,34 @@ argp_parser (int key, char *arg, struct argp_state *state) return 0; case 'K': + if (strcmp (arg, "prompt") == 0) + { + char buf[1024]; + grub_printf ("Enter ZFS password: "); + if (grub_password_get (buf, 1023)) + { + grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); + } + } + else { FILE *f; ssize_t real_size; - grub_uint8_t buf[GRUB_ZFS_MAX_KEYLEN]; + grub_uint8_t buf[1024]; f = fopen (arg, "rb"); if (!f) { printf ("Error loading file %s: %s\n", arg, strerror (errno)); return 0; } - real_size = fread (buf, 1, GRUB_ZFS_MAX_KEYLEN, f); + real_size = fread (buf, 1, 1024, f); if (real_size < 0) { printf ("Error loading file %s: %s\n", arg, strerror (errno)); fclose (f); return 0; } - if (real_size < GRUB_ZFS_MAX_KEYLEN) - grub_memset (buf + real_size, 0, GRUB_ZFS_MAX_KEYLEN - real_size); - grub_zfs_add_key (buf); + grub_zfs_add_key (buf, real_size, 0); } return 0; From d99b3726e591f125220fba02725bfe9fcbfb424b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 17:13:38 +0100 Subject: [PATCH 1345/1414] Support ZFS subvolumes with multiple keys --- grub-core/fs/zfs/zfs.c | 132 ++++++++++++++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 27 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 0e9869d3f..6ab1f61a7 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -167,7 +167,12 @@ struct subvolume dnode_end_t mdn; grub_uint64_t obj; grub_uint64_t case_insensitive; - grub_crypto_cipher_handle_t cipher; + grub_size_t nkeys; + struct + { + grub_crypto_cipher_handle_t cipher; + grub_uint64_t txg; + } *keyring; }; struct grub_zfs_data @@ -1503,9 +1508,37 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (!grub_zfs_decrypt) err = grub_error (GRUB_ERR_BAD_FS, "zfscrypt module not loaded"); else - err = grub_zfs_decrypt (data->subvol.cipher, &(bp)->blk_dva[encrypted], - compbuf, psize, ((grub_uint32_t *) &zc + 5), - endian); + { + unsigned i, besti = 0; + grub_uint64_t bestval = 0; + for (i = 0; i < data->subvol.nkeys; i++) + if (data->subvol.keyring[i].txg <= grub_zfs_to_cpu64 (bp->blk_birth, + endian) + && data->subvol.keyring[i].txg > bestval) + { + besti = i; + bestval = data->subvol.keyring[i].txg; + } + if (bestval == 0) + { + grub_free (compbuf); + *buf = NULL; + grub_dprintf ("zfs", "no key for txg %" PRIxGRUB_UINT64_T "\n", + grub_zfs_to_cpu64 (bp->blk_birth, + endian)); + return grub_error (GRUB_ERR_BAD_FS, "no key found in keychain"); + } + grub_dprintf ("zfs", "using key %u (%" PRIxGRUB_UINT64_T + ", %p) for txg %" PRIxGRUB_UINT64_T "\n", + besti, data->subvol.keyring[besti].txg, + data->subvol.keyring[besti].cipher, + grub_zfs_to_cpu64 (bp->blk_birth, + endian)); + err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher, + &(bp)->blk_dva[encrypted], + compbuf, psize, ((grub_uint32_t *) &zc + 5), + endian); + } if (err) { grub_free (compbuf); @@ -1896,7 +1929,9 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, /* XXX */ static int fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, - int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_size_t name_elem_length, + int NESTED_FUNC_ATTR (*hook) (const void *name, + grub_size_t name_length, const void *val_in, grub_size_t nelem, grub_size_t elemsize), @@ -1971,18 +2006,19 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, if (le->le_type != ZAP_CHUNK_ENTRY) continue; - buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) - + 1); + buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) + * name_elem_length + 1); if (zap_leaf_array_get (l, endian, blksft, grub_zfs_to_cpu16 (le->le_name_chunk, endian), grub_zfs_to_cpu16 (le->le_name_length, - endian), buf)) + endian) + * name_elem_length, buf)) { grub_free (buf); continue; } - buf[le->le_name_length] = 0; + buf[le->le_name_length * name_elem_length] = 0; val_length = ((int) le->le_value_length * (int) le->le_int_size); @@ -1997,7 +2033,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, continue; } - if (hook (buf, val, le->le_value_length, le->le_int_size)) + if (hook (buf, le->le_name_length, + val, le->le_value_length, le->le_int_size)) return 1; grub_free (buf); grub_free (val); @@ -2069,12 +2106,14 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, int ret; grub_zfs_endian_t endian; - auto int NESTED_FUNC_ATTR transform (const char *name, + auto int NESTED_FUNC_ATTR transform (const void *name, + grub_size_t namelen, const void *val_in, grub_size_t nelem, grub_size_t elemsize); - int NESTED_FUNC_ATTR transform (const char *name, + int NESTED_FUNC_ATTR transform (const void *name, + grub_size_t namelen __attribute__ ((unused)), const void *val_in, grub_size_t nelem, grub_size_t elemsize) @@ -2104,7 +2143,7 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ - ret = fzap_iterate (zap_dnode, zapbuf, transform, data); + ret = fzap_iterate (zap_dnode, zapbuf, 1, transform, data); grub_free (zapbuf); return ret; } @@ -2114,7 +2153,9 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, static int zap_iterate (dnode_end_t * zap_dnode, - int NESTED_FUNC_ATTR (*hook) (const char *name, + grub_size_t nameelemlen, + int NESTED_FUNC_ATTR (*hook) (const void *name, + grub_size_t namelen, const void *val_in, grub_size_t nelem, grub_size_t elemsize), @@ -2145,7 +2186,7 @@ zap_iterate (dnode_end_t * zap_dnode, { grub_dprintf ("zfs", "fat zap\n"); /* this is a fat zap */ - ret = fzap_iterate (zap_dnode, zapbuf, hook, data); + ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, data); grub_free (zapbuf); return ret; } @@ -2660,17 +2701,41 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_uint64_t keychainobj; grub_uint64_t salt; grub_err_t err; + int keyn = 0; - - auto int NESTED_FUNC_ATTR iterate_zap_key (const char *name, - const void *val_in, - grub_size_t nelem, - grub_size_t elemsize); - int NESTED_FUNC_ATTR iterate_zap_key (const char *name __attribute__ ((unused)), - const void *val_in, - grub_size_t nelem, - grub_size_t elemsize) + auto int NESTED_FUNC_ATTR count_zap_keys (const void *name, + grub_size_t namelen, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + int NESTED_FUNC_ATTR count_zap_keys (const void *name __attribute__ ((unused)), + grub_size_t namelen __attribute__ ((unused)), + const void *val_in __attribute__ ((unused)), + grub_size_t nelem __attribute__ ((unused)), + grub_size_t elemsize __attribute__ ((unused))) { + subvol->nkeys++; + return 0; + } + + auto int NESTED_FUNC_ATTR load_zap_key (const void *name, + grub_size_t namelen, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize); + int NESTED_FUNC_ATTR load_zap_key (const void *name, + grub_size_t namelen, + const void *val_in, + grub_size_t nelem, + grub_size_t elemsize) + { + if (namelen != 1) + { + grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n", + namelen); + return 0; + } + if (elemsize != 1) { grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", @@ -2678,7 +2743,9 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, return 0; } - subvol->cipher = grub_zfs_load_key (val_in, nelem, salt); + subvol->keyring[keyn].txg = grub_be_to_cpu64 (*(grub_uint64_t *) name); + subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt); + keyn++; return 0; } @@ -2782,7 +2849,16 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, grub_free (snapname); return err; } - zap_iterate (&keychain_dn, iterate_zap_key, data); + subvol->nkeys = 0; + zap_iterate (&keychain_dn, 8, count_zap_keys, data); + subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0])); + if (!subvol->keyring) + { + grub_free (fsname); + grub_free (snapname); + return err; + } + zap_iterate (&keychain_dn, 8, load_zap_key, data); } if (snapname) @@ -3087,7 +3163,9 @@ zfs_unmount (struct grub_zfs_data *data) grub_free (data->dnode_buf); grub_free (data->dnode_mdn); grub_free (data->file_buf); - grub_crypto_cipher_close (data->subvol.cipher); + for (i = 0; i < data->subvol.nkeys; i++) + grub_crypto_cipher_close (data->subvol.keyring[i].cipher); + grub_free (data->subvol.keyring); grub_free (data); } From bc1de0bc26ad95dd81b968fa75eaae92023bcb18 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 21:05:25 +0100 Subject: [PATCH 1346/1414] GCM support --- grub-core/fs/zfs/zfs.c | 10 ++- grub-core/fs/zfs/zfscrypt.c | 147 +++++++++++++++++++++++++++++++++--- include/grub/zfs/zfs.h | 4 +- 3 files changed, 147 insertions(+), 14 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 6ab1f61a7..fcf32d9db 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -172,6 +172,7 @@ struct subvolume { grub_crypto_cipher_handle_t cipher; grub_uint64_t txg; + grub_uint64_t algo; } *keyring; }; @@ -205,13 +206,15 @@ struct grub_zfs_data }; grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, void *nonce, char *buf, grub_size_t size, const grub_uint32_t *expected_mac, grub_zfs_endian_t endian) = NULL; grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, grub_size_t keysize, - grub_uint64_t salt) = NULL; + grub_uint64_t salt, + grub_uint64_t algo) = NULL; static grub_err_t zlib_decompress (void *s, void *d, @@ -1535,6 +1538,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, grub_zfs_to_cpu64 (bp->blk_birth, endian)); err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher, + data->subvol.keyring[besti].algo, &(bp)->blk_dva[encrypted], compbuf, psize, ((grub_uint32_t *) &zc + 5), endian); @@ -2744,7 +2748,9 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, } subvol->keyring[keyn].txg = grub_be_to_cpu64 (*(grub_uint64_t *) name); - subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt); + subvol->keyring[keyn].algo = grub_le_to_cpu64 (*(grub_uint64_t *) val_in); + subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt, + subvol->keyring[keyn].algo); keyn++; return 0; } diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index d8c7181f0..39335a728 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -141,8 +141,132 @@ grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, return GRUB_ERR_NONE; } +static void +grub_gcm_mul_x (grub_uint8_t *a) +{ + int i; + int c = 0, d = 0; + for (i = 0; i < 16; i++) + { + c = a[i] & 0x1; + a[i] = (a[i] >> 1) | (d << 7); + d = c; + } + if (d) + a[0] ^= 0xe1; +} + +static void +grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b) +{ + grub_uint8_t res[16], bs[16]; + int i; + grub_memcpy (bs, b, 16); + grub_memset (res, 0, 16); + for (i = 0; i < 128; i++) + { + if ((a[i / 8] << (i % 8)) & 0x80) + grub_crypto_xor (res, res, bs, 16); + grub_gcm_mul_x (bs); + } + + grub_memcpy (a, res, 16); +} + static grub_err_t -grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, +grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned nonce_len, unsigned m) +{ + grub_uint8_t iv[16]; + grub_uint8_t mul[16]; + grub_uint8_t mac[16], h[16], mac_xor[16]; + unsigned i, j; + grub_err_t err; + + grub_memset (mac, 0, sizeof (mac)); + + err = grub_crypto_ecb_encrypt (cipher, h, mac, 16); + if (err) + return err; + + if (nonce_len == 12) + { + grub_memcpy (iv, nonce, 12); + iv[12] = 0; + iv[13] = 0; + iv[14] = 0; + iv[15] = 1; + } + else + { + grub_memset (iv, 0, sizeof (iv)); + grub_memcpy (iv, nonce, nonce_len); + grub_gcm_mul (iv, h); + iv[15] ^= nonce_len * 8; + grub_gcm_mul (iv, h); + } + + err = grub_crypto_ecb_encrypt (cipher, mac_xor, iv, 16); + if (err) + return err; + + for (i = 0; i < (psize + 15) / 16; i++) + { + grub_size_t csize; + csize = 16; + if (csize > psize - 16 * i) + csize = psize - 16 * i; + for (j = 0; j < 4; j++) + { + iv[15 - j]++; + if (iv[15 - j] != 0) + break; + } + grub_crypto_xor (mac, mac, in + 16 * i, csize); + grub_gcm_mul (mac, h); + err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); + if (err) + return err; + grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); + } + for (j = 0; j < 8; j++) + mac[15 - j] ^= ((psize * 8) >> (8 * j)); + grub_gcm_mul (mac, h); + + if (mac_out) + grub_crypto_xor (mac_out, mac, mac_xor, m); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, + grub_uint8_t *out, const grub_uint8_t *in, + grub_size_t psize, + void *mac_out, const void *nonce, + unsigned l, unsigned m) +{ + switch (algo) + { + case 0: + return grub_ccm_decrypt (cipher, out, in, psize, mac_out, nonce, l, m); + case 1: + return grub_gcm_decrypt (cipher, out, in, psize, mac_out, nonce, + 15 - l, m); + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "algorithm %" + PRIuGRUB_UINT64_T " is not supported yet", algo); + } +} + +static grub_err_t +grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, + void *nonce, char *buf, grub_size_t size, const grub_uint32_t *expected_mac, grub_zfs_endian_t endian) @@ -159,11 +283,11 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, if (!cipher) return grub_error (GRUB_ERR_ACCESS_DENIED, "no decryption key available");; - err = grub_ccm_decrypt (cipher, - (grub_uint8_t *) buf, - (grub_uint8_t *) buf, - size, mac, - sw + 1, 3, 12); + err = algo_decrypt (cipher, algo, + (grub_uint8_t *) buf, + (grub_uint8_t *) buf, + size, mac, + sw + 1, 3, 12); if (err) return err; @@ -177,7 +301,8 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, void *nonce, static grub_crypto_cipher_handle_t grub_zfs_load_key_real (const struct grub_zfs_key *key, grub_size_t keysize, - grub_uint64_t salt) + grub_uint64_t salt, + grub_uint64_t algo) { unsigned keylen; struct grub_zfs_wrap_key *wrap_key; @@ -227,8 +352,8 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, continue; } - err = grub_ccm_decrypt (cipher, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); + err = algo_decrypt (cipher, algo, decrypted, key->unknown_purpose_key, 32, + mac, key->unknown_purpose_nonce, 2, 16); if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) != 0)) { @@ -237,8 +362,8 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, continue; } - err = grub_ccm_decrypt (cipher, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); + err = algo_decrypt (cipher, algo, decrypted, key->enc_key, keylen, mac, + key->enc_nonce, 2, 16); if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) { grub_dprintf ("zfs", "key loading failed\n"); diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h index db8e915bf..e326c8b2f 100644 --- a/include/grub/zfs/zfs.h +++ b/include/grub/zfs/zfs.h @@ -135,6 +135,7 @@ grub_zfs_add_key (grub_uint8_t *key_in, int passphrase); extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, void *nonce, char *buf, grub_size_t size, const grub_uint32_t *expected_mac, @@ -144,7 +145,8 @@ struct grub_zfs_key; extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, grub_size_t keysize, - grub_uint64_t salt); + grub_uint64_t salt, + grub_uint64_t algo); From ae9a20d973284a143e798e06d292c63a1b3a793e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Nov 2011 21:08:32 +0100 Subject: [PATCH 1347/1414] Small cleanup --- grub-core/fs/zfs/zfs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index fcf32d9db..4d9a474fb 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1479,6 +1479,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (comp != ZIO_COMPRESS_OFF) { + /* It's not really necessary to align to 16, just for safety. */ compbuf = grub_malloc (ALIGN_UP (psize, 16)); if (! compbuf) return grub_errno; @@ -1878,9 +1879,6 @@ zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); - /* if (zap->zap_flags != 0) - return grub_error (GRUB_ERR_BAD_FS, "bad ZAP flags");*/ - if (zap->zap_salt == 0) return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); From ed64e9e27954718192e598d1f4bfaf0caba38152 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 11:23:56 +0100 Subject: [PATCH 1348/1414] Support trampoline jumps on powerpc. * grub-core/kern/dl.c (grub_dl_load_segments) [__powerpc__]: Follow __ia64__ path. (grub_dl_load_segments): Set mod->sz. (grub_dl_flush_cache): Flush whole space occupied by module, not just segments. * grub-core/kern/ia64/dl.c (nopm): Make const while on it. (jump): Likewise. * grub-core/kern/powerpc/dl.c (grub_arch_dl_get_tramp_got_size): New function. (trampoline): New struct. (trampoline_template): New const. (grub_arch_dl_relocate_symbols): Create trampolines on overflow. * include/grub/dl.h (grub_dl): Add sz element. [__powerpc__]: Follow __ia64__. (GRUB_ARCH_DL_TRAMP_ALIGN): Define on ppc. (GRUB_ARCH_DL_GOT_ALIGN): Likewise. (GRUB_ARCH_DL_TRAMP_SIZE): Likewise. (grub_arch_dl_get_tramp_got_size) [__powerpc__]: New proto. --- ChangeLog | 23 ++++++++++++ grub-core/kern/dl.c | 21 ++++------- grub-core/kern/ia64/dl.c | 4 +- grub-core/kern/powerpc/dl.c | 75 ++++++++++++++++++++++++++++++++++++- include/grub/dl.h | 15 +++++++- 5 files changed, 120 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 891126792..48799984d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2011-11-08 Vladimir Serbinenko + + Support trampoline jumps on powerpc. + + * grub-core/kern/dl.c (grub_dl_load_segments) [__powerpc__]: Follow + __ia64__ path. + (grub_dl_load_segments): Set mod->sz. + (grub_dl_flush_cache): Flush whole space occupied by module, not just + segments. + * grub-core/kern/ia64/dl.c (nopm): Make const while on it. + (jump): Likewise. + * grub-core/kern/powerpc/dl.c (grub_arch_dl_get_tramp_got_size): New + function. + (trampoline): New struct. + (trampoline_template): New const. + (grub_arch_dl_relocate_symbols): Create trampolines on overflow. + * include/grub/dl.h (grub_dl): Add sz element. + [__powerpc__]: Follow __ia64__. + (GRUB_ARCH_DL_TRAMP_ALIGN): Define on ppc. + (GRUB_ARCH_DL_GOT_ALIGN): Likewise. + (GRUB_ARCH_DL_TRAMP_SIZE): Likewise. + (grub_arch_dl_get_tramp_got_size) [__powerpc__]: New proto. + 2011-11-06 Vladimir Serbinenko ZFS crypto support. diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 1841bf1f5..b6fb537e8 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -233,7 +233,7 @@ 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__ +#if defined (__ia64__) || defined (__powerpc__) grub_size_t tramp; grub_size_t got; #endif @@ -248,9 +248,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) talign = s->sh_addralign; } -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - tramp *= GRUB_IA64_DL_TRAMP_SIZE; + tramp *= GRUB_ARCH_DL_TRAMP_SIZE; got *= sizeof (grub_uint64_t); tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) @@ -269,6 +269,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->base = grub_memalign (talign, tsize); if (!mod->base) return grub_errno; + mod->sz = tsize; ptr = mod->base; #ifdef GRUB_MACHINE_EMU @@ -316,7 +317,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->segment = seg; } } -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); mod->tramp = ptr; ptr += tramp; @@ -575,15 +576,9 @@ grub_dl_unref (grub_dl_t mod) static void grub_dl_flush_cache (grub_dl_t mod) { - grub_dl_segment_t seg; - - for (seg = mod->segment; seg; seg = seg->next) { - if (seg->size) { - grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", - (unsigned long) seg->size, seg->addr); - grub_arch_sync_caches (seg->addr, seg->size); - } - } + grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", + (unsigned long) mod->sz, mod->base); + grub_arch_sync_caches (mod->base, mod->sz); } /* Load a module from core memory. */ diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 3904f73b7..31b5f94cf 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -104,13 +104,13 @@ add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) } } -static grub_uint8_t nopm[5] = +static const grub_uint8_t nopm[5] = { /* [MLX] nop.m 0x0 */ 0x05, 0x00, 0x00, 0x00, 0x01 }; -static grub_uint8_t jump[0x20] = +static const grub_uint8_t jump[0x20] = { /* ld8 r16=[r15],8 */ 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c index ad19e5600..34e780a45 100644 --- a/grub-core/kern/powerpc/dl.c +++ b/grub-core/kern/powerpc/dl.c @@ -37,6 +37,65 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_NONE; } +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + *tramp = 0; + *got = 0; + + /* Find a symbol table. */ + for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((const 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 = (const Elf_Shdr *) ((const char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + const Elf_Rela *rel, *max; + + for (rel = (const Elf_Rela *) ((const char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + if (ELF_R_TYPE (rel->r_info) == R_PPC_REL24) + (*tramp)++; + + } + + return; +} + +/* For low-endian reverse lis and addr_high as well as ori and addr_low. */ +struct trampoline +{ + grub_uint32_t lis; + grub_uint32_t ori; + grub_uint32_t mtctr; + grub_uint32_t bctr; +}; + +static const struct trampoline trampoline_template = + { + 0x3c000000, + 0x60000000, + 0x7c0903a6, + 0x4e800420, + }; /* Relocate symbols. */ grub_err_t @@ -46,6 +105,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Shdr *s; Elf_Word entsize; unsigned i; + struct trampoline *tptr = mod->tramp; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); @@ -106,7 +166,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Sword delta = value - (Elf_Word) addr; if (delta << 6 >> 6 != delta) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); + { + COMPILE_TIME_ASSERT (sizeof (struct trampoline) + == GRUB_ARCH_DL_TRAMP_SIZE); + grub_memcpy (tptr, &trampoline_template, + sizeof (*tptr)); + delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr; + tptr->lis |= (((value) >> 16) & 0xffff); + tptr->ori |= ((value) & 0xffff); + tptr++; + } + + if (delta << 6 >> 6 != delta) + return grub_error (GRUB_ERR_BAD_MODULE, + "relocation overflow"); *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); break; } diff --git a/include/grub/dl.h b/include/grub/dl.h index 75cd71758..886e966cc 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -136,11 +136,12 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) void *got; void *tramp; #endif void *base; + grub_size_t sz; struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -176,10 +177,20 @@ void grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); -#ifdef __ia64__ +#if defined (__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 +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +#endif + +#ifdef __powerpc__ +#define GRUB_ARCH_DL_TRAMP_SIZE 16 +#define GRUB_ARCH_DL_TRAMP_ALIGN 4 +#define GRUB_ARCH_DL_GOT_ALIGN 4 #endif #endif From 9f421dd1f07e7be1b6dfbad162d44bcd5c57916a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 11:32:19 +0100 Subject: [PATCH 1349/1414] * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used variable. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48799984d..dd8a9858d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-08 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used + variable. + 2011-11-08 Vladimir Serbinenko Support trampoline jumps on powerpc. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 4d9a474fb..fb16a009b 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -2164,14 +2164,12 @@ zap_iterate (dnode_end_t * zap_dnode, struct grub_zfs_data *data) { grub_uint64_t block_type; - int size; void *zapbuf; grub_err_t err; int ret; grub_zfs_endian_t endian; /* Read in the first block of the zap object data. */ - size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); if (err) return 0; From 78e08dc3cb36e163b2a1e96bf828c1ed0ae9f323 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 12:06:27 +0100 Subject: [PATCH 1350/1414] * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. --- ChangeLog | 4 ++++ util/grub.d/10_kfreebsd.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dd8a9858d..02af51ea8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-08 Vladimir Serbinenko + + * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. + 2011-11-08 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index e668f3fd9..a1b86b82b 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -160,7 +160,7 @@ while [ "x$list" != "x" ] ; do # zpool name kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) # filesystem name (empty string for the main filesystem) - kfreebsd_device="${kfreebsd_device}$(grub-mkrelpath / | sed -e "s,/*@$,,")" + kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} / | sed -e "s,/*@$,,")" ;; *) kfreebsd_device=${kfreebsd_fs}id/${GRUB_DEVICE_UUID} From cac14fb663e637f8bb944cb3aab16ce9040840b5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 12:15:57 +0100 Subject: [PATCH 1351/1414] Support escaped commas in hostdisk. * grub-core/kern/emu/hostdisk.c (unescape_cmp): New function. (find_grub_drive): Use unescape_cmp. (make_device_name): Escape commas. --- ChangeLog | 8 +++++ grub-core/kern/emu/hostdisk.c | 58 +++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02af51ea8..c7f8d3c7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-08 Vladimir Serbinenko + + Support escaped commas in hostdisk. + + * grub-core/kern/emu/hostdisk.c (unescape_cmp): New function. + (find_grub_drive): Use unescape_cmp. + (make_device_name): Escape commas. + 2011-11-08 Vladimir Serbinenko * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 23417a64d..4d5c28631 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -184,6 +184,27 @@ configure_device_driver (int fd) } #endif /* defined(__NetBSD__) */ +static int +unescape_cmp (const char *a, const char *b_escaped) +{ + while (*a || *b_escaped) + { + if (*b_escaped == '\\' && b_escaped[1] != 0) + b_escaped++; + if (*a < *b_escaped) + return -1; + if (*a > *b_escaped) + return +1; + a++; + b_escaped++; + } + if (*a) + return +1; + if (*b_escaped) + return -1; + return 0; +} + static int find_grub_drive (const char *name) { @@ -192,7 +213,7 @@ find_grub_drive (const char *name) if (name) { for (i = 0; i < ARRAY_SIZE (map); i++) - if (map[i].drive && ! strcmp (map[i].drive, name)) + if (map[i].drive && unescape_cmp (map[i].drive, name) == 0) return i; } @@ -1140,25 +1161,28 @@ grub_util_biosdisk_fini (void) static char * make_device_name (int drive, int dos_part, int bsd_part) { - char *ret; - char *dos_part_str = NULL; - char *bsd_part_str = NULL; + char *ret, *ptr, *end; + const char *iptr; + ret = xmalloc (strlen (map[drive].drive) * 2 + + sizeof (",XXXXXXXXXXXXXXXXXXXXXXXXXX" + ",XXXXXXXXXXXXXXXXXXXXXXXXXX")); + end = (ret + strlen (map[drive].drive) * 2 + + sizeof (",XXXXXXXXXXXXXXXXXXXXXXXXXX" + ",XXXXXXXXXXXXXXXXXXXXXXXXXX")); + ptr = ret; + for (iptr = map[drive].drive; *iptr; iptr++) + { + if (*iptr == ',') + *ptr++ = '\\'; + *ptr++ = *iptr; + } + *ptr = 0; if (dos_part >= 0) - dos_part_str = xasprintf (",%d", dos_part + 1); - + snprintf (ptr, end - ptr, ",%d", dos_part + 1); + ptr += strlen (ptr); if (bsd_part >= 0) - bsd_part_str = xasprintf (",%d", bsd_part + 1); - - ret = xasprintf ("%s%s%s", map[drive].drive, - dos_part_str ? : "", - bsd_part_str ? : ""); - - if (dos_part_str) - free (dos_part_str); - - if (bsd_part_str) - free (bsd_part_str); + snprintf (ptr, end - ptr, ",%d", bsd_part + 1); return ret; } From 958ee2216874b6587ff0534fa7030e06a58167ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 12:38:30 +0100 Subject: [PATCH 1352/1414] Illumos support. * Makefile.util.def (10_illumos): New script. * configure.ac: Set COND_HOST_ILLUMOS. * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__sun__]: Support Illumos calls. (find_partition_start) [__sun__]: Likewise. (convert_system_partition_to_system_disk) [__sun__]: Likewise. (device_is_wholedisk) [__sun__]: Handle Illumos naming scheme. (grub_util_biosdisk_get_grub_dev) [__sun__]: Handle Illumos. * util/getroot.c (find_root_device_from_libzfs) [__sun__]: Return raw device. * util/grub-probe.c (probe) [__sun__]: Do character check. * util/grub.d/10_illumos.in: New file. --- ChangeLog | 17 +++++++++ Makefile.util.def | 7 ++++ configure.ac | 2 + grub-core/kern/emu/hostdisk.c | 72 +++++++++++++++++++++++++++++------ util/getroot.c | 19 ++++++++- util/grub-probe.c | 2 +- util/grub.d/10_illumos.in | 54 ++++++++++++++++++++++++++ 7 files changed, 159 insertions(+), 14 deletions(-) create mode 100644 util/grub.d/10_illumos.in diff --git a/ChangeLog b/ChangeLog index c7f8d3c7b..edb0b2c10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-11-08 Vladimir Serbinenko + + Illumos support. + + * Makefile.util.def (10_illumos): New script. + * configure.ac: Set COND_HOST_ILLUMOS. + * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__sun__]: + Support Illumos calls. + (find_partition_start) [__sun__]: Likewise. + (convert_system_partition_to_system_disk) [__sun__]: Likewise. + (device_is_wholedisk) [__sun__]: Handle Illumos naming scheme. + (grub_util_biosdisk_get_grub_dev) [__sun__]: Handle Illumos. + * util/getroot.c (find_root_device_from_libzfs) [__sun__]: Return raw + device. + * util/grub-probe.c (probe) [__sun__]: Do character check. + * util/grub.d/10_illumos.in: New file. + 2011-11-08 Vladimir Serbinenko Support escaped commas in hostdisk. diff --git a/Makefile.util.def b/Makefile.util.def index 15a309367..8742d1583 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -367,6 +367,13 @@ script = { condition = COND_HOST_KFREEBSD; }; +script = { + name = '10_illumos'; + common = util/grub.d/10_illumos.in; + installdir = grubconf; + condition = COND_HOST_ILLUMOS; +}; + script = { name = '10_netbsd'; common = util/grub.d/10_netbsd.in; diff --git a/configure.ac b/configure.ac index 6aafdf13d..e707081a7 100644 --- a/configure.ac +++ b/configure.ac @@ -154,6 +154,7 @@ case "$host_os" in linux*) host_kernel=linux ;; freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;; netbsd*) host_kernel=netbsd ;; + solaris*) host_kernel=illumos ;; cygwin) host_kernel=windows ;; esac @@ -974,6 +975,7 @@ AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd]) AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows]) AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd]) +AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes]) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 4d5c28631..7074fa8c1 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -98,6 +98,10 @@ struct hd_geometry # define FLOPPY_MAJOR 2 #endif +#if defined (__sun__) +# include +#endif + #if defined(__APPLE__) # include #endif @@ -252,11 +256,11 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), grub_uint64_t grub_util_get_fd_sectors (int fd, unsigned *log_secsize) { -#if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) # if defined(__NetBSD__) struct disklabel label; -# else +# elif defined (__sun__) + struct dk_minfo minfo; +#else unsigned long long nr; # endif unsigned sector_size, log_sector_size; @@ -265,7 +269,11 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) if (fstat (fd, &st) < 0) grub_util_error ("fstat failed"); -# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) \ + || defined (__sun__) + +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) if (! S_ISCHR (st.st_mode)) # else if (! S_ISBLK (st.st_mode)) @@ -279,6 +287,8 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # elif defined(__NetBSD__) configure_device_driver (fd); if (ioctl (fd, DIOCGDINFO, &label) == -1) +# elif defined (__sun__) + if (!ioctl (fd, DKIOCGMEDIAINFO, &minfo)) # else if (ioctl (fd, BLKGETSIZE64, &nr)) # endif @@ -287,13 +297,14 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (ioctl (fd, DIOCGSECTORSIZE, §or_size)) goto fail; +# elif defined(__sun__) + sector_size = minfo.dki_lbsize; # elif defined(__NetBSD__) sector_size = label.d_secsize; # else if (ioctl (fd, BLKSSZGET, §or_size)) goto fail; # endif - if (sector_size & (sector_size - 1) || !sector_size) goto fail; for (log_sector_size = 0; @@ -307,6 +318,8 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) return nr; # elif defined(__NetBSD__) return label.d_secperunit; +# elif defined (__sun__) + return minfo.dki_capacity; # else if (nr & ((1 << log_sector_size) - 1)) grub_util_error ("unaligned device size"); @@ -315,11 +328,15 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) # endif fail: + /* In GNU/Hurd, stat() will return the right size. */ #elif !defined (__GNU__) # warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." #endif + sector_size = 512; + log_sector_size = 9; + if (log_secsize) *log_secsize = 9; @@ -419,12 +436,14 @@ find_partition_start (const char *dev) return out; } -#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) +#elif defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined (__sun__) static grub_disk_addr_t find_partition_start (const char *dev) { int fd; -# if !defined(HAVE_DIOCGDINFO) +#ifdef __sun__ + struct extpart_info pinfo; +# elif !defined(HAVE_DIOCGDINFO) struct hd_geometry hdg; # else /* defined(HAVE_DIOCGDINFO) */ struct disklabel label; @@ -511,7 +530,9 @@ devmapper_fail: return 0; } -# if !defined(HAVE_DIOCGDINFO) +#if defined(__sun__) + if (ioctl (fd, DKIOCEXTPARTINFO, &pinfo)) +# elif !defined(HAVE_DIOCGDINFO) if (ioctl (fd, HDIO_GETGEO, &hdg)) # else /* defined(HAVE_DIOCGDINFO) */ # if defined(__NetBSD__) @@ -532,7 +553,9 @@ devmapper_fail: close (fd); -# if !defined(HAVE_DIOCGDINFO) +#ifdef __sun__ + return pinfo.p_start; +# elif !defined(HAVE_DIOCGDINFO) return hdg.start; # else /* defined(HAVE_DIOCGDINFO) */ if (dev[0]) @@ -1568,12 +1591,37 @@ devmapper_out: } return path; +#elif defined (__sun__) + char *colon = grub_strrchr (os_dev, ':'); + if (grub_memcmp (os_dev, "/devices", sizeof ("/devices") - 1) == 0 + && colon) + { + char *ret = xmalloc (colon - os_dev + sizeof (":q,raw")); + grub_memcpy (ret, os_dev, colon - os_dev); + grub_memcpy (ret + (colon - os_dev), ":q,raw", sizeof (":q,raw")); + return ret; + } + else + return xstrdup (os_dev); #else # warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly." return xstrdup (os_dev); #endif } +#if defined(__sun__) +static int +device_is_wholedisk (const char *os_dev) +{ + if (grub_memcmp (os_dev, "/devices/", sizeof ("/devices/") - 1) != 0) + return 1; + if (grub_memcmp (os_dev + strlen (os_dev) - (sizeof (":q,raw") - 1), + ":q,raw", (sizeof (":q,raw") - 1)) == 0) + return 1; + return 0; +} +#endif + #if defined(__linux__) || defined(__CYGWIN__) static int device_is_wholedisk (const char *os_dev) @@ -1700,14 +1748,14 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) convert_system_partition_to_system_disk (os_dev, &st)) == 0) return make_device_name (drive, -1, -1); -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) if (! S_ISCHR (st.st_mode)) #else if (! S_ISBLK (st.st_mode)) #endif return make_device_name (drive, -1, -1); -#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__sun__) /* Linux counts partitions uniformly, whether a BSD partition or a DOS partition, so mapping them to GRUB devices is not trivial. @@ -1747,7 +1795,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) name = make_device_name (drive, -1, -1); -# if !defined(HAVE_DIOCGDINFO) +# if !defined(HAVE_DIOCGDINFO) && !defined(__sun__) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) return name; # else /* defined(HAVE_DIOCGDINFO) */ diff --git a/util/getroot.c b/util/getroot.c index 3d6f9370c..8fce283bc 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -61,6 +61,11 @@ # include #endif +#ifdef __sun__ +# include +# include +#endif + #include #include #include @@ -289,7 +294,19 @@ find_root_device_from_libzfs (const char *dir) struct stat st; if (stat (device, &st) == 0) { - device = xstrdup (device); +#ifdef __sun__ + if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1) + == 0) + device = xasprintf ("/dev/rdsk/%s", + device + sizeof ("/dev/dsk/") - 1); + else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1) + == 0 + && grub_memcmp (device + strlen (device) - 4, + ",raw", 4) != 0) + device = xasprintf ("%s,raw", device); + else +#endif + device = xstrdup (device); break; } diff --git a/util/grub-probe.c b/util/grub-probe.c index ae58c89f3..54b9d03c6 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -171,7 +171,7 @@ probe (const char *path, char *device_name) if (path == NULL) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__sun__) if (! grub_util_check_char_device (device_name)) grub_util_error ("%s is not a character device", device_name); #else diff --git a/util/grub.d/10_illumos.in b/util/grub.d/10_illumos.in new file mode 100644 index 000000000..2b87dfa4f --- /dev/null +++ b/util/grub.d/10_illumos.in @@ -0,0 +1,54 @@ +#! /bin/sh +set -e + +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,2008,2009,2010,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 . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +datarootdir=@datarootdir@ +. ${libdir}/@PACKAGE@/grub-mkconfig_lib + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR=@localedir@ + +CLASS="--class os" + +case "${GRUB_DISTRIBUTOR}" in + *) + OS="Illumos" + CLASS="--class illumos ${CLASS}" + ;; +esac + +echo "menuentry '${OS}' ${CLASS} {" +save_default_entry | sed -e "s/^/\t/" +prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" +message="$(gettext_printf "Loading kernel of Illumos ...")" + cat << EOF + insmod gzio + if cpuid -l ; then + ISADIR=amd64 + else + ISADIR= + fi + zfs-bootfs $($grub_mkrelpath /) ZFS_BOOTFS + multiboot $($grub_mkrelpath /platform/i86pc/kernel)/\$ISADIR/unix /platform/i86pc/kernel/\$ISADIR/unix -B \$ZFS_BOOTFS,console=text + module $($grub_mkrelpath /platform/i86pc)/\$ISADIR/boot_archive /platform/i86pc/\$ISADIR/boot_archive +} +EOF From 4a19b6017d989c076b06861d3bfd6ba6d3fa9c75 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 16:07:27 +0100 Subject: [PATCH 1353/1414] Fix ZFS crypto error types. * grub-core/fs/zfs/zfscrypt.c (grub_ccm_decrypt): Fix return type. (grub_gcm_decrypt): Likewise. (grub_zfs_load_key_real): Fix error code type. Handle possible error from PBKDF2. --- ChangeLog | 9 +++++++++ grub-core/fs/zfs/zfscrypt.c | 28 +++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index edb0b2c10..194bd13fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-08 Vladimir Serbinenko + + Fix ZFS crypto error types. + + * grub-core/fs/zfs/zfscrypt.c (grub_ccm_decrypt): Fix return type. + (grub_gcm_decrypt): Likewise. + (grub_zfs_load_key_real): Fix error code type. Handle possible error + from PBKDF2. + 2011-11-08 Vladimir Serbinenko Illumos support. diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 39335a728..14babd29f 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -90,7 +90,7 @@ grub_zfs_add_key (grub_uint8_t *key_in, return GRUB_ERR_NONE; } -static grub_err_t +static gcry_err_code_t grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t *out, const grub_uint8_t *in, grub_size_t psize, @@ -101,7 +101,7 @@ grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t mul[16]; grub_uint32_t mac[4]; unsigned i, j; - grub_err_t err; + gcry_err_code_t err; grub_memcpy (iv + 1, nonce, 15 - l); @@ -173,7 +173,7 @@ grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b) grub_memcpy (a, res, 16); } -static grub_err_t +static gcry_err_code_t grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t *out, const grub_uint8_t *in, grub_size_t psize, @@ -184,7 +184,7 @@ grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint8_t mul[16]; grub_uint8_t mac[16], h[16], mac_xor[16]; unsigned i, j; - grub_err_t err; + gcry_err_code_t err; grub_memset (mac, 0, sizeof (mac)); @@ -243,7 +243,7 @@ grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, } -static grub_err_t +static gcry_err_code_t algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, grub_uint8_t *out, const grub_uint8_t *in, grub_size_t psize, @@ -307,7 +307,6 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, unsigned keylen; struct grub_zfs_wrap_key *wrap_key; grub_crypto_cipher_handle_t ret = NULL; - grub_err_t err; if (keysize != sizeof (*key)) { @@ -327,6 +326,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, { grub_crypto_cipher_handle_t cipher; grub_uint8_t decrypted[32], mac[32], wrap_key_real[32]; + gcry_err_code_t err; cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); if (!cipher) { @@ -334,15 +334,21 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, return 0; } grub_memset (wrap_key_real, 0, sizeof (wrap_key_real)); + err = 0; if (!wrap_key->is_passphrase) grub_memcpy(wrap_key_real, wrap_key->key, wrap_key->keylen < keylen ? wrap_key->keylen : keylen); else - grub_crypto_pbkdf2 (GRUB_MD_SHA1, - (const grub_uint8_t *) wrap_key->key, - wrap_key->keylen, - (const grub_uint8_t *) &salt, sizeof (salt), - 1000, wrap_key_real, keylen); + err = grub_crypto_pbkdf2 (GRUB_MD_SHA1, + (const grub_uint8_t *) wrap_key->key, + wrap_key->keylen, + (const grub_uint8_t *) &salt, sizeof (salt), + 1000, wrap_key_real, keylen); + if (err) + { + grub_errno = GRUB_ERR_NONE; + continue; + } err = grub_crypto_cipher_set_key (cipher, wrap_key_real, keylen); From 27610c3836e79f8c8d8838b8f3121924a9e60500 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 19:34:19 +0100 Subject: [PATCH 1354/1414] Fix FreeBSD compilation. * grub-core/disk/geli.c (GRUB_MD_SHA256) [GRUB_UTIL]: Redefine in a way to avoid circular dependency. (GRUB_MD_SHA512) [GRUB_UTIL]: Likewise. * util/getroot.c (grub_util_follow_gpart_up): Move from here... * grub-core/kern/emu/hostdisk.c (+grub_util_follow_gpart_up): ... here. --- ChangeLog | 10 +++++++ grub-core/disk/geli.c | 32 +++++++++++++++++++++ grub-core/kern/emu/hostdisk.c | 53 +++++++++++++++++++++++++++++++++++ util/getroot.c | 50 --------------------------------- 4 files changed, 95 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index 194bd13fa..925b798bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-08 Vladimir Serbinenko + + Fix FreeBSD compilation. + + * grub-core/disk/geli.c (GRUB_MD_SHA256) [GRUB_UTIL]: Redefine in a way + to avoid circular dependency. + (GRUB_MD_SHA512) [GRUB_UTIL]: Likewise. + * util/getroot.c (grub_util_follow_gpart_up): Move from here... + * grub-core/kern/emu/hostdisk.c (+grub_util_follow_gpart_up): ... here. + 2011-11-08 Vladimir Serbinenko Fix ZFS crypto error types. diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index d2ae5da56..ab94b4131 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -58,6 +58,38 @@ GRUB_MOD_LICENSE ("GPLv3+"); +/* Dirty trick to solve circular dependency. */ +#ifdef GRUB_UTIL + +#include + +#undef GRUB_MD_SHA256 +#undef GRUB_MD_SHA512 + +static const gcry_md_spec_t * +grub_md_sha256_real (void) +{ + const gcry_md_spec_t *ret; + ret = grub_crypto_lookup_md_by_name ("sha256"); + if (!ret) + grub_util_error ("Coulnd't load sha256"); + return ret; +} + +static const gcry_md_spec_t * +grub_md_sha512_real (void) +{ + const gcry_md_spec_t *ret; + ret = grub_crypto_lookup_md_by_name ("sha512"); + if (!ret) + grub_util_error ("Coulnd't load sha512"); + return ret; +} + +#define GRUB_MD_SHA256 grub_md_sha256_real() +#define GRUB_MD_SHA512 grub_md_sha512_real() +#endif + struct grub_geli_key { grub_uint8_t iv_key[64]; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 7074fa8c1..7bfc66fef 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -94,6 +94,8 @@ struct hd_geometry # include /* DIOCGMEDIASIZE */ # include # include +# include +#include # define MAJOR(dev) major(dev) # define FLOPPY_MAJOR 2 #endif @@ -423,8 +425,59 @@ grub_util_device_is_mapped (const char *dev) #endif /* HAVE_DEVICE_MAPPER */ } + #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) +/* FIXME: geom actually gives us the whole container hierarchy. + It can be used more efficiently than this. */ +void +grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out) +{ + struct gmesh mesh; + struct gclass *class; + int error; + struct ggeom *geom; + + grub_util_info ("following geom '%s'", name); + + error = geom_gettree (&mesh); + if (error != 0) + grub_util_error ("couldn't open geom"); + + LIST_FOREACH (class, &mesh.lg_class, lg_class) + if (strcasecmp (class->lg_name, "part") == 0) + break; + if (!class) + grub_util_error ("couldn't open geom part"); + + LIST_FOREACH (geom, &class->lg_geom, lg_geom) + { + struct gprovider *provider; + LIST_FOREACH (provider, &geom->lg_provider, lg_provider) + if (strcmp (provider->lg_name, name) == 0) + { + char *name_tmp = xstrdup (geom->lg_name); + grub_disk_addr_t off = 0; + struct gconfig *config; + grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); + + grub_util_follow_gpart_up (name_tmp, &off, name_out); + free (name_tmp); + LIST_FOREACH (config, &provider->lg_config, lg_config) + if (strcasecmp (config->lg_name, "start") == 0) + off += strtoull (config->lg_val, 0, 10); + if (off_out) + *off_out = off; + return; + } + } + grub_util_info ("geom '%s' has no parent", name); + if (name_out) + *name_out = xstrdup (name); + if (off_out) + *off_out = 0; +} + static grub_disk_addr_t find_partition_start (const char *dev) { diff --git a/util/getroot.c b/util/getroot.c index 8fce283bc..41fbdec10 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -790,56 +790,6 @@ grub_util_get_dm_abstraction (const char *os_dev) #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) #include -/* FIXME: geom actually gives us the whole container hierarchy. - It can be used more efficiently than this. */ -void -grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out) -{ - struct gmesh mesh; - struct gclass *class; - int error; - struct ggeom *geom; - - grub_util_info ("following geom '%s'", name); - - error = geom_gettree (&mesh); - if (error != 0) - grub_util_error ("couldn't open geom"); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - if (strcasecmp (class->lg_name, "part") == 0) - break; - if (!class) - grub_util_error ("couldn't open geom part"); - - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - { - char *name_tmp = xstrdup (geom->lg_name); - grub_disk_addr_t off = 0; - struct gconfig *config; - grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); - - grub_util_follow_gpart_up (name_tmp, &off, name_out); - free (name_tmp); - LIST_FOREACH (config, &provider->lg_config, lg_config) - if (strcasecmp (config->lg_name, "start") == 0) - off += strtoull (config->lg_val, 0, 10); - if (off_out) - *off_out = off; - return; - } - } - grub_util_info ("geom '%s' has no parent", name); - if (name_out) - *name_out = xstrdup (name); - if (off_out) - *off_out = 0; -} - static const char * grub_util_get_geom_abstraction (const char *dev) { From 3ae17eb83c25cd9b82a8e49a3235168661d8cdbe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 19:44:18 +0100 Subject: [PATCH 1355/1414] Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. * grub-core/fs/zfs/zfscrypt.c (grub_zfs_decrypt_real): Use explicit byteswap when needed. --- ChangeLog | 7 +++++++ grub-core/fs/zfs/zfscrypt.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 925b798bc..b23f5156d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-08 Vladimir Serbinenko + + Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. + + * grub-core/fs/zfs/zfscrypt.c (grub_zfs_decrypt_real): Use explicit + byteswap when needed. + 2011-11-08 Vladimir Serbinenko Fix FreeBSD compilation. diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 14babd29f..13f62b25a 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -277,8 +277,9 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, grub_err_t err; grub_memcpy (sw, nonce, 16); - for (i = 0; i < 4; i++) - sw[i] = grub_cpu_to_be32 (grub_zfs_to_cpu32 (sw[i], endian)); + if (endian != GRUB_ZFS_BIG_ENDIAN) + for (i = 0; i < 4; i++) + sw[i] = grub_swap_bytes32 (sw[i]); if (!cipher) return grub_error (GRUB_ERR_ACCESS_DENIED, From 49a45021c1430b481ef4c0be95912e065aa9402f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 19:46:41 +0100 Subject: [PATCH 1356/1414] * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not used variable. * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): Likewise. --- ChangeLog | 7 +++++++ grub-core/kern/ia64/dl_helper.c | 3 --- grub-core/lib/LzmaEnc.c | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b23f5156d..b7bd30183 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-08 Vladimir Serbinenko + + * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not + used variable. + * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): + Likewise. + 2011-11-08 Vladimir Serbinenko Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c index 91f28026e..958cdb25e 100644 --- a/grub-core/kern/ia64/dl_helper.c +++ b/grub-core/kern/ia64/dl_helper.c @@ -30,7 +30,6 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, const Elf64_Ehdr *e = ehdr; grub_size_t cntt = 0, cntg = 0;; const Elf64_Shdr *s; - Elf64_Word entsize; unsigned i; /* Find a symbol table. */ @@ -43,8 +42,6 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, if (i == grub_le_to_cpu16 (e->e_shnum)) return; - entsize = s->sh_entsize; - 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))) diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c index 01ffa91f9..258ed9c91 100644 --- a/grub-core/lib/LzmaEnc.c +++ b/grub-core/lib/LzmaEnc.c @@ -1994,13 +1994,15 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) { UInt32 beforeSize = kNumOpts; +#ifdef COMPRESS_MF_MT Bool btMode; +#endif if (!RangeEnc_Alloc(&p->rc, alloc)) return SZ_ERROR_MEM; +#ifdef COMPRESS_MF_MT btMode = (p->matchFinderBase.btMode != 0); - #ifdef COMPRESS_MF_MT p->mtMode = (p->multiThread && !p->fastMode && btMode); - #endif +#endif { unsigned lclp = p->lc + p->lp; From 438a746a3ff63ed0428818a4f03b181431199747 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 8 Nov 2011 20:03:06 +0100 Subject: [PATCH 1357/1414] * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed with no error set. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfs.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b7bd30183..f8f424176 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-08 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed + with no error set. + 2011-11-08 Vladimir Serbinenko * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index fb16a009b..f85d56e99 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -1324,7 +1324,7 @@ read_dva (const dva_t *dva, { grub_uint64_t offset; unsigned i; - grub_err_t err; + grub_err_t err = 0; int try = 0; offset = dva_get_offset (dva, endian); @@ -1344,6 +1344,9 @@ read_dva (const dva_t *dva, if (err) return err; } + if (!err) + return grub_error (GRUB_ERR_BAD_FS, "unknown device %d", + (int) DVA_GET_VDEV (dva)); return err; } From 52b656c037a679c74e9c49dd2c92f289a18b2d4c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 11:43:39 +0100 Subject: [PATCH 1358/1414] Several AFFS fixes. * grub-core/fs/affs.c (grub_affs_bblock): Replace flags with version. (GRUB_AFFS_FLAG_FFS): Removed. (GRUB_AFFS_SYMLINK_SIZE): Likewise. (GRUB_AFFS_FILETYPE_DIR): Make positive and unsigned. (GRUB_AFFS_FILETYPE_DIR), (GRUB_AFFS_FILETYPE_REG): Fix a mix-up. (grub_fshelp_node): Make block 32-bit. Add block_cache and last_block_cache. (grub_affs_read_block): Fill and use block cache. (grub_affs_read_file): Removed. (grub_affs_mount): Zero-fill node. Fix version check. Don't reread boot block. (grub_affs_read_symlink): Fix symlink size. Add a \0 at the end for safety. (grub_affs_iterate_dir): Use more appropriate types. Zero-fill allocated space. (grub_affs_close): Free block cache. (grub_affs_read): Use grub_fshelp_read_file directly. --- ChangeLog | 22 +++++++++ grub-core/fs/affs.c | 111 +++++++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8f424176..035f18194 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2011-11-09 Vladimir Serbinenko + + Several AFFS fixes. + + * grub-core/fs/affs.c (grub_affs_bblock): Replace flags with version. + (GRUB_AFFS_FLAG_FFS): Removed. + (GRUB_AFFS_SYMLINK_SIZE): Likewise. + (GRUB_AFFS_FILETYPE_DIR): Make positive and unsigned. + (GRUB_AFFS_FILETYPE_DIR), (GRUB_AFFS_FILETYPE_REG): Fix a mix-up. + (grub_fshelp_node): Make block 32-bit. + Add block_cache and last_block_cache. + (grub_affs_read_block): Fill and use block cache. + (grub_affs_read_file): Removed. + (grub_affs_mount): Zero-fill node. Fix version check. Don't reread + boot block. + (grub_affs_read_symlink): Fix symlink size. Add a \0 at the end for + safety. + (grub_affs_iterate_dir): Use more appropriate types. Zero-fill allocated + space. + (grub_affs_close): Free block cache. + (grub_affs_read): Use grub_fshelp_read_file directly. + 2011-11-08 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index adf2932bd..06f41c4c3 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -32,15 +32,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct grub_affs_bblock { grub_uint8_t type[3]; - grub_uint8_t flags; + grub_uint8_t version; grub_uint32_t checksum; grub_uint32_t rootblock; } __attribute__ ((packed)); -/* Set if the filesystem is a AFFS filesystem. Otherwise this is an - OFS filesystem. */ -#define GRUB_AFFS_FLAG_FFS 1 - /* The affs rootblock. */ struct grub_affs_rblock { @@ -85,19 +81,19 @@ struct grub_affs_file #define GRUB_AFFS_BLOCKPTR_OFFSET 24 #define GRUB_AFFS_SYMLINK_OFFSET 24 -#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225) - -#define GRUB_AFFS_FILETYPE_DIR -3 -#define GRUB_AFFS_FILETYPE_REG 2 +#define GRUB_AFFS_FILETYPE_REG 0xfffffffd +#define GRUB_AFFS_FILETYPE_DIR 2 #define GRUB_AFFS_FILETYPE_SYMLINK 3 struct grub_fshelp_node { struct grub_affs_data *data; - grub_disk_addr_t block; + grub_uint32_t block; struct grub_fshelp_node *parent; struct grub_affs_file di; + grub_uint32_t *block_cache; + grub_uint32_t last_block_cache; }; /* Information about a "mounted" affs filesystem. */ @@ -120,32 +116,46 @@ static grub_dl_t my_mod; static grub_disk_addr_t grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { - int links; + grub_uint32_t target, curblock; grub_uint32_t pos; - int block = node->block; struct grub_affs_file file; struct grub_affs_data *data = node->data; grub_uint64_t mod; + if (!node->block_cache) + { + node->block_cache = grub_malloc ((((grub_be_to_cpu32 (node->di.size) + + 511) >> 9) / data->htsize + 1) + * sizeof (node->block_cache[0])); + if (!node->block_cache) + return -1; + node->last_block_cache = 0; + node->block_cache[0] = node->block; + } + + /* Files are at most 2G on AFFS, so no need for 64-bit division. */ + target = (grub_uint32_t) fileblock / data->htsize; + mod = (grub_uint32_t) fileblock % data->htsize; /* Find the block that points to the fileblock we are looking up by following the chain until the right table is reached. */ - for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--) + for (curblock = node->last_block_cache + 1; curblock <= target; curblock++) { - grub_disk_read (data->disk, block + data->blocksize - 1, + grub_disk_read (data->disk, + node->block_cache[curblock - 1] + data->blocksize - 1, data->blocksize * (GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION), sizeof (file), &file); if (grub_errno) return 0; - block = grub_be_to_cpu32 (file.extension); + node->block_cache[curblock] = grub_be_to_cpu32 (file.extension); + node->last_block_cache = curblock; } /* Translate the fileblock to the block within the right table. */ - fileblock = mod; - grub_disk_read (data->disk, block, + grub_disk_read (data->disk, node->block_cache[target], GRUB_AFFS_BLOCKPTR_OFFSET - + (data->htsize - fileblock - 1) * sizeof (pos), + + (data->htsize - mod - 1) * sizeof (pos), sizeof (pos), &pos); if (grub_errno) return 0; @@ -153,21 +163,6 @@ grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) return grub_be_to_cpu32 (pos); } - -/* Read LEN bytes from the file described by DATA starting with byte - POS. Return the amount of read bytes in READ. */ -static grub_ssize_t -grub_affs_read_file (grub_fshelp_node_t node, - void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, - unsigned offset, unsigned length), - grub_off_t pos, grub_size_t len, char *buf) -{ - return grub_fshelp_read_file (node->data->disk, node, read_hook, - pos, len, buf, grub_affs_read_block, - grub_be_to_cpu32 (node->di.size), 0); -} - - static struct grub_affs_data * grub_affs_mount (grub_disk_t disk) { @@ -178,7 +173,7 @@ grub_affs_mount (grub_disk_t disk) int checksum = 0; int blocksize = 0; - data = grub_malloc (sizeof (struct grub_affs_data)); + data = grub_zalloc (sizeof (struct grub_affs_data)); if (!data) return 0; @@ -196,18 +191,12 @@ grub_affs_mount (grub_disk_t disk) } /* Test if the filesystem is a OFS filesystem. */ - if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS)) + if (data->bblock.version < 1) { grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported"); goto fail; } - /* Read the bootblock. */ - grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock), - &data->bblock); - if (grub_errno) - goto fail; - /* No sane person uses more than 8KB for a block. At least I hope for that person because in that case this won't work. */ rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16); @@ -270,18 +259,21 @@ grub_affs_read_symlink (grub_fshelp_node_t node) { struct grub_affs_data *data = node->data; char *symlink; + const grub_size_t symlink_size = (data->blocksize * GRUB_DISK_SECTOR_SIZE + - 225); - symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize)); + symlink = grub_malloc (symlink_size + 1); if (!symlink) return 0; grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET, - GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink); + symlink_size, symlink); if (grub_errno) { grub_free (symlink); return 0; } + symlink[symlink_size] = 1; grub_dprintf ("affs", "Symlink: `%s'\n", symlink); return symlink; } @@ -301,24 +293,24 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, grub_uint32_t *hashtable; auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, - grub_disk_addr_t block, + grub_uint32_t block, const struct grub_affs_file *fil); int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, - grub_disk_addr_t block, + grub_uint32_t block, const struct grub_affs_file *fil) { int type; - node = grub_malloc (sizeof (*node)); + node = grub_zalloc (sizeof (*node)); if (!node) { grub_free (hashtable); return 1; } - if ((int) grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR) + if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG) type = GRUB_FSHELP_REG; - else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_REG) + else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_DIR) type = GRUB_FSHELP_DIR; else if (grub_be_to_cpu32 (fil->type) == GRUB_AFFS_FILETYPE_SYMLINK) type = GRUB_FSHELP_SYMLINK; @@ -339,7 +331,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, } /* Create the directory entries for `.' and `..'. */ - node = grub_malloc (sizeof (*node)); + node = grub_zalloc (sizeof (*node)); if (!node) return 1; @@ -348,7 +340,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 1; if (dir->parent) { - node = grub_malloc (sizeof (*node)); + node = grub_zalloc (sizeof (*node)); if (!node) return 1; *node = *dir->parent; @@ -356,7 +348,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 1; } - hashtable = grub_malloc (data->htsize * sizeof (*hashtable)); + hashtable = grub_zalloc (data->htsize * sizeof (*hashtable)); if (!hashtable) return 1; @@ -367,7 +359,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, for (i = 0; i < data->htsize; i++) { - grub_uint64_t next; + grub_uint32_t next; if (!hashtable[i]) continue; @@ -441,10 +433,13 @@ grub_affs_open (struct grub_file *file, const char *name) return grub_errno; } - static grub_err_t grub_affs_close (grub_file_t file) { + struct grub_affs_data *data = + (struct grub_affs_data *) file->data; + + grub_free (data->diropen.block_cache); grub_free (file->data); grub_dl_unref (my_mod); @@ -452,7 +447,6 @@ grub_affs_close (grub_file_t file) return GRUB_ERR_NONE; } - /* Read LEN bytes data from FILE into BUF. */ static grub_ssize_t grub_affs_read (grub_file_t file, char *buf, grub_size_t len) @@ -460,13 +454,12 @@ grub_affs_read (grub_file_t file, char *buf, grub_size_t len) struct grub_affs_data *data = (struct grub_affs_data *) file->data; - int size = grub_affs_read_file (&data->diropen, file->read_hook, - file->offset, len, buf); - - return size; + return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen, + file->read_hook, + file->offset, len, buf, grub_affs_read_block, + grub_be_to_cpu32 (data->diropen.di.size), 0); } - static grub_err_t grub_affs_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, From 19e81ba7a0b67bb1bd3d427c9c7cc1147a78ec8d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 14:44:21 +0100 Subject: [PATCH 1359/1414] * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. --- ChangeLog | 4 ++++ configure.ac | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 035f18194..1b7fd4411 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-09 Vladimir Serbinenko + + * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. + 2011-11-09 Vladimir Serbinenko Several AFFS fixes. diff --git a/configure.ac b/configure.ac index e707081a7..1b3288c8a 100644 --- a/configure.ac +++ b/configure.ac @@ -464,6 +464,7 @@ if test "x$target_m32" = x1; then # Force 32-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m32" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" TARGET_MODULE_FORMAT="elf32" fi @@ -472,6 +473,7 @@ if test "x$target_m64" = x1; then # Force 64-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m64" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" TARGET_MODULE_FORMAT="elf64" fi From 57b01250046a33900d3e4b7434967aacb343bc7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 14:47:45 +0100 Subject: [PATCH 1360/1414] * include/grub/misc.h (grub_strncat): Fix the order of conditionals to avoid accessing beyond the array. --- ChangeLog | 5 +++++ include/grub/misc.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1b7fd4411..352c69c4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-09 Vladimir Serbinenko + + * include/grub/misc.h (grub_strncat): Fix the order of conditionals to + avoid accessing beyond the array. + 2011-11-09 Vladimir Serbinenko * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. diff --git a/include/grub/misc.h b/include/grub/misc.h index 5bc159e7d..4e7d9077c 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -87,7 +87,7 @@ grub_strncat (char *dest, const char *src, int c) while (*p) p++; - while ((*p = *src) != '\0' && c--) + while (c-- && (*p = *src) != '\0') { p++; src++; From 8a5a3a5b5a3f53520f8dd63808e5715558d0d326 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Nov 2011 15:01:58 +0100 Subject: [PATCH 1361/1414] Fix several memory leaks. * grub-core/fs/btrfs.c (grub_btrfs_dir): Fix memory leak. * grub-core/fs/cpio.c (grub_cpio_find_file): Likewise. (grub_cpio_dir): Likewise. * grub-core/fs/fat.c (grub_fat_label): Likewise. * grub-core/fs/jfs.c (grub_jfs_label): Likewise. * grub-core/fs/romfs.c (grub_romfs_close): Likewise. (grub_romfs_label): Likewise. * grub-core/fs/squash4.c (squash_mount): Use zalloc for safety. (squash_unmount): New function. (grub_squash_dir): Fix memory leak. (grub_squash_open): Likewise. (grub_squash_read): Likewise. (grub_squash_mtime): Likewise. * grub-core/fs/xfs.c (grub_xfs_open): Likewise. * grub-core/fs/zfs/zfs.c (check_pool_label): Likewise. * util/grub-fstest.c (fstest): Likewise. --- ChangeLog | 21 +++++++++++++++++++++ grub-core/fs/btrfs.c | 29 +++++++++++++++++++---------- grub-core/fs/cpio.c | 3 +++ grub-core/fs/fat.c | 6 +++++- grub-core/fs/jfs.c | 2 ++ grub-core/fs/romfs.c | 6 +++++- grub-core/fs/squash4.c | 22 +++++++++++++++++----- grub-core/fs/xfs.c | 11 +++++++---- grub-core/fs/zfs/zfs.c | 2 ++ util/grub-fstest.c | 4 +++- 10 files changed, 84 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 352c69c4f..c367bb134 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2011-11-09 Vladimir Serbinenko + + Fix several memory leaks. + + * grub-core/fs/btrfs.c (grub_btrfs_dir): Fix memory leak. + * grub-core/fs/cpio.c (grub_cpio_find_file): Likewise. + (grub_cpio_dir): Likewise. + * grub-core/fs/fat.c (grub_fat_label): Likewise. + * grub-core/fs/jfs.c (grub_jfs_label): Likewise. + * grub-core/fs/romfs.c (grub_romfs_close): Likewise. + (grub_romfs_label): Likewise. + * grub-core/fs/squash4.c (squash_mount): Use zalloc for safety. + (squash_unmount): New function. + (grub_squash_dir): Fix memory leak. + (grub_squash_open): Likewise. + (grub_squash_read): Likewise. + (grub_squash_mtime): Likewise. + * grub-core/fs/xfs.c (grub_xfs_open): Likewise. + * grub-core/fs/zfs/zfs.c (check_pool_label): Likewise. + * util/grub-fstest.c (fstest): Likewise. + 2011-11-09 Vladimir Serbinenko * include/grub/misc.h (grub_strncat): Fix the order of conditionals to diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 3dc680034..e5aa3084c 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1415,22 +1415,28 @@ grub_btrfs_dir (grub_device_t device, const char *path, err = find_path (data, path, &key_in, &tree, &type); if (err) - return err; + { + grub_btrfs_unmount (data); + return err; + } if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + { + grub_btrfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, &desc); if (err) - return err; + { + grub_btrfs_unmount (data); + return err; + } if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM || key_out.object_id != key_in.object_id) { r = next (data, &desc, &elemaddr, &elemsize, &key_out); if (r <= 0) - { - free_iterator (&desc); - return -r; - } + goto out; } do { @@ -1448,14 +1454,17 @@ grub_btrfs_dir (grub_device_t device, const char *path, direl = grub_malloc (allocated + 1); if (!direl) { - free_iterator (&desc); - return grub_errno; + r = -grub_errno; + break; } } err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize); if (err) - return err; + { + r = -err; + break; + } for (cdirel = direl; (grub_uint8_t *) cdirel - (grub_uint8_t *) direl diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c index b43e54ec9..39b35b335 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -147,6 +147,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, && grub_memcmp(*name, "TRAILER!!!", 11) == 0) { *ofs = 0; + grub_free (*name); return GRUB_ERR_NONE; } @@ -481,6 +482,8 @@ grub_cpio_dir (grub_device_t device, const char *path_in, } } } + else + grub_free (name); data->hofs = ofs; } diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index fb1113814..0d32e229d 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -1048,7 +1048,10 @@ grub_fat_label (grub_device_t device, char **label) grub_size_t chc; *label = grub_malloc (11 * 4 + 1); if (!*label) - return grub_errno; + { + grub_free (data); + return grub_errno; + } chc = dir.type_specific.volume_label.character_count; if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str)) chc = ARRAY_SIZE (dir.type_specific.volume_label.str); @@ -1057,6 +1060,7 @@ grub_fat_label (grub_device_t device, char **label) } } + grub_free (data); return grub_errno; } diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index cf7520bb3..91497f143 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -891,6 +891,8 @@ grub_jfs_label (grub_device_t device, char **label) else *label = 0; + grub_free (data); + return grub_errno; } diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index 713e8293f..202ca102e 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -397,7 +397,10 @@ grub_romfs_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_romfs_close (grub_file_t file) { - grub_free (file->data); + struct grub_fshelp_node *data = file->data; + + grub_free (data->data); + grub_free (data); return GRUB_ERR_NONE; } @@ -432,6 +435,7 @@ grub_romfs_label (grub_device_t device, char **label) return err; } (*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0; + grub_free (data); return GRUB_ERR_NONE; } diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index a3832b6be..0728287b7 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -287,7 +287,7 @@ squash_mount (grub_disk_t disk) if (err) return NULL; - data = grub_malloc (sizeof (*data)); + data = grub_zalloc (sizeof (*data)); if (!data) return NULL; data->sb = sb; @@ -418,6 +418,15 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) grub_cpu_to_le16 (data->sb.root_ino_offset)); } +static void +squash_unmount (struct grub_squash_data *data) +{ + grub_free (data->ino.cumulated_block_sizes); + grub_free (data->ino.block_sizes); + grub_free (data); +} + + static grub_err_t grub_squash_dir (grub_device_t device, const char *path, int (*hook) (const char *filename, @@ -436,6 +445,7 @@ grub_squash_dir (grub_device_t device, const char *path, info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); info.mtimeset = 1; info.mtime = grub_le_to_cpu32 (node->ino.mtime); + grub_free (node); return hook (filename, &info); } @@ -457,7 +467,7 @@ grub_squash_dir (grub_device_t device, const char *path, if (!grub_errno) grub_squash_iterate_dir (fdiro, iterate); - grub_free (data); + squash_unmount (data); return grub_errno; } @@ -482,7 +492,7 @@ grub_squash_open (struct grub_file *file, const char *name) grub_squash_read_symlink, GRUB_FSHELP_REG); if (grub_errno) { - grub_free (data); + squash_unmount (data); return grub_errno; } @@ -499,6 +509,8 @@ grub_squash_open (struct grub_file *file, const char *name) else file->size = grub_le_to_cpu32 (fdiro->ino.file.size); + grub_free (fdiro); + return GRUB_ERR_NONE; } @@ -664,7 +676,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) static grub_err_t grub_squash_close (grub_file_t file) { - grub_free (file->data); + squash_unmount (file->data); return GRUB_ERR_NONE; } @@ -677,7 +689,7 @@ grub_squash_mtime (grub_device_t dev, grub_int32_t *tm) if (! data) return grub_errno; *tm = grub_le_to_cpu32 (data->sb.creation_time); - grub_free (data); + squash_unmount (data); return GRUB_ERR_NONE; } diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 3dc5e0af0..c4d47a099 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -771,10 +771,13 @@ grub_xfs_open (struct grub_file *file, const char *name) } if (fdiro != &data->diropen) - grub_memcpy (&data->diropen, fdiro, - sizeof (struct grub_fshelp_node) - - sizeof (struct grub_xfs_inode) - + (1 << data->sblock.log2_inode)); + { + grub_memcpy (&data->diropen, fdiro, + sizeof (struct grub_fshelp_node) + - sizeof (struct grub_xfs_inode) + + (1 << data->sblock.log2_inode)); + grub_free (fdiro); + } file->size = grub_be_to_cpu64 (data->diropen.inode.size); file->data = data; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index f85d56e99..7ceb16db2 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -781,9 +781,11 @@ check_pool_label (struct grub_zfs_data *data, err = fill_vdev_info (data, nv, diskdesc); if (err) { + grub_free (nv); grub_free (nvlist); return err; } + grub_free (nv); } grub_dprintf ("zfs", "check 10 passed\n"); diff --git a/util/grub-fstest.c b/util/grub-fstest.c index f90755e86..47b536771 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -401,7 +401,9 @@ fstest (int n, char **args) if (!uuid) grub_util_error ("couldn't retrieve UUID"); argv[1] = uuid; - execute_command ("xnu_uuid", 2, argv); + execute_command ("xnu_uuid", 2, argv); + grub_free (uuid); + grub_device_close (dev); } } From 28840fdaae146999e51d5741a6434b4f3ffaf54c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:07:51 +0100 Subject: [PATCH 1362/1414] * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): Fix declaration. --- ChangeLog | 5 +++++ include/grub/i386/netbsd_bootinfo.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c367bb134..7cd370c1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-10 Vladimir Serbinenko + + * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): + Fix declaration. + 2011-11-09 Vladimir Serbinenko Fix several memory leaks. diff --git a/include/grub/i386/netbsd_bootinfo.h b/include/grub/i386/netbsd_bootinfo.h index 228f26aaa..24e145b01 100644 --- a/include/grub/i386/netbsd_bootinfo.h +++ b/include/grub/i386/netbsd_bootinfo.h @@ -92,7 +92,7 @@ struct grub_netbsd_btinfo_bootwedge { grub_disk_addr_t matchblk; grub_uint64_t matchnblks; grub_uint8_t matchhash[16]; /* MD5 hash */ -} __packed; +} __attribute__ ((packed)); struct grub_netbsd_btinfo_symtab { From 6b68db81fc42ed6a4b9aa7f15f5578136c383980 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:09:33 +0100 Subject: [PATCH 1363/1414] * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for >= 6 drives. --- ChangeLog | 5 +++++ grub-core/fs/btrfs.c | 9 ++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cd370c1b..506036d5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-10 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for + >= 6 drives. + 2011-11-10 Vladimir Serbinenko * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index e5aa3084c..fae9199a4 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -734,12 +734,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, &low); high = grub_divmod64 (middle, - grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu16 (chunk->nstripes) + / grub_le_to_cpu16 (chunk->nsubstripes), &stripen); - stripen *= grub_le_to_cpu16 (chunk->nstripes) - / grub_le_to_cpu16 (chunk->nsubstripes); - redundancy = grub_le_to_cpu16 (chunk->nstripes) - / grub_le_to_cpu16 (chunk->nsubstripes); + stripen *= grub_le_to_cpu16 (chunk->nsubstripes); + redundancy = grub_le_to_cpu16 (chunk->nsubstripes); stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length) * high; csize = grub_le_to_cpu64 (chunk->stripe_length) - low; From ad9a2f44b4cbf8e22a65f9f019b7914f1a60d169 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:16:27 +0100 Subject: [PATCH 1364/1414] * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat argument (access out of bounds). --- ChangeLog | 5 +++++ grub-core/fs/iso9660.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 506036d5a..ef82df3af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-10 Vladimir Serbinenko + + * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat + argument (access out of bounds). + 2011-11-10 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index d4c52bed4..5e2f7824a 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -559,9 +559,9 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, filename = ".."; else if (entry->len >= 5) { - int size = 1; + grub_size_t size = 1, csize = 1; char *old; - size = entry->len - 5; + csize = size = entry->len - 5; old = filename; if (filename_alloc) { @@ -580,7 +580,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, return grub_errno; } filename_alloc = 1; - grub_strncat (filename, (char *) &entry->data[1], size); + grub_strncat (filename, (char *) &entry->data[1], csize); filename[size] = '\0'; } } From 45bd824d2eed877eef2c55c96063eefbc4a3c5d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:38:06 +0100 Subject: [PATCH 1365/1414] Fix ZFS memory and resource leaks. * grub-core/fs/zfs/zfs.c (fill_vdev_info_real): New paramter inserted. All users updated. Free type on exit. (fill_vdev_info): New parameter inserted. All users updated. (check_pool_label): Likewise. (scan_disk): Likewise. (scan_devices): Close non-inserted disks. (fzap_iterate): Free l. (unmount_device): Free children descripto memory. --- ChangeLog | 14 +++++++ grub-core/fs/zfs/zfs.c | 84 +++++++++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef82df3af..24a2b783b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-10 Vladimir Serbinenko + + Fix ZFS memory and resource leaks. + + * grub-core/fs/zfs/zfs.c (fill_vdev_info_real): New paramter inserted. + All users updated. + Free type on exit. + (fill_vdev_info): New parameter inserted. All users updated. + (check_pool_label): Likewise. + (scan_disk): Likewise. + (scan_devices): Close non-inserted disks. + (fzap_iterate): Free l. + (unmount_device): Free children descripto memory. + 2011-11-10 Vladimir Serbinenko * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 7ceb16db2..760668940 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -535,7 +535,8 @@ static grub_err_t fill_vdev_info_real (struct grub_zfs_data *data, const char *nvlist, struct grub_zfs_device_desc *fill, - struct grub_zfs_device_desc *insert) + struct grub_zfs_device_desc *insert, + int *inserted) { char *type; @@ -545,10 +546,16 @@ fill_vdev_info_real (struct grub_zfs_data *data, return grub_errno; if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &(fill->id))) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + } if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); + } if (grub_strcmp (type, VDEV_TYPE_DISK) == 0 || grub_strcmp (type, VDEV_TYPE_FILE) == 0) @@ -563,8 +570,11 @@ fill_vdev_info_real (struct grub_zfs_data *data, fill->original = insert->original; if (!data->device_original) data->device_original = fill; + *inserted = 1; } + grub_free (type); + return GRUB_ERR_NONE; } @@ -580,17 +590,27 @@ fill_vdev_info_real (struct grub_zfs_data *data, grub_uint64_t par; fill->type = DEVICE_RAIDZ; if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); + } fill->nparity = par; if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "ashift", &par)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz ashift"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz ashift"); + } fill->ashift = par; } - nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, ZPOOL_CONFIG_CHILDREN); + nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, + ZPOOL_CONFIG_CHILDREN); if (nelm <= 0) - return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); + { + grub_free (type); + return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); + } if (!fill->children) { @@ -608,34 +628,43 @@ fill_vdev_info_real (struct grub_zfs_data *data, child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, ZPOOL_CONFIG_CHILDREN, i); - err = fill_vdev_info_real (data, child, &fill->children[i], insert); + err = fill_vdev_info_real (data, child, &fill->children[i], insert, + inserted); grub_free (child); if (err) - return err; + { + grub_free (type); + return err; + } } + grub_free (type); return GRUB_ERR_NONE; } - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", - type); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", type); + grub_free (type); + return grub_errno; } static grub_err_t fill_vdev_info (struct grub_zfs_data *data, - char *nvlist, struct grub_zfs_device_desc *diskdesc) + char *nvlist, struct grub_zfs_device_desc *diskdesc, + int *inserted) { grub_uint64_t id; unsigned i; + *inserted = 0; + if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &id)) return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); for (i = 0; i < data->n_devices_attached; i++) if (data->devices_attached[i].id == id) return fill_vdev_info_real (data, nvlist, &data->devices_attached[i], - diskdesc); + diskdesc, inserted); data->n_devices_attached++; if (data->n_devices_attached > data->n_devices_allocated) @@ -658,7 +687,7 @@ fill_vdev_info (struct grub_zfs_data *data, return fill_vdev_info_real (data, nvlist, &data->devices_attached[data->n_devices_attached - 1], - diskdesc); + diskdesc, inserted); } /* @@ -667,7 +696,8 @@ fill_vdev_info (struct grub_zfs_data *data, */ static grub_err_t check_pool_label (struct grub_zfs_data *data, - struct grub_zfs_device_desc *diskdesc) + struct grub_zfs_device_desc *diskdesc, + int *inserted) { grub_uint64_t pool_state, txg = 0; char *nvlist; @@ -679,6 +709,8 @@ check_pool_label (struct grub_zfs_data *data, int found; grub_err_t err; + *inserted = 0; + err = zfs_fetch_nvlist (diskdesc, &nvlist); if (err) return err; @@ -778,7 +810,7 @@ check_pool_label (struct grub_zfs_data *data, grub_free (nvlist); return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); } - err = fill_vdev_info (data, nv, diskdesc); + err = fill_vdev_info (data, nv, diskdesc, inserted); if (err) { grub_free (nv); @@ -796,7 +828,7 @@ check_pool_label (struct grub_zfs_data *data, static grub_err_t scan_disk (grub_device_t dev, struct grub_zfs_data *data, - int original) + int original, int *inserted) { int label = 0; uberblock_phys_t *ub_array, *ubbest = NULL; @@ -858,7 +890,7 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, grub_memmove (&(data->current_uberblock), &ubbest->ubp_uberblock, sizeof (uberblock_t)); - err = check_pool_label (data, &desc); + err = check_pool_label (data, &desc, inserted); if (err) { grub_errno = GRUB_ERR_NONE; @@ -889,6 +921,7 @@ scan_devices (struct grub_zfs_data *data) { grub_device_t dev; grub_err_t err; + int inserted; dev = grub_device_open (name); if (!dev) return 0; @@ -897,7 +930,7 @@ scan_devices (struct grub_zfs_data *data) grub_device_close (dev); return 0; } - err = scan_disk (dev, data, 0); + err = scan_disk (dev, data, 0, &inserted); if (err == GRUB_ERR_BAD_FS) { grub_device_close (dev); @@ -910,6 +943,9 @@ scan_devices (struct grub_zfs_data *data) grub_print_error (); return 0; } + + if (!inserted) + grub_device_close (dev); return 0; } @@ -2042,10 +2078,14 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, if (hook (buf, le->le_name_length, val, le->le_value_length, le->le_int_size)) - return 1; + { + grub_free (l); + return 1; + } grub_free (buf); grub_free (val); } + grub_free (l); } return 0; } @@ -3156,6 +3196,7 @@ unmount_device (struct grub_zfs_device_desc *desc) case DEVICE_MIRROR: for (i = 0; i < desc->n_children; i++) unmount_device (&desc->children[i]); + grub_free (desc->children); return; } } @@ -3190,6 +3231,7 @@ zfs_mount (grub_device_t dev) grub_size_t ospsize; grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; + int inserted; if (! dev->disk) { @@ -3210,7 +3252,7 @@ zfs_mount (grub_device_t dev) data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) * data->n_devices_allocated); data->n_devices_attached = 0; - err = scan_disk (dev, data, 1); + err = scan_disk (dev, data, 1, &inserted); if (err) { zfs_unmount (data); From cb544caa2ecd10367cd05d5ebbcdc019fdab255a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:43:08 +0100 Subject: [PATCH 1366/1414] * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. --- ChangeLog | 4 ++++ grub-core/fs/zfs/zfs.c | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24a2b783b..2687b65be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-10 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. + 2011-11-10 Vladimir Serbinenko Fix ZFS memory and resource leaks. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 760668940..20cba3509 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -3227,7 +3227,7 @@ zfs_mount (grub_device_t dev) { struct grub_zfs_data *data = 0; grub_err_t err; - objset_phys_t *osp = 0; + void *osp = 0; grub_size_t ospsize; grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; @@ -3265,7 +3265,7 @@ zfs_mount (grub_device_t dev) ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); err = zio_read (&ub->ub_rootbp, ub_endian, - (void **) &osp, &ospsize, data); + &osp, &ospsize, data); if (err) { zfs_unmount (data); @@ -3281,7 +3281,8 @@ zfs_mount (grub_device_t dev) } /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); + grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode, + DNODE_SIZE); data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop, ub_endian) >> 63) & 1; grub_free (osp); From c3591189b82421a8eaeebc97c118d81bba1931cd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 08:46:09 +0100 Subject: [PATCH 1367/1414] Remove local keyword. * util/grub-mkconfig_lib.in (version_test_numeric): Remove local. (version_test_gt): Likewise. (version_find_latest): Likewise. (gettext_printf): Likewise. * util/grub.d/10_windows.in (get_os_name_from_boot_ini): Likewise. --- ChangeLog | 10 ++++++++ util/grub-mkconfig_lib.in | 48 +++++++++++++++++++-------------------- util/grub.d/10_windows.in | 10 ++++---- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2687b65be..e60b4da9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-10 Vladimir Serbinenko + + Remove local keyword. + + * util/grub-mkconfig_lib.in (version_test_numeric): Remove local. + (version_test_gt): Likewise. + (version_find_latest): Likewise. + (gettext_printf): Likewise. + * util/grub.d/10_windows.in (get_os_name_from_boot_ini): Likewise. + 2011-11-10 Vladimir Serbinenko * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index a453a6bb5..5a9bf90c0 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -167,21 +167,21 @@ grub_file_is_not_garbage () version_test_numeric () { - local a="$1" - local cmp="$2" - local b="$3" - if [ "$a" = "$b" ] ; then - case "$cmp" in + version_test_numeric_a="$1" + version_test_numeric_cmp="$2" + version_test_numeric_b="$3" + if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then + case "$version_test_numeric_cmp" in ge|eq|le) return 0 ;; gt|lt) return 1 ;; esac fi - if [ "$cmp" = "lt" ] ; then - c="$a" - a="$b" - b="$c" + if [ "$version_test_numeric_cmp" = "lt" ] ; then + version_test_numeric_c="$version_test_numeric_a" + version_test_numeric_a="$version_test_numeric_b" + version_test_numeric_b="$version_test_numeric_c" fi - if (echo "$a" ; echo "$b") | sort -n | head -n 1 | grep -qx "$b" ; then + if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | sort -n | head -n 1 | grep -qx "$version_test_numeric_b" ; then return 0 else return 1 @@ -190,30 +190,30 @@ version_test_numeric () version_test_gt () { - local a="`echo "$1" | sed -e "s/[^-]*-//"`" - local b="`echo "$2" | sed -e "s/[^-]*-//"`" - local cmp=gt - if [ "x$b" = "x" ] ; then + version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`" + version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`" + version_test_gt_cmp=gt + if [ "x$version_test_gt_b" = "x" ] ; then return 0 fi - case "$a:$b" in + case "$version_test_gt_a:$version_test_gt_b" in *.old:*.old) ;; - *.old:*) a="`echo -n "$a" | sed -e 's/\.old$//'`" ; cmp=gt ;; - *:*.old) b="`echo -n "$b" | sed -e 's/\.old$//'`" ; cmp=ge ;; + *.old:*) version_test_gt_a="`echo -n "$version_test_gt_a" | sed -e 's/\.old$//'`" ; cmp=gt ;; + *:*.old) version_test_gt_b="`echo -n "$version_test_gt_b" | sed -e 's/\.old$//'`" ; cmp=ge ;; esac - version_test_numeric "$a" "$cmp" "$b" + version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" return "$?" } version_find_latest () { - local a="" + version_find_latest_a="" for i in "$@" ; do - if version_test_gt "$i" "$a" ; then - a="$i" + if version_test_gt "$i" "$version_find_latest_a" ; then + version_find_latest_a="$i" fi done - echo "$a" + echo "$version_find_latest_a" } # One layer of quotation is eaten by "", the second by sed, and the third by @@ -227,9 +227,9 @@ gettext_quoted () { # remaining arguments to printf. This is a useful abbreviation and tends to # be easier to type. gettext_printf () { - local format="$1" + gettext_printf_format="$1" shift - printf "$(gettext_quoted "$format")" "$@" + printf "$(gettext_quoted "$gettext_printf_format")" "$@" } uses_abstraction () { diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 0a848880d..20fd4e044 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -42,14 +42,14 @@ get_os_name_from_boot_ini () sort | uniq | wc -l`" = 1 || return 1 # Search 'default=PARTITION' - local part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'` - test -n "$part" || return 1 + get_os_name_from_boot_ini_part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'` + test -n "$get_os_name_from_boot_ini_part" || return 1 # Search 'PARTITION="NAME" ...' - local name=`sed -n 's,\\\\,/,g;s,^'"$part"'="\([^"]*\)".*$,\1,p' "$1" | sed 1q` - test -n "$name" || return 1 + get_os_name_from_boot_ini_name=`sed -n 's,\\\\,/,g;s,^'"$get_os_name_from_boot_ini_part"'="\([^"]*\)".*$,\1,p' "$1" | sed 1q` + test -n "$get_os_name_from_boot_ini_name" || return 1 - echo "$name" + echo "$get_os_name_from_boot_ini_name" } From f627652531ee17d729e024858d529c9b05657593 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Nov 2011 09:31:06 +0100 Subject: [PATCH 1368/1414] Put symlink at the end of the node and fix a potential memory corruption. * grub-core/fs/iso9660.c (grub_fshelp_node): New field have_symlink. Make symlink into an array. (set_rockridge): Set have_symlink and alloc_dirents. (grub_iso9660_read_symlink): Use new layout. (grub_iso9660_iterate_dir): Fix memory corruption. Use new layout. (grub_iso9660_dir): Set have_symlink. (grub_iso9660_open): Likewise. --- ChangeLog | 14 +++++++++++ grub-core/fs/iso9660.c | 55 +++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index e60b4da9c..f293e0773 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-10 Vladimir Serbinenko + + Put symlink at the end of the node and fix a potential + memory corruption. + + * grub-core/fs/iso9660.c (grub_fshelp_node): New field have_symlink. + Make symlink into an array. + (set_rockridge): Set have_symlink and alloc_dirents. + (grub_iso9660_read_symlink): Use new layout. + (grub_iso9660_iterate_dir): Fix memory corruption. + Use new layout. + (grub_iso9660_dir): Set have_symlink. + (grub_iso9660_open): Likewise. + 2011-11-10 Vladimir Serbinenko Remove local keyword. diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 5e2f7824a..7b1e32f7c 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -159,8 +159,9 @@ struct grub_fshelp_node { struct grub_iso9660_data *data; grub_size_t have_dirents, alloc_dirents; - char *symlink; + int have_symlink; struct grub_iso9660_dir dirents[8]; + char symlink[0]; }; enum @@ -408,9 +409,9 @@ set_rockridge (struct grub_iso9660_data *data) struct grub_fshelp_node rootnode; rootnode.data = data; - rootnode.alloc_dirents = 0; + rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents); rootnode.have_dirents = 1; - rootnode.symlink = 0; + rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* The 2nd data byte stored how many bytes are skipped every time @@ -500,7 +501,10 @@ grub_iso9660_mount (grub_disk_t disk) static char * grub_iso9660_read_symlink (grub_fshelp_node_t node) { - return node->symlink ? grub_strdup (node->symlink) : grub_strdup (""); + return node->have_symlink + ? grub_strdup (node->symlink + + (node->have_dirents) * sizeof (node->dirents[0]) + - sizeof (node->dirents)) : grub_strdup (""); } static grub_off_t @@ -703,7 +707,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, /* Setup a new node. */ node->data = dir->data; - node->symlink = symlink; + node->have_symlink = 0; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ @@ -767,10 +771,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, { struct grub_fshelp_node *new_node; node->alloc_dirents *= 2; - new_node = grub_malloc (sizeof (struct grub_fshelp_node) - + ((node->alloc_dirents - - ARRAY_SIZE (node->dirents)) - * sizeof (node->dirents[0]))); + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0]))); if (!new_node) { if (filename_alloc) @@ -778,9 +783,37 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, grub_free (node); return 0; } + node = new_node; } node->dirents[node->have_dirents++] = dirent; } + if (symlink) + { + if ((node->alloc_dirents - node->have_dirents) + * sizeof (node->dirents[0]) < grub_strlen (symlink) + 1) + { + struct grub_fshelp_node *new_node; + new_node = grub_realloc (node, + sizeof (struct grub_fshelp_node) + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0])) + + grub_strlen (symlink) + 1); + if (!new_node) + { + if (filename_alloc) + grub_free (filename); + grub_free (node); + return 0; + } + node = new_node; + } + node->have_symlink = 1; + grub_strcpy (node->symlink + + node->have_dirents * sizeof (node->dirents[0]) + - sizeof (node->dirents), symlink); + grub_free (symlink); + } if (hook (filename, type, node)) { if (filename_alloc) @@ -832,7 +865,7 @@ grub_iso9660_dir (grub_device_t device, const char *path, rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.symlink = 0; + rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ @@ -875,7 +908,7 @@ grub_iso9660_open (struct grub_file *file, const char *name) rootnode.data = data; rootnode.alloc_dirents = 0; rootnode.have_dirents = 1; - rootnode.symlink = 0; + rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; /* Use the fshelp function to traverse the path. */ From 33f784e88175d449eab915d74020cb6cd581b333 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Thu, 10 Nov 2011 09:41:07 +0100 Subject: [PATCH 1369/1414] Allow all modules to perform serial IO * grub-core/term-serial.c (grub_serial_find): Remove static qualifier * include/grub/serial.h (grub_serial_port_configure): New inline function. (grub_serial_port_fetch): Likewise. (grub_serial_port_put): Likewise. (grub_serial_port_fini): Likewise. (grub_serial_find): New proto. --- ChangeLog | 12 ++++++++++++ grub-core/term/serial.c | 2 +- include/grub/serial.h | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f293e0773..6c7304387 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2011-11-10 Shea Levy + + Allow all modules to perform serial IO + + * grub-core/term-serial.c (grub_serial_find): Remove static qualifier + * include/grub/serial.h (grub_serial_port_configure): New inline + function. + (grub_serial_port_fetch): Likewise. + (grub_serial_port_put): Likewise. + (grub_serial_port_fini): Likewise. + (grub_serial_find): New proto. + 2011-11-10 Vladimir Serbinenko Put symlink at the end of the node and fix a potential diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 306694192..86935626c 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -125,7 +125,7 @@ static struct grub_term_output grub_serial_term_output = -static struct grub_serial_port * +struct grub_serial_port * grub_serial_find (char *name) { struct grub_serial_port *port; diff --git a/include/grub/serial.h b/include/grub/serial.h index 41b720891..49ac0623a 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -96,6 +96,32 @@ grub_err_t EXPORT_FUNC(grub_serial_register) (struct grub_serial_port *port); void EXPORT_FUNC(grub_serial_unregister) (struct grub_serial_port *port); + /* Convenience functions to perform primitive operations on a port. */ +static inline grub_err_t +grub_serial_port_configure (struct grub_serial_port *port, + struct grub_serial_config *config) +{ + return port->driver->configure (port, config); +} + +static inline int +grub_serial_port_fetch (struct grub_serial_port *port) +{ + return port->driver->fetch (port); +} + +static inline void +grub_serial_port_put (struct grub_serial_port *port, const int c) +{ + port->driver->put (port, c); +} + +static inline void +grub_serial_port_fini (struct grub_serial_port *port) +{ + port->driver->fini (port); +} + /* Set default settings. */ static inline grub_err_t grub_serial_config_defaults (struct grub_serial_port *port) @@ -117,6 +143,7 @@ grub_serial_config_defaults (struct grub_serial_port *port) void grub_ns8250_init (void); char *grub_serial_ns8250_add_port (grub_port_t port); +struct grub_serial_port *grub_serial_find (char *name); extern struct grub_serial_driver grub_ns8250_driver; void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); From 11a775a3ad55e6de651edcd71d344ea41e64d2eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:08:29 +0100 Subject: [PATCH 1370/1414] * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. --- ChangeLog | 4 ++++ grub-core/commands/probe.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6c7304387..4e2d18c11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. + 2011-11-10 Shea Levy Allow all modules to perform serial IO diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index ce1e9aac0..a1d68cdeb 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -136,7 +136,7 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) return err; if (! label) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "uuid for this FS isn't supported yet"); + "label for this FS isn't supported yet"); if (state[0].set) grub_env_set (state[0].arg, label); From f768836950b038dbc67dabafb2a6086148edab82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:10:50 +0100 Subject: [PATCH 1371/1414] * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): A stylistic fix. --- ChangeLog | 5 +++++ grub-core/efiemu/main.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4e2d18c11..fcbfe0c9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): + A stylistic fix. + 2011-11-11 Vladimir Serbinenko * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index 7ad3abb0d..126ecf9e7 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -149,7 +149,8 @@ grub_efiemu_register_configuration_table (grub_efi_guid_t guid, if (! get_table && ! data) return grub_error (GRUB_ERR_BAD_ARGUMENT, "you must set at least get_table or data"); - if ((err = grub_efiemu_unregister_configuration_table (guid))) + err = grub_efiemu_unregister_configuration_table (guid); + if (err) return err; tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl)); From 6c1892942da03b61e5bfe74f670d3b5c33053152 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:13:23 +0100 Subject: [PATCH 1372/1414] * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. --- ChangeLog | 4 ++++ grub-core/fs/btrfs.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fcbfe0c9d..e37326afa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. + 2011-11-11 Vladimir Serbinenko * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index fae9199a4..db251ffd7 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -1615,7 +1615,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), if (embed_type != GRUB_EMBED_PCBIOS) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "BtrFS curently supports only PC-BIOS embedding"); + "BtrFS currently supports only PC-BIOS embedding"); if (64 * 2 - 1 < *nsectors) return grub_error (GRUB_ERR_OUT_OF_RANGE, From 53dc85906500ef6a23a37562c5619bf25ca6d7a2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:18:34 +0100 Subject: [PATCH 1373/1414] * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove leftover debug printf. --- ChangeLog | 5 +++++ grub-core/fs/ntfs.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index e37326afa..2b2920b79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove + leftover debug printf. + 2011-11-11 Vladimir Serbinenko * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index 13de52cd8..ac695a29f 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -705,17 +705,18 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) switch (grub_cpu_to_le32 (symdesc.type)) { case 0xa000000c: - off = sizeof (struct symlink_descriptor) + 4 + grub_cpu_to_le32 (symdesc.off1); + off = (sizeof (struct symlink_descriptor) + 4 + + grub_cpu_to_le32 (symdesc.off1)); len = grub_cpu_to_le32 (symdesc.len1); break; case 0xa0000003: - off = sizeof (struct symlink_descriptor) + grub_cpu_to_le32 (symdesc.off1); + off = (sizeof (struct symlink_descriptor) + + grub_cpu_to_le32 (symdesc.off1)); len = grub_cpu_to_le32 (symdesc.len1); break; default: grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", grub_cpu_to_le32 (symdesc.type)); - grub_printf ("%d\n", __LINE__); return NULL; } From e2d22baf41ecd6252d9c7ca718d4906f37338cd9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:21:33 +0100 Subject: [PATCH 1374/1414] * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): Fix module name. --- ChangeLog | 5 +++++ grub-core/fs/zfs/zfscrypt.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b2920b79..0864781d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): + Fix module name. + 2011-11-11 Vladimir Serbinenko * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 13f62b25a..619878243 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -455,7 +455,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) static grub_extcmd_t cmd_key; -GRUB_MOD_INIT(zfscrypto) +GRUB_MOD_INIT(zfscrypt) { grub_zfs_decrypt = grub_zfs_decrypt_real; grub_zfs_load_key = grub_zfs_load_key_real; @@ -465,7 +465,7 @@ GRUB_MOD_INIT(zfscrypto) options); } -GRUB_MOD_FINI(zfscrypto) +GRUB_MOD_FINI(zfscrypt) { grub_zfs_decrypt = 0; grub_zfs_load_key = 0; From 4c458569a7f1a7ac71c0d4f91820d45a227b3326 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:34:38 +0100 Subject: [PATCH 1375/1414] * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): Make buf a const. --- ChangeLog | 5 +++++ grub-core/kern/ieee1275/ieee1275.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0864781d7..f011fdef5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): + Make buf a const. + 2011-11-11 Vladimir Serbinenko * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c index 9e2919172..b32fd2d8b 100644 --- a/grub-core/kern/ieee1275/ieee1275.c +++ b/grub-core/kern/ieee1275/ieee1275.c @@ -532,7 +532,7 @@ grub_ieee1275_release (grub_addr_t addr, grub_size_t size) int grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle, - const char *propname, void *buf, + const char *propname, const void *buf, grub_size_t size, grub_ssize_t *actual) { struct set_property_args From 63a9e6f6a07bc07ae1df3c6917428cccfbf1fb71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 17:44:47 +0100 Subject: [PATCH 1376/1414] * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): Issue error rather than printf on unknown arguments. --- ChangeLog | 5 +++++ grub-core/kern/ieee1275/openfw.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f011fdef5..7c2b55e3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): + Issue error rather than printf on unknown arguments. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 57252d96b..3568ffe64 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -403,7 +403,8 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) break; default: unknown: - grub_printf ("Unsupported type %s for device %s\n", type, device); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported type %s for device %s", type, device); } fail: From 9bb182f3716cc9f850f5e64edb61a6da09748d7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 18:05:16 +0100 Subject: [PATCH 1377/1414] * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue an error and not a fatal on unrecognised relocation types. --- ChangeLog | 5 +++++ grub-core/kern/x86_64/dl.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c2b55e3b..b0a790c10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue + an error and not a fatal on unrecognised relocation types. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index 090ad78b8..9b63b30f8 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -109,7 +109,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) break; default: - grub_fatal ("Unrecognized relocation: %d\n", ELF_R_TYPE (rel->r_info)); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "this relocation (%d) is not implemented yet", + ELF_R_TYPE (rel->r_info)); } } } From f7ce5bafb56ebeb2121c2d35eb98293f3e98acd0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 18:30:34 +0100 Subject: [PATCH 1378/1414] Fix mips compilation. * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec): Restrict hash_id to normal decoder. (hashes): Use in embed decoder as well (for sizes). (dec_stream_header): Fix embed decompressor logic. (dec_stream_footer): Likewise. --- ChangeLog | 10 ++++++++++ grub-core/lib/xzembed/xz_dec_stream.c | 19 ++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0a790c10..ca07d5cab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-11-11 Vladimir Serbinenko + + Fix mips compilation. + + * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec): Restrict hash_id to + normal decoder. + (hashes): Use in embed decoder as well (for sizes). + (dec_stream_header): Fix embed decompressor logic. + (dec_stream_footer): Likewise. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index 383c29a2f..09e5e513a 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -78,9 +78,9 @@ struct xz_dec { #ifndef GRUB_EMBED_DECOMPRESSOR const gcry_md_spec_t *hash; const gcry_md_spec_t *crc32; + grub_uint8_t hash_id; #endif grub_size_t hash_size; - grub_uint8_t hash_id; /* True if we are operating in single-call mode. */ bool single_call; @@ -428,8 +428,7 @@ static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, return XZ_STREAM_END; } -#ifndef GRUB_EMBED_DECOMPRESSOR -static struct +static const struct { const char *name; grub_size_t size; @@ -438,7 +437,6 @@ static struct [0x04] = { "CRC64", 8}, [0x0A] = { "SHA256", 32}, }; -#endif /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ static enum xz_ret dec_stream_header(struct xz_dec *s) @@ -470,9 +468,9 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) } #endif +#ifndef GRUB_EMBED_DECOMPRESSOR /* - * Decode the Stream Flags field. Of integrity checks, we support - * only none (Check ID = 0) and CRC32 (Check ID = 1). + * Decode the Stream Flags field. */ if (s->temp.buf[HEADER_MAGIC_SIZE] != 0 || s->temp.buf[HEADER_MAGIC_SIZE + 1] >= ARRAY_SIZE (hashes) @@ -482,7 +480,6 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1]; -#ifndef GRUB_EMBED_DECOMPRESSOR if (s->crc32) { s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL); @@ -530,17 +527,15 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) s->hash->init(s->index.hash.hash_context); s->hash->init(s->block.hash.hash_context); } -#else - s->hash = 0; -#endif -#if 1 if (!s->hash) return XZ_OPTIONS_ERROR; #endif } else { +#ifndef GRUB_EMBED_DECOMPRESSOR s->hash = 0; +#endif s->hash_size = 0; } @@ -589,8 +584,10 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) if ((s->index.size >> 2) != get_le32(s->temp.buf + 4)) return XZ_DATA_ERROR; +#ifndef GRUB_EMBED_DECOMPRESSOR if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id) return XZ_DATA_ERROR; +#endif /* * Use XZ_STREAM_END instead of XZ_OK to be more convenient From a8bd9d39d6fa19ee6672db9732a6f9f1a6d2502e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 18:32:06 +0100 Subject: [PATCH 1379/1414] * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): Fix prototype. --- ChangeLog | 5 +++++ include/grub/ieee1275/ieee1275.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca07d5cab..4838d9566 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): + Fix prototype. + 2011-11-11 Vladimir Serbinenko Fix mips compilation. diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 81590ee4b..be3835a42 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -173,7 +173,8 @@ int EXPORT_FUNC(grub_ieee1275_claim) (grub_addr_t addr, grub_size_t size, unsigned int align, grub_addr_t *result); int EXPORT_FUNC(grub_ieee1275_release) (grub_addr_t addr, grub_size_t size); int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle, - const char *propname, void *buf, + const char *propname, + const void *buf, grub_size_t size, grub_ssize_t *actual); int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle, From 067fdf005573500c6998402affe1723cd51efaf9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:02:51 +0100 Subject: [PATCH 1380/1414] * grub-core/kern/misc.c (grub_strstr): Moved from here ... * include/grub/misc.h (grub_strstr): ... here. Make static and inline. --- ChangeLog | 5 +++++ grub-core/kern/misc.c | 46 ----------------------------------------- include/grub/misc.h | 48 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4838d9566..6d740545a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_strstr): Moved from here ... + * include/grub/misc.h (grub_strstr): ... here. Make static and inline. + 2011-11-11 Vladimir Serbinenko * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index ebf80f100..34c9b3b0c 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -312,52 +312,6 @@ grub_strrchr (const char *s, int c) return p; } -/* Copied from gnulib. - Written by Bruno Haible , 2005. */ -char * -grub_strstr (const char *haystack, const char *needle) -{ - /* Be careful not to look at the entire extent of haystack or needle - until needed. This is useful because of these two cases: - - haystack may be very long, and a match of needle found early, - - needle may be very long, and not even a short initial segment of - needle may be found in haystack. */ - if (*needle != '\0') - { - /* Speed up the following searches of needle by caching its first - character. */ - char b = *needle++; - - for (;; haystack++) - { - if (*haystack == '\0') - /* No match. */ - return NULL; - if (*haystack == b) - /* The first character matches. */ - { - const char *rhaystack = haystack + 1; - const char *rneedle = needle; - - for (;; rhaystack++, rneedle++) - { - if (*rneedle == '\0') - /* Found a match. */ - return (char *) haystack; - if (*rhaystack == '\0') - /* No match. */ - return NULL; - if (*rhaystack != *rneedle) - /* Nothing in this round. */ - break; - } - } - } - } - else - return (char *) haystack; -} - int grub_strword (const char *haystack, const char *needle) { diff --git a/include/grub/misc.h b/include/grub/misc.h index 4e7d9077c..358f73258 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -113,7 +113,53 @@ int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n); char *EXPORT_FUNC(grub_strchr) (const char *s, int c); char *EXPORT_FUNC(grub_strrchr) (const char *s, int c); int EXPORT_FUNC(grub_strword) (const char *s, const char *w); -char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle); + +/* Copied from gnulib. + Written by Bruno Haible , 2005. */ +static inline char * +grub_strstr (const char *haystack, const char *needle) +{ + /* Be careful not to look at the entire extent of haystack or needle + until needed. This is useful because of these two cases: + - haystack may be very long, and a match of needle found early, + - needle may be very long, and not even a short initial segment of + needle may be found in haystack. */ + if (*needle != '\0') + { + /* Speed up the following searches of needle by caching its first + character. */ + char b = *needle++; + + for (;; haystack++) + { + if (*haystack == '\0') + /* No match. */ + return 0; + if (*haystack == b) + /* The first character matches. */ + { + const char *rhaystack = haystack + 1; + const char *rneedle = needle; + + for (;; rhaystack++, rneedle++) + { + if (*rneedle == '\0') + /* Found a match. */ + return (char *) haystack; + if (*rhaystack == '\0') + /* No match. */ + return 0; + if (*rhaystack != *rneedle) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; +} + int EXPORT_FUNC(grub_isspace) (int c); int EXPORT_FUNC(grub_isprint) (int c); From 9aed8a7178adb8c959fde3c3c3318478c8eab9ec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:09:14 +0100 Subject: [PATCH 1381/1414] * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. --- ChangeLog | 4 ++++ grub-core/normal/main.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6d740545a..abf4dce28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/misc.c (grub_strstr): Moved from here ... diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index f372b6798..281b1f4bc 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -274,7 +274,6 @@ grub_normal_execute (const char *config, int nested, int batch) prefix = grub_env_get ("prefix"); read_lists (prefix); grub_register_variable_hook ("prefix", NULL, read_lists_hook); - grub_command_execute ("parser.grub", 0, 0); } if (config) From d35d0d3753cef291ed141d891f6c5e98dee929f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:34:37 +0100 Subject: [PATCH 1382/1414] Add const keyword to grub_env_get and gettextize week days. * grub-core/hook/datehook.c (grub_datetime_names): Make const. (grub_read_hook_datetime): Return const char *. * grub-core/kern/env.c (grub_env_get): Return const char *. All users updated. * grub-core/normal/datetime.c (grub_weekday_names): Make const. Mark for gettext. (grub_get_weekday_name): Return const char *. Call gettext. * grub-core/script/argv.c (grub_script_argv_append): Receive const char * and len as the argument. All users updated. (grub_script_argv_split_append): Receive const char *. * include/grub/datetime.h (grub_get_weekday_name): Update proto. * include/grub/env.h (grub_env_get): Likewise. (grub_env_read_hook_t): Return const char *. * include/grub/script_sh.h (grub_script_argv_append): Update proto. (grub_script_argv_split_append): Likewise. --- ChangeLog | 20 ++++++++++++++ grub-core/commands/i386/pc/drivemap.c | 2 +- grub-core/commands/legacycfg.c | 2 +- grub-core/commands/loadenv.c | 4 +-- grub-core/commands/wildcard.c | 2 +- grub-core/gettext/gettext.c | 2 +- grub-core/hook/datehook.c | 4 +-- grub-core/kern/dl.c | 2 +- grub-core/kern/env.c | 2 +- grub-core/kern/parser.c | 2 +- grub-core/lib/i386/pc/biosnum.c | 2 +- grub-core/loader/i386/linux.c | 7 ++--- grub-core/loader/i386/xnu.c | 2 +- grub-core/normal/datetime.c | 21 ++++++++------- grub-core/normal/menu.c | 4 +-- grub-core/script/argv.c | 25 ++++++++--------- grub-core/script/execute.c | 39 ++++++++++++++++----------- include/grub/datetime.h | 2 +- include/grub/env.h | 6 ++--- include/grub/script_sh.h | 5 ++-- 20 files changed, 91 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index abf4dce28..f98fd8e75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2011-11-11 Vladimir Serbinenko + + Add const keyword to grub_env_get and gettextize week days. + + * grub-core/hook/datehook.c (grub_datetime_names): Make const. + (grub_read_hook_datetime): Return const char *. + * grub-core/kern/env.c (grub_env_get): Return const char *. All users + updated. + * grub-core/normal/datetime.c (grub_weekday_names): Make const. + Mark for gettext. + (grub_get_weekday_name): Return const char *. Call gettext. + * grub-core/script/argv.c (grub_script_argv_append): Receive const + char * and len as the argument. All users updated. + (grub_script_argv_split_append): Receive const char *. + * include/grub/datetime.h (grub_get_weekday_name): Update proto. + * include/grub/env.h (grub_env_get): Likewise. + (grub_env_read_hook_t): Return const char *. + * include/grub/script_sh.h (grub_script_argv_append): Update proto. + (grub_script_argv_split_append): Likewise. + 2011-11-11 Vladimir Serbinenko * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index c9c8881b4..9a89f968c 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -363,7 +363,7 @@ uninstall_int13_handler (void) static int grub_get_root_biosnumber_drivemap (void) { - char *biosnum; + const char *biosnum; int ret = -1; grub_device_t dev; diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index e68b3315a..4e87adafc 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -344,7 +344,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), int bsd_part = -1; { grub_device_t dev; - char *hdbiasstr; + const char *hdbiasstr; int hdbias = 0; hdbiasstr = grub_env_get ("legacy_hdbias"); if (hdbiasstr) diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index 5d53a8e66..1073712d5 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -43,7 +43,7 @@ open_envblk_file (char *filename) if (! filename) { - char *prefix; + const char *prefix; prefix = grub_env_get ("prefix"); if (prefix) @@ -346,7 +346,7 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) while (argc) { - char *value; + const char *value; value = grub_env_get (args[0]); if (value) diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 256c07e51..d991b2010 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -436,7 +436,7 @@ wildcard_expand (const char *s, char ***strs) else if (*start == '/') /* no device part */ { - char *root; + const char *root; char *prefix; root = grub_env_get ("root"); diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 8581b1ff3..682754421 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -294,7 +294,7 @@ grub_mofile_open_lang (const char *locale_dir, const char *locale) static void grub_gettext_init_ext (const char *locale) { - char *locale_dir; + const char *locale_dir; if (!locale) return; diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c index f64fac074..d7ceb85c8 100644 --- a/grub-core/hook/datehook.c +++ b/grub-core/hook/datehook.c @@ -26,7 +26,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static char *grub_datetime_names[] = +static const char *grub_datetime_names[] = { "YEAR", "MONTH", @@ -37,7 +37,7 @@ static char *grub_datetime_names[] = "WEEKDAY", }; -static char * +static const char * grub_read_hook_datetime (struct grub_env_var *var, const char *val __attribute__ ((unused))) { diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index b6fb537e8..26cf0d21d 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -697,7 +697,7 @@ grub_dl_load (const char *name) { char *filename; grub_dl_t mod; - char *grub_dl_dir = grub_env_get ("prefix"); + const char *grub_dl_dir = grub_env_get ("prefix"); mod = grub_dl_get (name); if (mod) diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c index 8f843a872..96b730d35 100644 --- a/grub-core/kern/env.c +++ b/grub-core/kern/env.c @@ -132,7 +132,7 @@ grub_env_set (const char *name, const char *val) return grub_errno; } -char * +const char * grub_env_get (const char *name) { struct grub_env_var *var; diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c index 6370a7b3a..5b449586c 100644 --- a/grub-core/kern/parser.c +++ b/grub-core/kern/parser.c @@ -123,7 +123,7 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, void add_var (grub_parser_state_t newstate) { - char *val; + const char *val; /* Check if a variable was being read in and the end of the name was reached. */ diff --git a/grub-core/lib/i386/pc/biosnum.c b/grub-core/lib/i386/pc/biosnum.c index 12771085a..0f0e743c4 100644 --- a/grub-core/lib/i386/pc/biosnum.c +++ b/grub-core/lib/i386/pc/biosnum.c @@ -24,7 +24,7 @@ static int grub_get_root_biosnumber_default (void) { - char *biosnum; + const char *biosnum; int ret = -1; grub_device_t dev; diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index fded7bb0a..a6eb95028 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -320,7 +320,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) void *framebuffer; grub_err_t err; grub_video_driver_id_t driver_id; - char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); + const char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); driver_id = grub_video_get_driver_id (); @@ -418,14 +418,15 @@ grub_linux_boot (void) struct linux_kernel_params *params; int e820_num; grub_err_t err = 0; - char *modevar, *tmp; + const char *modevar; + char *tmp; struct grub_relocator32_state state; params = real_mode_mem; #ifdef GRUB_MACHINE_IEEE1275 { - char *bootpath; + const char *bootpath; grub_ssize_t len; bootpath = grub_env_get ("root"); diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 6128ec384..fa7af514b 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -700,7 +700,7 @@ grub_cpu_xnu_fill_devicetree (void) return grub_errno; /* First see if user supplies the value. */ - char *fsbvar = grub_env_get ("fsb"); + const char *fsbvar = grub_env_get ("fsb"); if (! fsbvar) *((grub_uint64_t *) curval->data) = 0; else diff --git a/grub-core/normal/datetime.c b/grub-core/normal/datetime.c index 44791e18c..8183601ba 100644 --- a/grub-core/normal/datetime.c +++ b/grub-core/normal/datetime.c @@ -18,16 +18,17 @@ */ #include +#include -static char *grub_weekday_names[] = +static const char *grub_weekday_names[] = { - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", + N_("Sunday"), + N_("Monday"), + N_("Tuesday"), + N_("Wednesday"), + N_("Thursday"), + N_("Friday"), + N_("Saturday"), }; int @@ -42,10 +43,10 @@ grub_get_weekday (struct grub_datetime *datetime) return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7; } -char * +const char * grub_get_weekday_name (struct grub_datetime *datetime) { - return grub_weekday_names[grub_get_weekday (datetime)]; + return _ (grub_weekday_names[grub_get_weekday (datetime)]); } #define SECPERMIN 60 diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index 2c127794b..b75e9f523 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -79,7 +79,7 @@ grub_menu_get_entry (grub_menu_t menu, int no) int grub_menu_get_timeout (void) { - char *val; + const char *val; int timeout; val = grub_env_get ("timeout"); @@ -124,7 +124,7 @@ grub_menu_set_timeout (int timeout) static int get_and_remove_first_entry_number (const char *name) { - char *val; + const char *val; char *tail; int entry; diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c index 856828d7b..b58d3e658 100644 --- a/grub-core/script/argv.c +++ b/grub-core/script/argv.c @@ -66,7 +66,8 @@ grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args) struct grub_script_argv r = { 0, 0, 0 }; for (i = 0; i < argc; i++) - if (grub_script_argv_next (&r) || grub_script_argv_append (&r, args[i])) + if (grub_script_argv_next (&r) + || grub_script_argv_append (&r, args[i], grub_strlen (args[i]))) { grub_script_argv_free (&r); return 1; @@ -99,23 +100,23 @@ grub_script_argv_next (struct grub_script_argv *argv) /* Append `s' to the last argument. */ int -grub_script_argv_append (struct grub_script_argv *argv, const char *s) +grub_script_argv_append (struct grub_script_argv *argv, const char *s, + grub_size_t slen) { - int a; - int b; + grub_size_t a; char *p = argv->args[argv->argc - 1]; if (! s) return 0; a = p ? grub_strlen (p) : 0; - b = grub_strlen (s); - p = grub_realloc (p, round_up_exp ((a + b + 1) * sizeof (char))); + p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char))); if (! p) return 1; - grub_strcpy (p + a, s); + grub_memcpy (p + a, s, slen); + p[a+slen] = 0; argv->args[argv->argc - 1] = p; return 0; @@ -123,10 +124,9 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s) /* Split `s' and append words as multiple arguments. */ int -grub_script_argv_split_append (struct grub_script_argv *argv, char *s) +grub_script_argv_split_append (struct grub_script_argv *argv, const char *s) { - char ch; - char *p; + const char *p; int errors = 0; if (! s) @@ -138,10 +138,7 @@ grub_script_argv_split_append (struct grub_script_argv *argv, char *s) while (*s && ! grub_isspace (*s)) s++; - ch = *s; - *s = '\0'; - errors += grub_script_argv_append (argv, p); - *s = ch; + errors += grub_script_argv_append (argv, p, s - p); while (*s && grub_isspace (*s)) s++; diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 72d199760..1fb5de6a3 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -193,7 +193,7 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) if (! grub_env_special (name)) { - char *v = grub_env_get (name); + const char *v = grub_env_get (name); if (v && v[0]) { if (type == GRUB_SCRIPT_ARG_TYPE_VAR) @@ -202,20 +202,20 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) goto fail; } else - if (grub_script_argv_append (&result, v)) + if (grub_script_argv_append (&result, v, grub_strlen (v))) goto fail; } } else if (! scope) { - if (grub_script_argv_append (&result, 0)) + if (grub_script_argv_append (&result, 0, 0)) goto fail; } else if (grub_strcmp (name, "#") == 0) { char buffer[ERRNO_DIGITS_MAX + 1]; grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc); - if (grub_script_argv_append (&result, buffer)) + if (grub_script_argv_append (&result, buffer, grub_strlen (buffer))) goto fail; } else if (grub_strcmp (name, "*") == 0) @@ -231,10 +231,11 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) } else { - if (i != 0 && grub_script_argv_append (&result, " ")) + if (i != 0 && grub_script_argv_append (&result, " ", 1)) goto fail; - if (grub_script_argv_append (&result, scope->argv.args[i])) + if (grub_script_argv_append (&result, scope->argv.args[i], + grub_strlen (scope->argv.args[i]))) goto fail; } } @@ -251,7 +252,8 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) goto fail; } else - if (grub_script_argv_append (&result, scope->argv.args[i])) + if (grub_script_argv_append (&result, scope->argv.args[i], + grub_strlen (scope->argv.args[i]))) goto fail; } } @@ -270,7 +272,9 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) goto fail; } else - if (grub_script_argv_append (&result, scope->argv.args[num - 1])) + if (grub_script_argv_append (&result, scope->argv.args[num - 1], + grub_strlen (scope->argv.args[num - 1]) + )) goto fail; } } @@ -309,7 +313,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, char *p = 0; if (! grub_wildcard_translator || escape_type == 0) - return grub_script_argv_append (&result, s); + return grub_script_argv_append (&result, s, grub_strlen (s)); if (escape_type > 0) p = grub_wildcard_translator->escape (s); @@ -319,7 +323,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, if (! p) return 1; - r = grub_script_argv_append (&result, p); + r = grub_script_argv_append (&result, p, grub_strlen (p)); grub_free (p); return r; } @@ -344,7 +348,8 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR) { - if (grub_script_argv_append (&result, values[i])) + if (grub_script_argv_append (&result, values[i], + grub_strlen (values[i]))) goto fail; } else @@ -359,16 +364,18 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, break; case GRUB_SCRIPT_ARG_TYPE_BLOCK: - if (grub_script_argv_append (&result, "{") || - grub_script_argv_append (&result, arg->str) || - grub_script_argv_append (&result, "}")) + if (grub_script_argv_append (&result, "{", 1) + || grub_script_argv_append (&result, arg->str, + grub_strlen (arg->str)) + || grub_script_argv_append (&result, "}", 1)) goto fail; result.script = arg->script; break; case GRUB_SCRIPT_ARG_TYPE_TEXT: if (grub_strlen (arg->str) && - grub_script_argv_append (&result, arg->str)) + grub_script_argv_append (&result, arg->str, + grub_strlen (arg->str))) goto fail; break; @@ -680,7 +687,7 @@ grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd) { int ret; - char *result; + const char *result; struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd; /* Check if the commands results in a true or a false. The value is diff --git a/include/grub/datetime.h b/include/grub/datetime.h index 049dbc227..a7154fa1a 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -46,7 +46,7 @@ grub_err_t grub_set_datetime (struct grub_datetime *datetime); #endif int grub_get_weekday (struct grub_datetime *datetime); -char *grub_get_weekday_name (struct grub_datetime *datetime); +const char *grub_get_weekday_name (struct grub_datetime *datetime); void grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime); diff --git a/include/grub/env.h b/include/grub/env.h index c0107f16a..1ef11ecad 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -26,8 +26,8 @@ struct grub_env_var; -typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var, - const char *val); +typedef const char *(*grub_env_read_hook_t) (struct grub_env_var *var, + const char *val); typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, const char *val); @@ -43,7 +43,7 @@ struct grub_env_var }; grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); -char *EXPORT_FUNC(grub_env_get) (const char *name); +const char *EXPORT_FUNC(grub_env_get) (const char *name); void EXPORT_FUNC(grub_env_unset) (const char *name); void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var)); struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name); diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 6d31fca5a..fdccaca8d 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -245,8 +245,9 @@ void grub_script_mem_free (struct grub_script_mem *mem); void grub_script_argv_free (struct grub_script_argv *argv); int grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args); int grub_script_argv_next (struct grub_script_argv *argv); -int grub_script_argv_append (struct grub_script_argv *argv, const char *s); -int grub_script_argv_split_append (struct grub_script_argv *argv, char *s); +int grub_script_argv_append (struct grub_script_argv *argv, const char *s, + grub_size_t slen); +int grub_script_argv_split_append (struct grub_script_argv *argv, const char *s); struct grub_script_arglist * grub_script_create_arglist (struct grub_parser_param *state); From c1860f878be376b2778dc0590a94f8f8494a7c87 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:45:31 +0100 Subject: [PATCH 1383/1414] * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. (grub_xvasprintf): Likewise. --- ChangeLog | 5 +++++ grub-core/kern/misc.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index f98fd8e75..bdab31591 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. + (grub_xvasprintf): Likewise. + 2011-11-11 Vladimir Serbinenko Add const keyword to grub_env_get and gettextize week days. diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 34c9b3b0c..8dd7f453f 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -216,6 +216,8 @@ grub_vprintf (const char *fmt, va_list args) s = grub_vsnprintf_real (curbuf, s, fmt, ap2); } + va_end (ap2); + grub_xputs (curbuf); if (curbuf != buf) @@ -911,6 +913,9 @@ grub_xvasprintf (const char *fmt, va_list ap) return NULL; s = grub_vsnprintf_real (ret, as, fmt, ap2); + + va_end (ap2); + if (s <= as) return ret; From 5b289bc5f6b48bdfb12a9a78779b4fef66d91d6e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:52:41 +0100 Subject: [PATCH 1384/1414] * util/grub-macho2img.c: Add comment concerning gettext. * grub-core/lib/legacy_parse.c: Likewise. --- ChangeLog | 5 +++++ grub-core/lib/legacy_parse.c | 3 +++ util/grub-macho2img.c | 2 ++ 3 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index bdab31591..aaec2066b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * util/grub-macho2img.c: Add comment concerning gettext. + * grub-core/lib/legacy_parse.c: Likewise. + 2011-11-11 Vladimir Serbinenko * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 659fa7061..43fca51dc 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -58,6 +58,9 @@ struct legacy_command const char *longdesc; }; +/* Help texts are kept here mostly for reference. They are never shown. So + no need to gettextize. + */ static struct legacy_command legacy_commands[] = { {"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", diff --git a/util/grub-macho2img.c b/util/grub-macho2img.c index bce0a06d1..6dfb5fcbe 100644 --- a/util/grub-macho2img.c +++ b/util/grub-macho2img.c @@ -25,6 +25,8 @@ #include #include +/* Please don't internationalise this file. It's pointless. */ + /* XXX: this file assumes particular Mach-O layout and does no checks. */ /* However as build system ensures correct usage of this tool this shouldn't be a problem. */ From df067ad13af3c5722a0d7370d429415342d446a0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 20:59:25 +0100 Subject: [PATCH 1385/1414] * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into dprintf. * grub-core/font/font.c (grub_font_load): Likewise. --- ChangeLog | 6 ++++++ grub-core/efiemu/mm.c | 3 ++- grub-core/font/font.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index aaec2066b..e645709ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into + dprintf. + * grub-core/font/font.c (grub_font_load): Likewise. + 2011-11-11 Vladimir Serbinenko * util/grub-macho2img.c: Add comment concerning gettext. diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c index 3c1dc2946..7bb7cc080 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -404,7 +404,8 @@ grub_efiemu_mmap_fill (void) GRUB_EFI_ACPI_MEMORY_NVS); default: - grub_printf ("Unknown memory type %d. Assuming unusable\n", type); + grub_dprintf ("efiemu", + "Unknown memory type %d. Assuming unusable\n", type); case GRUB_MEMORY_RESERVED: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_UNUSABLE_MEMORY); diff --git a/grub-core/font/font.c b/grub-core/font/font.c index 26eac4c05..3737480cf 100644 --- a/grub-core/font/font.c +++ b/grub-core/font/font.c @@ -608,7 +608,7 @@ grub_font_load (const char *filename) if (!font->name) { - grub_printf ("Note: Font has no name.\n"); + grub_dprintf ("font", "Font has no name.\n"); font->name = grub_strdup ("Unknown"); } From c76b54176213bb705badc31a434ec0229a45751e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:03:49 +0100 Subject: [PATCH 1386/1414] * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic fix. --- ChangeLog | 5 +++++ grub-core/hook/datehook.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e645709ef..be33b7660 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic + fix. + 2011-11-11 Vladimir Serbinenko * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c index d7ceb85c8..ac75908ef 100644 --- a/grub-core/hook/datehook.c +++ b/grub-core/hook/datehook.c @@ -50,7 +50,7 @@ grub_read_hook_datetime (struct grub_env_var *var, int i; for (i = 0; i < 7; i++) - if (! grub_strcmp (var->name, grub_datetime_names[i])) + if (grub_strcmp (var->name, grub_datetime_names[i]) == 0) { int n; From 12d4f965cddb0625d2c6ada654463adefdef8bce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:14:41 +0100 Subject: [PATCH 1387/1414] Support %1$d syntax. * tests/printf_unit_test.c: New file. * Makefile.util.def (printf_test): New test. * grub-core/kern/misc.c (grub_vsnprintf_real): Support %1$d syntax. --- Makefile.util.def | 15 ++ grub-core/kern/misc.c | 484 ++++++++++++++++++++++++++------------- tests/printf_unit_test.c | 43 ++++ 3 files changed, 378 insertions(+), 164 deletions(-) create mode 100644 tests/printf_unit_test.c diff --git a/Makefile.util.def b/Makefile.util.def index 8742d1583..89e614468 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -660,6 +660,21 @@ program = { ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; +program = { + testcase; + name = printf_test; + common = tests/printf_unit_test.c; + common = tests/lib/unit_test.c; + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/tests/lib/test.c; + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +}; + program = { name = grub-menulst2cfg; mansection = 1; diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 8dd7f453f..128139dc8 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -637,10 +637,13 @@ grub_lltoa (char *str, int c, unsigned long long n) } static int -grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args) +grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list args_in) { char c; + grub_size_t n = 0; grub_size_t count = 0; + grub_size_t count_args = 0; + const char *fmt; auto void write_char (unsigned char ch); auto void write_str (const char *s); auto void write_fill (const char ch, int n); @@ -659,209 +662,362 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list ar write_char (*s++); } - void write_fill (const char ch, int n) + void write_fill (const char ch, int count_fill) { int i; - for (i = 0; i < n; i++) + for (i = 0; i < count_fill; i++) write_char (ch); } + fmt = fmt0; while ((c = *fmt++) != 0) { if (c != '%') - write_char (c); - else + continue; + + if (*fmt && *fmt =='-') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + if (*fmt && *fmt == '$') + fmt++; + + if (*fmt && *fmt =='-') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + if (*fmt && *fmt =='.') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + c = *fmt++; + if (c == 'l') { - char tmp[32]; - char *p; - unsigned int format1 = 0; - unsigned int format2 = ~ 0U; - char zerofill = ' '; - int rightfill = 0; - int n; - int longfmt = 0; - int longlongfmt = 0; - int unsig = 0; + c = *fmt++; + if (c == 'l') + c = *fmt++; + } + switch (c) + { + case 'p': + case 'x': + case 'u': + case 'd': + case 'c': + case 'C': + case 's': + count_args++; + break; + } + } - if (*fmt && *fmt =='-') + enum { INT, WCHAR, LONG, LONGLONG, POINTER } types[count_args]; + union + { + int i; + grub_uint32_t w; + long l; + long long ll; + void *p; + } args[count_args]; + + grub_memset (types, 0, sizeof (types)); + + fmt = fmt0; + n = 0; + while ((c = *fmt++) != 0) + { + int longfmt = 0; + int longlongfmt = 0; + grub_size_t curn; + const char *p; + + if (c != '%') + continue; + + curn = n++; + + if (*fmt && *fmt =='-') + fmt++; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + p = fmt; + + if (*fmt && *fmt == '$') + { + curn = grub_strtoull (p, 0, 10) - 1; + fmt++; + } + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + + c = *fmt++; + if (c == 'l') + { + c = *fmt++; + longfmt = 1; + if (c == 'l') { - rightfill = 1; - fmt++; + c = *fmt++; + longlongfmt = 1; } + } + if (curn >= count_args) + continue; + switch (c) + { + case 'x': + case 'u': + case 'd': + if (longlongfmt) + types[curn] = LONGLONG; + else if (longfmt) + types[curn] = LONG; + else + types[curn] = INT; + break; + case 'p': + case 's': + types[curn] = POINTER; + break; + case 'c': + types[curn] = INT; + break; + case 'C': + types[curn] = WCHAR; + break; + } + } - p = (char *) fmt; - /* Read formatting parameters. */ + for (n = 0; n < count_args; n++) + switch (types[n]) + { + case WCHAR: + args[n].w = va_arg (args_in, grub_uint32_t); + break; + case POINTER: + args[n].p = va_arg (args_in, void *); + break; + case INT: + args[n].i = va_arg (args_in, int); + break; + case LONG: + args[n].l = va_arg (args_in, long); + break; + case LONGLONG: + args[n].ll = va_arg (args_in, long long); + break; + } + + fmt = fmt0; + + n = 0; + while ((c = *fmt++) != 0) + { + char tmp[32]; + char *p; + unsigned int format1 = 0; + unsigned int format2 = ~ 0U; + char zerofill = ' '; + int rightfill = 0; + int longfmt = 0; + int longlongfmt = 0; + int unsig = 0; + grub_size_t curn; + + if (c != '%') + { + write_char (c); + continue; + } + + curn = n++; + + rescan:; + + if (*fmt && *fmt =='-') + { + rightfill = 1; + fmt++; + } + + p = (char *) fmt; + /* Read formatting parameters. */ + while (*p && grub_isdigit (*p)) + p++; + + if (p > fmt) + { + char s[p - fmt + 1]; + grub_strncpy (s, fmt, p - fmt); + s[p - fmt] = 0; + if (s[0] == '0') + zerofill = '0'; + format1 = grub_strtoul (s, 0, 10); + fmt = p; + } + + if (*p && *p == '.') + { + p++; + fmt++; while (*p && grub_isdigit (*p)) p++; if (p > fmt) { - char s[p - fmt + 1]; - grub_strncpy (s, fmt, p - fmt); - s[p - fmt] = 0; - if (s[0] == '0') - zerofill = '0'; - format1 = grub_strtoul (s, 0, 10); + char fstr[p - fmt + 1]; + grub_strncpy (fstr, fmt, p - fmt); + fstr[p - fmt] = 0; + format2 = grub_strtoul (fstr, 0, 10); fmt = p; } + } + if (*fmt == '$') + { + curn = format1 - 1; + fmt++; + format1 = 0; + format2 = ~ 0U; + zerofill = ' '; + rightfill = 0; - if (*p && *p == '.') - { - p++; - fmt++; - while (*p && grub_isdigit (*p)) - p++; - - if (p > fmt) - { - char fstr[p - fmt + 1]; - grub_strncpy (fstr, fmt, p - fmt); - fstr[p - fmt] = 0; - format2 = grub_strtoul (fstr, 0, 10); - fmt = p; - } - } + goto rescan; + } + c = *fmt++; + if (c == 'l') + { + longfmt = 1; c = *fmt++; if (c == 'l') { - longfmt = 1; + longlongfmt = 1; c = *fmt++; - if (c == 'l') - { - longlongfmt = 1; - c = *fmt++; - } } + } - switch (c) - { - case 'p': - write_str ("0x"); - c = 'x'; - longlongfmt |= (sizeof (void *) == sizeof (long long)); - /* Fall through. */ - case 'x': - case 'u': - unsig = 1; - /* Fall through. */ - case 'd': - if (longlongfmt) - { - long long ll; + if (curn >= count_args) + continue; - ll = va_arg (args, long long); - grub_lltoa (tmp, c, ll); - } - else if (longfmt && unsig) - { - unsigned long l = va_arg (args, unsigned long); - grub_lltoa (tmp, c, l); - } - else if (longfmt) - { - long l = va_arg (args, long); - grub_lltoa (tmp, c, l); - } - else if (unsig) - { - unsigned u = va_arg (args, unsigned); - grub_lltoa (tmp, c, u); - } - else - { - n = va_arg (args, int); - grub_lltoa (tmp, c, n); - } - if (! rightfill && grub_strlen (tmp) < format1) - write_fill (zerofill, format1 - grub_strlen (tmp)); - write_str (tmp); - if (rightfill && grub_strlen (tmp) < format1) - write_fill (zerofill, format1 - grub_strlen (tmp)); - break; + switch (c) + { + case 'p': + write_str ("0x"); + c = 'x'; + longlongfmt |= (sizeof (void *) == sizeof (long long)); + /* Fall through. */ + case 'x': + case 'u': + unsig = 1; + /* Fall through. */ + case 'd': + if (longlongfmt) + grub_lltoa (tmp, c, args[curn].ll); + else if (longfmt && unsig) + grub_lltoa (tmp, c, (unsigned long) args[curn].l); + else if (longfmt) + grub_lltoa (tmp, c, args[curn].l); + else if (unsig) + grub_lltoa (tmp, c, (unsigned) args[curn].i); + else + grub_lltoa (tmp, c, args[curn].i); + if (! rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + write_str (tmp); + if (rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + break; - case 'c': - n = va_arg (args, int); - write_char (n & 0xff); - break; + case 'c': + write_char (args[curn].i & 0xff); + break; - case 'C': + case 'C': + { + grub_uint32_t code = args[curn].w; + int shift; + unsigned mask; + + if (code <= 0x7f) { - grub_uint32_t code = va_arg (args, grub_uint32_t); - int shift; - unsigned mask; - - if (code <= 0x7f) - { - shift = 0; - mask = 0; - } - else if (code <= 0x7ff) - { - shift = 6; - mask = 0xc0; - } - else if (code <= 0xffff) - { - shift = 12; - mask = 0xe0; - } - else if (code <= 0x1fffff) - { - shift = 18; - mask = 0xf0; - } - else if (code <= 0x3ffffff) - { - shift = 24; - mask = 0xf8; - } - else if (code <= 0x7fffffff) - { - shift = 30; - mask = 0xfc; - } - else - { - code = '?'; - shift = 0; - mask = 0; - } - - write_char (mask | (code >> shift)); - - for (shift -= 6; shift >= 0; shift -= 6) - write_char (0x80 | (0x3f & (code >> shift))); + shift = 0; + mask = 0; + } + else if (code <= 0x7ff) + { + shift = 6; + mask = 0xc0; + } + else if (code <= 0xffff) + { + shift = 12; + mask = 0xe0; + } + else if (code <= 0x1fffff) + { + shift = 18; + mask = 0xf0; + } + else if (code <= 0x3ffffff) + { + shift = 24; + mask = 0xf8; + } + else if (code <= 0x7fffffff) + { + shift = 30; + mask = 0xfc; + } + else + { + code = '?'; + shift = 0; + mask = 0; } - break; - case 's': - p = va_arg (args, char *); - if (p) - { - grub_size_t len = 0; - while (len < format2 && p[len]) - len++; + write_char (mask | (code >> shift)); - if (!rightfill && len < format1) - write_fill (zerofill, format1 - len); + for (shift -= 6; shift >= 0; shift -= 6) + write_char (0x80 | (0x3f & (code >> shift))); + } + break; - grub_size_t i; - for (i = 0; i < len; i++) - write_char (*p++); + case 's': + p = args[curn].p; + if (p) + { + grub_size_t len = 0; + while (len < format2 && p[len]) + len++; - if (rightfill && len < format1) - write_fill (zerofill, format1 - len); - } - else - write_str ("(null)"); + if (!rightfill && len < format1) + write_fill (zerofill, format1 - len); - break; + grub_size_t i; + for (i = 0; i < len; i++) + write_char (*p++); - default: - write_char (c); - break; + if (rightfill && len < format1) + write_fill (zerofill, format1 - len); } + else + write_str ("(null)"); + + break; + + default: + write_char (c); + break; } } diff --git a/tests/printf_unit_test.c b/tests/printf_unit_test.c new file mode 100644 index 000000000..6e601b401 --- /dev/null +++ b/tests/printf_unit_test.c @@ -0,0 +1,43 @@ +/* + * 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 + +static void +printf_test (void) +{ + char real[512]; + char expected[512]; + grub_snprintf (real, sizeof (real), "%d %d %d", 1, 2, 3); + snprintf (expected, sizeof (expected), "%d %d %d", 1, 2, 3); + grub_test_assert (strcmp (real, expected) == 0); + grub_snprintf (real, sizeof (real), "%3$d %2$d %1$d", 1, 2, 3); + snprintf (expected, sizeof (expected), "%3$d %2$d %1$d", 1, 2, 3); + grub_test_assert (strcmp (real, expected) == 0); + grub_snprintf (real, sizeof (real), "%d %lld %d", 1, 2LL, 3); + snprintf (expected, sizeof (expected), "%d %lld %d", 1, 2LL, 3); + grub_test_assert (strcmp (real, expected) == 0); + grub_snprintf (real, sizeof (real), "%3$d %2$lld %1$d", 1, 2LL, 3); + snprintf (expected, sizeof (expected), "%3$d %2$lld %1$d", 1, 2LL, 3); + grub_test_assert (strcmp (real, expected) == 0); +} + +GRUB_UNIT_TEST ("printf_unit_test", printf_test); From 073aa7a9bf07d988b6337850f48599901089b9d7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:22:02 +0100 Subject: [PATCH 1388/1414] Forgotten ChangeLog entry --- ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index be33b7660..725415cd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-11-11 Vladimir Serbinenko + + Support %1$d syntax. + + * tests/printf_unit_test.c: New file. + * Makefile.util.def (printf_test): New test. + * grub-core/kern/misc.c (grub_vsnprintf_real): Support %1$d syntax. + 2011-11-11 Vladimir Serbinenko * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic From 6e0632e28cd692faae2b026bb987e69906d6326a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 21:44:56 +0100 Subject: [PATCH 1389/1414] * grub-core/commands/acpihalt.c: Gettextized. * grub-core/commands/cacheinfo.c: Likewise. * grub-core/commands/cmp.c: Likewise. * grub-core/commands/efi/loadbios.c: Likewise. * grub-core/commands/gptsync.c: Likewise. * grub-core/commands/ieee1275/suspend.c: Likewise. * grub-core/commands/legacycfg.c: Likewise. * grub-core/commands/memrw.c: Likewise. * grub-core/commands/minicmd.c: Likewise. * grub-core/commands/parttool.c: Likewise. * grub-core/commands/time.c: Likewise. * grub-core/commands/videoinfo.c: Likewise. * grub-core/disk/geli.c: Likewise. * grub-core/disk/i386/pc/biosdisk.c: Likewise. * grub-core/disk/luks.c: Likewise. * grub-core/disk/lvm.c: Likewise. * grub-core/font/font_cmd.c: Likewise. * grub-core/fs/zfs/zfscrypt.c: Likewise. * grub-core/fs/zfs/zfsinfo.c: Likewise. * grub-core/gfxmenu/view.c: Likewise. * grub-core/kern/emu/hostdisk.c: Likewise. * grub-core/kern/emu/main.c: Likewise. * grub-core/kern/emu/misc.c: Likewise. * grub-core/kern/emu/mm.c: Likewise. * grub-core/kern/mips/arc/init.c: Likewise. * grub-core/kern/mips/loongson/init.c: Likewise. * grub-core/kern/partition.c: Likewise. * grub-core/lib/i386/halt.c: Likewise. * grub-core/lib/mips/arc/reboot.c: Likewise. * grub-core/lib/mips/loongson/reboot.c: Likewise. * grub-core/loader/i386/pc/chainloader.c: Likewise. * grub-core/loader/i386/xnu.c: Likewise. * grub-core/loader/multiboot.c: Likewise. * grub-core/net/bootp.c: Likewise. * grub-core/net/net.c: Likewise. * grub-core/normal/term.c: Likewise. * grub-core/partmap/bsdlabel.c: Likewise. * grub-core/parttool/msdospart.c: Likewise. * grub-core/term/gfxterm.c: Likewise. * grub-core/term/terminfo.c: Likewise. * grub-core/video/i386/pc/vbe.c: Likewise. * util/grub-menulst2cfg.c: Likewise. * util/grub-mkdevicemap.c: Likewise. * util/grub-mklayout.c: Likewise. * util/grub-mkrelpath.c: Likewise. * util/grub-script-check.c: Likewise. * util/ieee1275/grub-ofpathname.c: Likewise. * util/resolve.c: Likewise. --- ChangeLog | 51 ++++++++++++++++ grub-core/commands/acpihalt.c | 3 +- grub-core/commands/cacheinfo.c | 4 +- grub-core/commands/cmp.c | 19 +++--- grub-core/commands/efi/loadbios.c | 6 +- grub-core/commands/gptsync.c | 2 +- grub-core/commands/ieee1275/suspend.c | 2 +- grub-core/commands/legacycfg.c | 2 +- grub-core/commands/memrw.c | 2 +- grub-core/commands/minicmd.c | 2 +- grub-core/commands/parttool.c | 14 ++--- grub-core/commands/time.c | 4 +- grub-core/commands/videoinfo.c | 65 ++++++++++---------- grub-core/disk/geli.c | 14 ++--- grub-core/disk/i386/pc/biosdisk.c | 3 +- grub-core/disk/luks.c | 6 +- grub-core/disk/lvm.c | 3 +- grub-core/font/font_cmd.c | 2 +- grub-core/fs/zfs/zfscrypt.c | 6 +- grub-core/fs/zfs/zfsinfo.c | 83 +++++++++++++------------- grub-core/gfxmenu/view.c | 3 +- grub-core/kern/emu/hostdisk.c | 20 +++---- grub-core/kern/emu/main.c | 10 ++-- grub-core/kern/emu/misc.c | 6 +- grub-core/kern/emu/mm.c | 2 +- grub-core/kern/mips/arc/init.c | 5 +- grub-core/kern/mips/loongson/init.c | 3 +- grub-core/kern/partition.c | 3 +- grub-core/lib/i386/halt.c | 3 +- grub-core/lib/mips/arc/reboot.c | 3 +- grub-core/lib/mips/loongson/reboot.c | 3 +- grub-core/loader/i386/pc/chainloader.c | 2 +- grub-core/loader/i386/xnu.c | 2 +- grub-core/loader/multiboot.c | 2 +- grub-core/net/bootp.c | 4 +- grub-core/net/net.c | 8 +-- grub-core/normal/term.c | 5 +- grub-core/partmap/bsdlabel.c | 3 +- grub-core/parttool/msdospart.c | 13 ++-- grub-core/term/gfxterm.c | 5 +- grub-core/term/terminfo.c | 2 +- grub-core/video/i386/pc/vbe.c | 17 +++--- util/grub-menulst2cfg.c | 7 ++- util/grub-mkdevicemap.c | 8 +-- util/grub-mklayout.c | 16 ++--- util/grub-mkrelpath.c | 10 ++-- util/grub-script-check.c | 10 ++-- util/ieee1275/grub-ofpathname.c | 2 +- util/resolve.c | 5 +- 49 files changed, 275 insertions(+), 200 deletions(-) diff --git a/ChangeLog b/ChangeLog index 725415cd0..c3c0cfe61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,54 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/commands/acpihalt.c: Gettextized. + * grub-core/commands/cacheinfo.c: Likewise. + * grub-core/commands/cmp.c: Likewise. + * grub-core/commands/efi/loadbios.c: Likewise. + * grub-core/commands/gptsync.c: Likewise. + * grub-core/commands/ieee1275/suspend.c: Likewise. + * grub-core/commands/legacycfg.c: Likewise. + * grub-core/commands/memrw.c: Likewise. + * grub-core/commands/minicmd.c: Likewise. + * grub-core/commands/parttool.c: Likewise. + * grub-core/commands/time.c: Likewise. + * grub-core/commands/videoinfo.c: Likewise. + * grub-core/disk/geli.c: Likewise. + * grub-core/disk/i386/pc/biosdisk.c: Likewise. + * grub-core/disk/luks.c: Likewise. + * grub-core/disk/lvm.c: Likewise. + * grub-core/font/font_cmd.c: Likewise. + * grub-core/fs/zfs/zfscrypt.c: Likewise. + * grub-core/fs/zfs/zfsinfo.c: Likewise. + * grub-core/gfxmenu/view.c: Likewise. + * grub-core/kern/emu/hostdisk.c: Likewise. + * grub-core/kern/emu/main.c: Likewise. + * grub-core/kern/emu/misc.c: Likewise. + * grub-core/kern/emu/mm.c: Likewise. + * grub-core/kern/mips/arc/init.c: Likewise. + * grub-core/kern/mips/loongson/init.c: Likewise. + * grub-core/kern/partition.c: Likewise. + * grub-core/lib/i386/halt.c: Likewise. + * grub-core/lib/mips/arc/reboot.c: Likewise. + * grub-core/lib/mips/loongson/reboot.c: Likewise. + * grub-core/loader/i386/pc/chainloader.c: Likewise. + * grub-core/loader/i386/xnu.c: Likewise. + * grub-core/loader/multiboot.c: Likewise. + * grub-core/net/bootp.c: Likewise. + * grub-core/net/net.c: Likewise. + * grub-core/normal/term.c: Likewise. + * grub-core/partmap/bsdlabel.c: Likewise. + * grub-core/parttool/msdospart.c: Likewise. + * grub-core/term/gfxterm.c: Likewise. + * grub-core/term/terminfo.c: Likewise. + * grub-core/video/i386/pc/vbe.c: Likewise. + * util/grub-menulst2cfg.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-mklayout.c: Likewise. + * util/grub-mkrelpath.c: Likewise. + * util/grub-script-check.c: Likewise. + * util/ieee1275/grub-ofpathname.c: Likewise. + * util/resolve.c: Likewise. + 2011-11-11 Vladimir Serbinenko Support %1$d syntax. diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 9a4cda521..177ec15f0 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -33,6 +33,7 @@ typedef uint8_t grub_uint8_t; #endif #include +#include #ifndef GRUB_DSDT_TEST #include @@ -327,6 +328,6 @@ grub_acpi_halt (void) grub_millisleep (1500); - grub_printf ("ACPI shutdown failed\n"); + grub_puts_ (N_("ACPI shutdown failed")); } #endif diff --git a/grub-core/commands/cacheinfo.c b/grub-core/commands/cacheinfo.c index 771763c9c..92aaa218d 100644 --- a/grub-core/commands/cacheinfo.c +++ b/grub-core/commands/cacheinfo.c @@ -31,14 +31,14 @@ grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)), unsigned long hits, misses; grub_disk_cache_get_performance (&hits, &misses); - grub_printf ("Disk cache: hits = %lu, misses = %lu ", hits, misses); + grub_printf_ (N_("Disk cache: hits = %lu, misses = %lu "), hits, misses); if (hits + misses) { unsigned long ratio = hits * 10000 / (hits + misses); grub_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100); } else - grub_printf ("(N/A)\n"); + grub_puts_ (N_("(N/A)")); return 0; } diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c index 526459311..5d5925dd5 100644 --- a/grub-core/commands/cmp.c +++ b/grub-core/commands/cmp.c @@ -42,8 +42,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), if (argc != 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); - grub_printf ("Compare file `%s' with `%s':\n", args[0], - args[1]); + grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], + args[1]); file1 = grub_file_open (args[0]); file2 = grub_file_open (args[1]); @@ -51,9 +51,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), goto cleanup; if (grub_file_size (file1) != grub_file_size (file2)) - grub_printf ("Files differ in size: %llu [%s], %llu [%s]\n", - (unsigned long long) grub_file_size (file1), args[0], - (unsigned long long) grub_file_size (file2), args[1]); + grub_printf_ (N_("Files differ in size: %llu [%s], %llu [%s]\n"), + (unsigned long long) grub_file_size (file1), args[0], + (unsigned long long) grub_file_size (file2), args[1]); else { pos = 0; @@ -78,9 +78,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), { if (buf1[i] != buf2[i]) { - grub_printf ("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n", - (unsigned long long) (i + pos), buf1[i], args[0], - buf2[i], args[1]); + grub_printf_ (N_("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n"), + (unsigned long long) (i + pos), buf1[i], + args[0], buf2[i], args[1]); goto cleanup; } } @@ -89,7 +89,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), } while (rd2); - grub_printf ("The files are identical.\n"); + /* TRANSLATORS: it's always exactly 2 files. */ + grub_printf_ (N_("The files are identical.\n")); } cleanup: diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c index 138311222..5eb490fd4 100644 --- a/grub-core/commands/efi/loadbios.c +++ b/grub-core/commands/efi/loadbios.c @@ -49,7 +49,7 @@ enable_rom_area (void) rom_ptr = (grub_uint32_t *) VBIOS_ADDR; if (*rom_ptr != BLANK_MEM) { - grub_printf ("ROM image is present.\n"); + grub_puts_ (N_("ROM image is present.")); return 0; } @@ -67,7 +67,7 @@ enable_rom_area (void) *rom_ptr = 0; if (*rom_ptr != 0) { - grub_printf ("Can\'t enable ROM area.\n"); + grub_puts_ (N_("Can\'t enable ROM area.")); return 0; } @@ -209,7 +209,7 @@ GRUB_MOD_INIT(loadbios) 0, N_("Fake BIOS.")); cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, - "BIOS_DUMP [INT10_DUMP]", + N_("BIOS_DUMP [INT10_DUMP]"), N_("Load BIOS dump.")); } diff --git a/grub-core/commands/gptsync.c b/grub-core/commands/gptsync.c index e92dc20ec..88d4b6296 100644 --- a/grub-core/commands/gptsync.c +++ b/grub-core/commands/gptsync.c @@ -231,7 +231,7 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - grub_printf ("New MBR is written to '%s'\n", args[0]); + grub_printf_ (N_("New MBR is written to '%s'\n"), args[0]); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/ieee1275/suspend.c b/grub-core/commands/ieee1275/suspend.c index de068951d..844485077 100644 --- a/grub-core/commands/ieee1275/suspend.c +++ b/grub-core/commands/ieee1275/suspend.c @@ -31,7 +31,7 @@ grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - grub_printf ("Run 'go' to resume GRUB.\n"); + grub_puts_ (N_("Run 'go' to resume GRUB.")); grub_ieee1275_enter (); grub_cls (); return 0; diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index 4e87adafc..4de2d84d5 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -723,7 +723,7 @@ grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unuse if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected"); - grub_printf ("Enter password:"); + grub_puts_ (N_("Enter password: ")); if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) return GRUB_ACCESS_DENIED; diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c index 3b51189d6..5984288ce 100644 --- a/grub-core/commands/memrw.c +++ b/grub-core/commands/memrw.c @@ -31,7 +31,7 @@ static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; static const struct grub_arg_option options[] = { {0, 'v', 0, N_("Save read value into variable VARNAME."), - "VARNAME", ARG_TYPE_STRING}, + N_("VARNAME"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c index b9cbd06c1..1bb0147df 100644 --- a/grub-core/commands/minicmd.c +++ b/grub-core/commands/minicmd.c @@ -145,7 +145,7 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), { grub_dl_t mod; - grub_printf ("Name\tRef Count\tDependencies\n"); + grub_printf_ (N_("Name\tRef Count\tDependencies\n")); FOR_DL_MODULES (mod) { grub_dl_dep_t dep; diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index a54286161..ab5ab5ea4 100644 --- a/grub-core/commands/parttool.c +++ b/grub-core/commands/parttool.c @@ -37,9 +37,9 @@ static struct grub_parttool *parts = 0; static int curhandle = 0; static grub_dl_t mymod; static char helpmsg[] = - "Perform COMMANDS on partition.\n" - "Use \"parttool PARTITION help\" for the list " - "of available commands."; + N_("Perform COMMANDS on partition.\n" + "Use \"parttool PARTITION help\" for the list " + "of available commands."); int grub_parttool_register(const char *part_name, @@ -128,7 +128,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), break; case GRUB_PARTTOOL_ARG_VAL: - grub_printf ("=VAL"); + grub_xputs (_("=VAL")); spacing -= 4; break; @@ -137,18 +137,18 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } while (spacing-- > 0) grub_printf (" "); - grub_printf ("%s\n", curarg->desc); + grub_puts_ (curarg->desc); } } if (! found) - grub_printf ("Sorry no parttool is available for %s\n", + grub_printf_ (N_("Sorry no parttool is available for %s\n"), dev->disk->partition->partmap->name); return GRUB_ERR_NONE; } if (argc < 1) { - grub_printf ("%s\n", helpmsg); + grub_puts_ (helpmsg); return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments"); } diff --git a/grub-core/commands/time.c b/grub-core/commands/time.c index 687495964..224f92b3f 100644 --- a/grub-core/commands/time.c +++ b/grub-core/commands/time.c @@ -47,8 +47,8 @@ grub_cmd_time (grub_command_t ctxt __attribute__ ((unused)), (cmd->func) (cmd, argc - 1, &args[1]); end = grub_get_time_ms (); - grub_printf ("Elapsed time: %d.%03d seconds \n", (end - start) / 1000, - (end - start) % 1000); + grub_printf_ (N_("Elapsed time: %d.%03d seconds \n"), (end - start) / 1000, + (end - start) % 1000); return grub_errno; } diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 7ff172fd7..9e12ff55e 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -52,36 +52,36 @@ hook (const struct grub_video_mode_info *info) grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) - grub_printf ("Text-only "); + grub_xputs (_("Text-only ")); /* Show mask and position details for direct color modes. */ if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) - grub_printf ("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d", - info->red_mask_size, - info->green_mask_size, - info->blue_mask_size, - info->reserved_mask_size, - info->red_field_pos, - info->green_field_pos, - info->blue_field_pos, - info->reserved_field_pos); + grub_printf_ (N_("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d"), + info->red_mask_size, + info->green_mask_size, + info->blue_mask_size, + info->reserved_mask_size, + info->red_field_pos, + info->green_field_pos, + info->blue_field_pos, + info->reserved_field_pos); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - grub_printf ("Packed "); + grub_xputs (_("Packed ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV) - grub_printf ("YUV "); + grub_xputs (_("YUV ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR) - grub_printf ("Planar "); + grub_xputs (_("Planar ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES) - grub_printf ("Hercules "); + grub_xputs (_("Hercules ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA) - grub_printf ("CGA "); + grub_xputs (_("CGA ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4) - grub_printf ("Non-chain 4 "); + grub_xputs (_("Non-chain 4 ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) - grub_printf ("Monochrome "); + grub_xputs (_("Monochrome ")); if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN) - grub_printf ("Unknown "); + grub_xputs (_("Unknown ")); - grub_printf ("\n"); + grub_xputs ("\n"); return 0; } @@ -93,19 +93,19 @@ print_edid (struct grub_video_edid_info *edid_info) if (grub_video_edid_checksum (edid_info)) { - grub_printf (" EDID checksum invalid\n"); + grub_puts_ (N_(" EDID checksum invalid")); grub_errno = GRUB_ERR_NONE; return; } - grub_printf (" EDID version: %u.%u\n", - edid_info->version, edid_info->revision); + grub_printf_ (N_(" EDID version: %u.%u\n"), + edid_info->version, edid_info->revision); if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height) == GRUB_ERR_NONE) - grub_printf (" Preferred mode: %ux%u\n", edid_width, edid_height); + grub_printf_ (N_(" Preferred mode: %ux%u\n"), edid_width, edid_height); else { - grub_printf (" No preferred mode available\n"); + grub_printf_ (N_(" No preferred mode available\n")); grub_errno = GRUB_ERR_NONE; } } @@ -147,20 +147,20 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), id = grub_video_get_driver_id (); - grub_printf ("List of supported video modes:\n"); - grub_printf ("Legend: P=Packed pixel, D=Direct color, " - "mask/pos=R/G/B/reserved\n"); + grub_puts_ (N_("List of supported video modes:")); + grub_puts_ (N_("Legend: P=Packed pixel, D=Direct color, " + "mask/pos=R/G/B/reserved")); FOR_VIDEO_ADAPTERS (adapter) { struct grub_video_mode_info info; struct grub_video_edid_info edid_info; - grub_printf ("Adapter '%s':\n", adapter->name); + grub_printf_ (N_("Adapter '%s':\n"), adapter->name); if (!adapter->iterate) { - grub_printf (" No info available\n"); + grub_puts_ (N_(" No info available")); continue; } @@ -178,7 +178,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), { if (adapter->init ()) { - grub_printf (" Failed\n"); + grub_puts_ (N_(" Failed")); grub_errno = GRUB_ERR_NONE; continue; } @@ -215,12 +215,13 @@ static grub_command_t cmd_vbe; GRUB_MOD_INIT(videoinfo) { - cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, "[WxH[xD]]", + cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, N_("[WxH[xD]]"), N_("List available video modes. If " "resolution is given show only modes" " matching it.")); #ifdef GRUB_MACHINE_PCBIOS - cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, "[WxH[xD]]", + cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, + N_("[WxH[xD]]"), N_("List available video modes. If " "resolution is given show only modes" " matching it.")); diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index ab94b4131..d3137bc16 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -226,7 +226,7 @@ grub_util_get_geli_uuid (const char *dev) uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1); if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0) - grub_util_error ("couldn't read ELI metadata"); + grub_util_error (_("couldn't read ELI metadata")); COMPILE_TIME_ASSERT (sizeof (header) <= 512); header = (void *) &hdr; @@ -235,7 +235,7 @@ grub_util_get_geli_uuid (const char *dev) if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) || grub_le_to_cpu32 (header->version) > 5 || grub_le_to_cpu32 (header->version) < 1) - grub_util_error ("wrong ELI magic or version"); + grub_util_error (_("wrong ELI magic or version")); err = make_uuid ((void *) &hdr, uuid); if (err) @@ -418,15 +418,15 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) keysize = grub_le_to_cpu16 (header.keylen) / 8; grub_memset (zero, 0, sizeof (zero)); - grub_printf ("Attempting to decrypt master key...\n"); + grub_puts_ (N_("Attempting to decrypt master key...")); /* Get the passphrase from the user. */ tmp = NULL; if (source->partition) tmp = grub_partition_get_name (source->partition); - grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name, - source->partition ? "," : "", tmp ? : "", - dev->uuid); + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, + source->partition ? "," : "", tmp ? : "", + dev->uuid); grub_free (tmp); if (!grub_password_get (passphrase, MAX_PASSPHRASE)) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); @@ -513,7 +513,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) if (grub_memcmp (candidate_key.hmac, key_hmac, dev->hash->mdlen) != 0) continue; - grub_printf ("Slot %d opened\n", i); + grub_printf_ (N_("Slot %d opened\n"), i); /* Set the master key. */ if (!dev->rekey) diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index e152b9d89..25f683fd1 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -27,6 +27,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -625,7 +626,7 @@ GRUB_MOD_INIT(biosdisk) if (grub_disk_firmware_is_tainted) { - grub_printf ("Firmware is marked as tainted, refusing to initialize.\n"); + grub_puts_ (N_("Firmware is marked as tainted, refusing to initialize.")); return; } grub_disk_firmware_fini = grub_disk_biosdisk_fini; diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 0ec95fccd..a5c0d3418 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -316,7 +316,7 @@ luks_recover_key (grub_disk_t source, if (err) return err; - grub_printf ("Attempting to decrypt master key...\n"); + grub_puts_ (N_("Attempting to decrypt master key...")); keysize = grub_be_to_cpu32 (header.keyBytes); for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) @@ -332,7 +332,7 @@ luks_recover_key (grub_disk_t source, tmp = NULL; if (source->partition) tmp = grub_partition_get_name (source->partition); - grub_printf ("Enter passphrase for %s%s%s (%s): ", source->name, + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, source->partition ? "," : "", tmp ? : "", dev->uuid); grub_free (tmp); @@ -434,7 +434,7 @@ luks_recover_key (grub_disk_t source, continue; } - grub_printf ("Slot %d opened\n", i); + grub_printf_ (N_("Slot %d opened\n"), i); /* Set the master key. */ gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 4020fc427..388c7f173 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -775,7 +776,7 @@ grub_lvm_memberlist (grub_disk_t disk) for (pv = lv->vg->pvs; pv; pv = pv->next) { if (!pv->disk) - grub_util_error ("Couldn't find PV %s. Check your device.map", + grub_util_error (_("Couldn't find PV %s. Check your device.map"), pv->name); tmp = grub_malloc (sizeof (*tmp)); tmp->disk = pv->disk; diff --git a/grub-core/font/font_cmd.c b/grub-core/font/font_cmd.c index 98f0b88d6..b38eccd6d 100644 --- a/grub-core/font/font_cmd.c +++ b/grub-core/font/font_cmd.c @@ -49,7 +49,7 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), { struct grub_font_node *node; - grub_printf ("Loaded fonts:\n"); + grub_puts_ (N_("Loaded fonts:")); for (node = grub_font_list; node; node = node->next) { grub_font_t font = node->value; diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 619878243..63380f66a 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -421,7 +421,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) } else { - grub_printf ("Enter ZFS password: "); + grub_xputs (_("Enter ZFS password: ")); if (!grub_password_get ((char *) buf, 1023)) return grub_errno; real_size = grub_strlen ((char *) buf); @@ -460,8 +460,8 @@ GRUB_MOD_INIT(zfscrypt) grub_zfs_decrypt = grub_zfs_decrypt_real; grub_zfs_load_key = grub_zfs_load_key_real; cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, - "zfskey [-h|-p|-r] [FILE]", - "Import ZFS wrapping key stored in FILE.", + N_("[-h|-p|-r] [FILE]"), + N_("Import ZFS wrapping key stored in FILE."), options); } diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index 8c073fab5..94f2a1ac8 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -44,32 +45,32 @@ print_state (char *nvlist, int tab) int isok = 1; print_tabs (tab); - grub_printf ("State: "); + grub_xputs (_("State: ")); if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_REMOVED, &ival)) { - grub_printf ("removed "); + grub_xputs (_("removed ")); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) { - grub_printf ("faulted "); + grub_xputs (_("faulted ")); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_OFFLINE, &ival)) { - grub_printf ("offline "); + grub_xputs (_("offline ")); isok = 0; } if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) - grub_printf ("degraded "); + grub_xputs (_("degraded ")); if (isok) - grub_printf ("online"); - grub_printf ("\n"); + grub_xputs (_("online")); + grub_xputs ("\n"); return GRUB_ERR_NONE; } @@ -84,7 +85,7 @@ print_vdev_info (char *nvlist, int tab) if (!type) { print_tabs (tab); - grub_printf ("Incorrect VDEV: no type available\n"); + grub_puts_ (N_("Incorrect VDEV: no type available")); return grub_errno; } @@ -95,7 +96,7 @@ print_vdev_info (char *nvlist, int tab) char *devid = 0; print_tabs (tab); - grub_printf ("Leaf VDEV\n"); + grub_puts_ (N_("Leaf VDEV")); print_state (nvlist, tab); @@ -103,23 +104,23 @@ print_vdev_info (char *nvlist, int tab) grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH); print_tabs (tab); if (!bootpath) - grub_printf ("Bootpath: unavailable\n"); + grub_puts_ (N_("Bootpath: unavailable\n")); else - grub_printf ("Bootpath: %s\n", bootpath); + grub_printf_ (N_("Bootpath: %s\n"), bootpath); path = grub_zfs_nvlist_lookup_string (nvlist, "path"); print_tabs (tab); if (!path) - grub_printf ("Path: unavailable\n"); + grub_puts_ (N_("Path: unavailable")); else - grub_printf ("Path: %s\n", path); + grub_printf_ (N_("Path: %s\n"), path); devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); print_tabs (tab); if (!devid) - grub_printf ("Devid: unavailable\n"); + grub_puts_ (N_("Devid: unavailable")); else - grub_printf ("Devid: %s\n", devid); + grub_printf_ (N_("Devid: %s\n"), devid); grub_free (bootpath); grub_free (devid); grub_free (path); @@ -136,10 +137,10 @@ print_vdev_info (char *nvlist, int tab) print_tabs (tab); if (nelm <= 0) { - grub_printf ("Incorrect mirror VDEV\n"); + grub_puts_ (N_("Incorrect mirror VDEV")); return GRUB_ERR_NONE; } - grub_printf ("Mirror VDEV with %d children\n", nelm); + grub_printf_ (N_("Mirror VDEV with %d children\n"), nelm); print_state (nvlist, tab); for (i = 0; i < nelm; i++) { @@ -151,11 +152,11 @@ print_vdev_info (char *nvlist, int tab) print_tabs (tab); if (!child) { - grub_printf ("Mirror VDEV element %d isn't correct\n", i); + grub_printf_ (N_("Mirror VDEV element %d isn't correct\n"), i); continue; } - grub_printf ("Mirror VDEV element %d:\n", i); + grub_printf_ (N_("Mirror VDEV element %d:\n"), i); print_vdev_info (child, tab + 1); grub_free (child); @@ -164,7 +165,7 @@ print_vdev_info (char *nvlist, int tab) } print_tabs (tab); - grub_printf ("Unknown VDEV type: %s\n", type); + grub_printf_ (N_("Unknown VDEV type: %s\n"), type); return GRUB_ERR_NONE; } @@ -221,15 +222,15 @@ get_bootpath (char *nvlist, char **bootpath, char **devid) return GRUB_ERR_NONE; } -static char *poolstates[] = { - [POOL_STATE_ACTIVE] = "active", - [POOL_STATE_EXPORTED] = "exported", - [POOL_STATE_DESTROYED] = "destroyed", - [POOL_STATE_SPARE] = "reserved for hot spare", - [POOL_STATE_L2CACHE] = "level 2 ARC device", - [POOL_STATE_UNINITIALIZED] = "uninitialized", - [POOL_STATE_UNAVAIL] = "unavailable", - [POOL_STATE_POTENTIALLY_ACTIVE] = "potentially active" +static const char *poolstates[] = { + [POOL_STATE_ACTIVE] = N_("Pool state: active"), + [POOL_STATE_EXPORTED] = N_("Pool state: exported"), + [POOL_STATE_DESTROYED] = N_("Pool state: destroyed"), + [POOL_STATE_SPARE] = N_("Pool state: reserved for hot spare"), + [POOL_STATE_L2CACHE] = N_("Pool state: level 2 ARC device"), + [POOL_STATE_UNINITIALIZED] = N_("Pool state: uninitialized"), + [POOL_STATE_UNAVAIL] = N_("Pool state: unavailable"), + [POOL_STATE_POTENTIALLY_ACTIVE] = N_("Pool state: potentially active") }; static grub_err_t @@ -274,30 +275,30 @@ grub_cmd_zfsinfo (grub_command_t cmd __attribute__ ((unused)), int argc, poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); if (!poolname) - grub_printf ("Pool name: unavailable\n"); + grub_puts_ (N_("Pool name: unavailable")); else - grub_printf ("Pool name: %s\n", poolname); + grub_printf_ (N_("Pool name: %s\n"), poolname); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); if (!found) - grub_printf ("Pool GUID: unavailable\n"); + grub_puts_ (N_("Pool GUID: unavailable")); else - grub_printf ("Pool GUID: %016llx\n", (long long unsigned) guid); + grub_printf_ (N_("Pool GUID: %016llx\n"), (long long unsigned) guid); found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, &pool_state); if (!found) - grub_printf ("Unable to retrieve pool state\n"); + grub_puts_ (N_("Unable to retrieve pool state")); else if (pool_state >= ARRAY_SIZE (poolstates)) - grub_printf ("Unrecognized pool state\n"); + grub_puts_ (N_("Unrecognized pool state")); else - grub_printf ("Pool state: %s\n", poolstates[pool_state]); + grub_puts_ (poolstates[pool_state]); nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); if (!nv) - grub_printf ("No vdev tree available\n"); + grub_puts_ (N_("No vdev tree available")); else print_vdev_info (nv, 1); @@ -395,11 +396,11 @@ static grub_command_t cmd_info, cmd_bootfs; GRUB_MOD_INIT (zfsinfo) { cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, - "zfsinfo DEVICE", - "Print ZFS info about DEVICE."); + N_("DEVICE"), + N_("Print ZFS info about DEVICE.")); cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, - "zfs-bootfs FILESYSTEM [VARIABLE]", - "Print ZFS-BOOTFSOBJ or set it to VARIABLE"); + N_("FILESYSTEM [VARIABLE]"), + N_("Print ZFS-BOOTFSOBJ or set it to VARIABLE")); } GRUB_MOD_FINI (zfsinfo) diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c index 836a9884d..9023fd3c4 100644 --- a/grub-core/gfxmenu/view.c +++ b/grub-core/gfxmenu/view.c @@ -36,6 +36,7 @@ #include #include #include +#include static void init_terminal (grub_gfxmenu_view_t view); @@ -77,7 +78,7 @@ grub_gfxmenu_view_new (const char *theme_path, view->desktop_image = 0; view->desktop_color = default_bg_color; view->terminal_box = grub_gfxmenu_create_box (0, 0); - view->title_text = grub_strdup ("GRUB Boot Menu"); + view->title_text = grub_strdup (_("GRUB Boot Menu")); view->progress_message_text = 0; view->theme_path = 0; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 7bfc66fef..f537b2759 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -269,7 +269,7 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) struct stat st; if (fstat (fd, &st) < 0) - grub_util_error ("fstat failed"); + grub_util_error (_("fstat failed")); #if defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) \ @@ -324,7 +324,7 @@ grub_util_get_fd_sectors (int fd, unsigned *log_secsize) return minfo.dki_capacity; # else if (nr & ((1 << log_sector_size) - 1)) - grub_util_error ("unaligned device size"); + grub_util_error (_("unaligned device size")); return (nr >> log_sector_size); # endif @@ -373,7 +373,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) size = grub_util_get_disk_size (map[drive].device); if (size % 512) - grub_util_error ("unaligned device size"); + grub_util_error (_("unaligned device size")); disk->total_sectors = size >> 9; @@ -442,13 +442,13 @@ grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **n error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) if (strcasecmp (class->lg_name, "part") == 0) break; if (!class) - grub_util_error ("couldn't open geom part"); + grub_util_error (_("couldn't open geom part")); LIST_FOREACH (geom, &class->lg_geom, lg_geom) { @@ -1144,18 +1144,18 @@ read_device_map (const char *dev_map) continue; if (*p != '(') - show_error ("No open parenthesis found"); + show_error (_("No open parenthesis found")); p++; /* Find a free slot. */ drive = find_free_slot (); if (drive < 0) - show_error ("Map table size exceeded"); + show_error (_("Map table size exceeded")); e = p; p = strchr (p, ')'); if (! p) - show_error ("No close parenthesis found"); + show_error (_("No close parenthesis found")); map[drive].drive = xmalloc (p - e + sizeof ('\0')); strncpy (map[drive].drive, e, p - e + sizeof ('\0')); @@ -1167,7 +1167,7 @@ read_device_map (const char *dev_map) p++; if (*p == '\0') - show_error ("No filename found"); + show_error (_("No filename found")); /* NUL-terminate the filename. */ e = p; @@ -1196,7 +1196,7 @@ read_device_map (const char *dev_map) { map[drive].device = xmalloc (PATH_MAX); if (! realpath (p, map[drive].device)) - grub_util_error ("cannot get the real path of `%s'", p); + grub_util_error (_("cannot get the real path of `%s'"), p); } else #endif diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 8d15f17c5..725d1ac7f 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -98,10 +98,10 @@ usage (int status) { if (status) fprintf (stderr, - "Try `%s --help' for more information.\n", program_name); + _("Try `%s --help' for more information.\n"), program_name); else printf ( - "Usage: %s [OPTION]...\n" + _("Usage: %s [OPTION]...\n" "\n" "GRUB emulator.\n" "\n" @@ -113,7 +113,7 @@ usage (int status) " -h, --help display this message and exit\n" " -V, --version print version information and exit\n" "\n" - "Report bugs to <%s>.\n", program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); + "Report bugs to <%s>.\n"), program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); return status; } @@ -166,13 +166,13 @@ main (int argc, char *argv[]) if (optind < argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind]); return usage (1); } /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */ if (hold && verbosity > 0) - printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n", + printf (_("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n"), program_name, (int) getpid ()); while (hold) { diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 6f5ea9fb9..21f314d55 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -117,7 +117,7 @@ xmalloc (grub_size_t size) p = malloc (size); if (! p) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); return p; } @@ -127,7 +127,7 @@ xrealloc (void *ptr, grub_size_t size) { ptr = realloc (ptr, size); if (! ptr) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); return ptr; } @@ -185,7 +185,7 @@ xasprintf (const char *fmt, ...) if (vasprintf (&result, fmt, ap) < 0) { if (errno == ENOMEM) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); return NULL; } diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c index 6a70efb4c..b58ccc794 100644 --- a/grub-core/kern/emu/mm.c +++ b/grub-core/kern/emu/mm.c @@ -77,7 +77,7 @@ grub_memalign (grub_size_t align, grub_size_t size) #else (void) align; (void) size; - grub_util_error ("grub_memalign is not supported"); + grub_util_error (_("grub_memalign is not supported")); #endif if (!p) diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index ec0fa521a..41545b11f 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -33,6 +33,7 @@ #include #include #include +#include const char *type_names[] = { #ifdef GRUB_CPU_WORDS_BIGENDIAN @@ -178,7 +179,7 @@ grub_halt (void) grub_millisleep (1500); - grub_printf ("Shutdown failed\n"); + grub_puts_ (N_("Shutdown failed")); grub_refresh (); while (1); } @@ -190,7 +191,7 @@ grub_exit (void) grub_millisleep (1500); - grub_printf ("Exit failed\n"); + grub_puts_ (N_("Exit failed")); grub_refresh (); while (1); } diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 6ddf151f2..3b282e1e0 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -31,6 +31,7 @@ #include #include #include +#include extern void grub_video_sm712_init (void); extern void grub_video_sis315pro_init (void); @@ -254,7 +255,7 @@ grub_halt (void) break; } - grub_printf ("Shutdown failed\n"); + grub_puts_ (N_("Shutdown failed")); grub_refresh (); while (1); } diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index a2f5dd722..cd9e8ae0f 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -47,7 +48,7 @@ grub_partition_check_containment (const grub_disk_t disk, grub_dprintf ("partition", "sub-partition %s%d of (%s,%s) ends after parent.\n", part->partmap->name, part->number + 1, disk->name, partname); #ifdef GRUB_UTIL - grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", + grub_util_warn (_("Discarding improperly nested partition (%s,%s,%s%d)"), disk->name, partname, part->partmap->name, part->number + 1); #endif grub_free (partname); diff --git a/grub-core/lib/i386/halt.c b/grub-core/lib/i386/halt.c index 15c4ba0d6..bd878c9bf 100644 --- a/grub-core/lib/i386/halt.c +++ b/grub-core/lib/i386/halt.c @@ -19,6 +19,7 @@ #include #include #include +#include const char bochs_shutdown[] = "Shutdown"; @@ -52,7 +53,7 @@ grub_halt (void) for (i = 0; i < sizeof (bochs_shutdown) - 1; i++) grub_outb (bochs_shutdown[i], 0x8900); - grub_printf ("GRUB doesn't know how to halt this machine yet!\n"); + grub_puts_ (N_("GRUB doesn't know how to halt this machine yet!")); /* In order to return we'd have to check what the previous status of IF flag was. But user most likely doesn't want to return anyway ... */ diff --git a/grub-core/lib/mips/arc/reboot.c b/grub-core/lib/mips/arc/reboot.c index f0d085765..ecf12a7ed 100644 --- a/grub-core/lib/mips/arc/reboot.c +++ b/grub-core/lib/mips/arc/reboot.c @@ -20,6 +20,7 @@ #include #include #include +#include void grub_reboot (void) @@ -28,7 +29,7 @@ grub_reboot (void) grub_millisleep (1500); - grub_printf ("Reboot failed\n"); + grub_puts_ (N_("Reboot failed")); grub_refresh (); while (1); } diff --git a/grub-core/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c index f099ba250..1b510784b 100644 --- a/grub-core/lib/mips/loongson/reboot.c +++ b/grub-core/lib/mips/loongson/reboot.c @@ -24,6 +24,7 @@ #include #include #include +#include void grub_reboot (void) @@ -51,7 +52,7 @@ grub_reboot (void) } grub_millisleep (1500); - grub_printf ("Reboot failed\n"); + grub_puts_ (N_("Reboot failed")); grub_refresh (); while (1); } diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c index 8d6ec8f20..42fbdeb32 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -247,7 +247,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(chainloader) { cmd = grub_register_command ("chainloader", grub_cmd_chainloader, - "[--force|--bpb] FILE", + N_("[--force|--bpb] FILE"), N_("Load another boot loader.")); my_mod = mod; } diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index fa7af514b..36893ae62 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -1018,7 +1018,7 @@ grub_xnu_boot (void) { grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_printf ("Booting in blind mode\n"); + grub_puts_ (N_("Booting in blind mode")); bootparams->lfb_mode = 0; bootparams->lfb_width = 0; diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index d9e74b3c7..2de8e0909 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -182,7 +182,7 @@ grub_multiboot_set_console (int console_type, int accepted_consoles, if (console_required) return grub_error (GRUB_ERR_BAD_OS, "OS requires a console but none is available"); - grub_printf ("WARNING: no console will be available to OS"); + grub_puts_ (N_("WARNING: no console will be available to OS")); accepts_video = 0; accepts_ega_text = 0; return GRUB_ERR_NONE; diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index 84bdc04d7..ba6a29020 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -520,10 +520,10 @@ void grub_bootp_init (void) { cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, - "[CARD]", + N_("[CARD]"), N_("perform a bootp autoconfiguration")); cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, - "[CARD]", + N_("[CARD]"), N_("perform a bootp autoconfiguration")); cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, N_("VAR INTERFACE NUMBER DESCRIPTION"), diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 0f8a60413..09acea900 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -946,16 +946,16 @@ static grub_command_t cmd_lsaddr; GRUB_MOD_INIT(net) { cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, - "SHORTNAME CARD ADDRESS [HWADDRESS]", + N_("SHORTNAME CARD ADDRESS [HWADDRESS]"), N_("Add a network address.")); cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, - "SHORTNAME", + N_("SHORTNAME"), N_("Delete a network address.")); cmd_addroute = grub_register_command ("net_add_route", grub_cmd_addroute, - "SHORTNAME NET [INTERFACE| gw GATEWAY]", + N_("SHORTNAME NET [INTERFACE| gw GATEWAY]"), N_("Add a network route.")); cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, - "SHORTNAME", + N_("SHORTNAME"), N_("Delete a network route.")); cmd_lsroutes = grub_register_command ("net_ls_routes", grub_cmd_listroutes, "", N_("list network routes")); diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index a8b9e6683..922f8518f 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -24,6 +24,7 @@ #include #include #include +#include struct term_state { @@ -63,7 +64,9 @@ print_more (void) pos = grub_term_save_pos (); - grub_utf8_to_ucs4_alloc ("--MORE--", &unicode_str, + /* TRANSLATORS: This has to fit on one line. It's ok to include few + words but don't write poems. */ + grub_utf8_to_ucs4_alloc (_("--MORE--"), &unicode_str, &unicode_last_position); if (!unicode_str) diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 888100aa2..490fbdd7b 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -24,6 +24,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -105,7 +106,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, /* disk->partition != NULL as 0 < delta */ partname = disk->partition ? grub_partition_get_name (disk->partition) : ""; - grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)", + grub_util_warn (_("Discarding improperly nested partition (%s,%s,%s%d)"), disk->name, partname, p.partmap->name, p.number + 1); grub_free (partname); #endif diff --git a/grub-core/parttool/msdospart.c b/grub-core/parttool/msdospart.c index ecaca140a..3377a2ccc 100644 --- a/grub-core/parttool/msdospart.c +++ b/grub-core/parttool/msdospart.c @@ -27,6 +27,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv2+"); @@ -35,7 +36,7 @@ static int type_table_handle = -1; static struct grub_parttool_argdesc grub_pcpart_bootargs[] = { - {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL}, + {"boot", N_("Make partition active"), GRUB_PARTTOOL_ARG_BOOL}, {0, 0, 0} }; @@ -65,12 +66,12 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev, for (i = 0; i < 4; i++) mbr.entries[i].flag = 0x0; mbr.entries[index].flag = 0x80; - grub_printf ("Partition %d is active now. \n", index); + grub_printf_ (N_("Partition %d is active now. \n"), index); } else { mbr.entries[index].flag = 0x0; - grub_printf ("Cleared active flag on %d. \n", index); + grub_printf (N_("Cleared active flag on %d. \n"), index); } /* Write the MBR. */ @@ -83,8 +84,8 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev, static struct grub_parttool_argdesc grub_pcpart_typeargs[] = { - {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL}, - {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL}, + {"type", N_("Change partition type"), GRUB_PARTTOOL_ARG_VAL}, + {"hidden", N_("Make partition hidden"), GRUB_PARTTOOL_ARG_BOOL}, {0, 0, 0} }; @@ -129,7 +130,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, } mbr.entries[index].type = type; - grub_printf ("Setting partition type to 0x%x\n", type); + grub_printf_ (N_("Setting partition type to 0x%x\n"), type); /* Write the parttable. */ grub_disk_write (dev->disk, part->offset, 0, diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 2f8deac18..a10af5930 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1111,7 +1111,10 @@ grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func) static const struct grub_arg_option background_image_cmd_options[] = { - {"mode", 'm', 0, "Background image mode.", "stretch|normal", + /* TRANSLATORS: note that GRUB will accept only original keywords stretch + and normal, not the translated ones. So please put both in translation + e.g. stretch=(%STRETCH%)|normal(=%NORMAL). */ + {"mode", 'm', 0, N_("Background image mode."), N_("stretch|normal"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 3419a5117..f8b29ec2e 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -606,7 +606,7 @@ print_terminfo (void) }; struct grub_term_output *cur; - grub_printf ("Current terminfo types: \n"); + grub_puts_ (N_("Current terminfo types:")); for (cur = terminfo_outputs; cur; cur = ((struct grub_terminfo_output_state *) cur->data)->next) grub_printf ("%s: %s\t%s\n", cur->name, diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 438ac92b2..92dd7ec07 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -993,15 +994,15 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, static void grub_video_vbe_print_adapter_specific_info (void) { - grub_printf (" VBE info: version: %d.%d OEM software rev: %d.%d\n", - controller_info.version >> 8, - controller_info.version & 0xFF, - controller_info.oem_software_rev >> 8, - controller_info.oem_software_rev & 0xFF); - + grub_printf_ (N_(" VBE info: version: %d.%d OEM software rev: %d.%d\n"), + controller_info.version >> 8, + controller_info.version & 0xFF, + controller_info.oem_software_rev >> 8, + controller_info.oem_software_rev & 0xFF); + /* The total_memory field is in 64 KiB units. */ - grub_printf (" total memory: %d KiB\n", - (controller_info.total_memory << 16) / 1024); + grub_printf_ (N_(" total memory: %d KiB\n"), + (controller_info.total_memory << 16) / 1024); } static struct grub_video_adapter grub_video_vbe_adapter = diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 513af47c1..aeabad976 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -24,6 +24,7 @@ #include #include #include +#include int main (int argc, char **argv) @@ -37,7 +38,7 @@ main (int argc, char **argv) if (argc >= 2 && argv[1][0] == '-') { - fprintf (stdout, "Usage: %s [INFILE [OUTFILE]]\n", argv[0]); + fprintf (stdout, _("Usage: %s [INFILE [OUTFILE]]\n"), argv[0]); return 0; } @@ -46,7 +47,7 @@ main (int argc, char **argv) in = fopen (argv[1], "r"); if (!in) { - fprintf (stderr, "Couldn't open %s for reading: %s\n", + fprintf (stderr, _("Couldn't open %s for reading: %s\n"), argv[1], strerror (errno)); return 1; } @@ -61,7 +62,7 @@ main (int argc, char **argv) { if (in != stdin) fclose (in); - fprintf (stderr, "Couldn't open %s for writing: %s\n", + fprintf (stderr, _("Couldn't open %s for writing: %s\n"), argv[2], strerror (errno)); return 1; } diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index bdecae4a3..bdf8ef1c6 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -62,7 +62,7 @@ make_device_map (const char *device_map, int floppy_disks) fp = fopen (device_map, "w"); if (! fp) - grub_util_error ("cannot open %s", device_map); + grub_util_error (_("cannot open %s"), device_map); grub_util_iterate_devices (process_device, floppy_disks); @@ -86,9 +86,9 @@ usage (int status) { if (status) fprintf (stderr, - "Try `%s --help' for more information.\n", program_name); + _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTION]...\n\ \n\ Generate a device map file automatically.\n\ @@ -101,7 +101,7 @@ Generate a device map file automatically.\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +"), program_name, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); exit (status); diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 04501cb40..8de07747d 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -260,9 +260,9 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS]\n\ -i, --input set input filename. Default is STDIN\n\ -o, --output set output filename. Default is STDOUT\n\ @@ -270,7 +270,7 @@ Usage: %s [OPTIONS]\n\ -V, --version print version information and exit.\n\ -v, --verbose print verbose messages.\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -300,7 +300,7 @@ lookup (char *code, int shift) if (strcmp (code, console_grub_equivalences_common[i].layout) == 0) return console_grub_equivalences_common[i].grub; - fprintf (stderr, "Unknown key %s\n", code); + fprintf (stderr, _("Unknown key %s\n"), code); return '\0'; } @@ -396,7 +396,7 @@ write_keymaps (FILE *in, FILE *out) if (keycode_usb == 0 || keycode_usb >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) { - fprintf (stderr, "Unknown keycode 0x%02x\n", keycode_linux); + fprintf (stderr, _("Unknown keycode 0x%02x\n"), keycode_linux); continue; } if (keycode_usb < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) @@ -414,7 +414,7 @@ write_keymaps (FILE *in, FILE *out) if (ok == 0) { - fprintf (stderr, "ERROR: no keycodes found. Check output of %s.\n", + fprintf (stderr, _("ERROR: no keycodes found. Check output of %s.\n"), CKBCOMP); exit (1); } @@ -479,7 +479,7 @@ main (int argc, char *argv[]) in = stdin; if (!in) - grub_util_error ("Couldn't open input file: %s\n", strerror (errno)); + grub_util_error (_("Couldn't open input file: %s\n"), strerror (errno)); if (outfile_name) out = fopen (outfile_name, "wb"); @@ -490,7 +490,7 @@ main (int argc, char *argv[]) { if (in != stdin) fclose (in); - grub_util_error ("Couldn't open output file: %s\n", strerror (errno)); + grub_util_error (_("Couldn't open output file: %s\n"), strerror (errno)); } write_keymaps (in, out); diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index 3fe3fe698..788db38a2 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -38,9 +38,9 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS] PATH\n\ \n\ Make a system path relative to its root.\n\ @@ -49,7 +49,7 @@ Options:\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -89,13 +89,13 @@ main (int argc, char *argv[]) if (optind >= argc) { - fprintf (stderr, "No path is specified.\n"); + fprintf (stderr, _("No path is specified.\n")); usage (1); } if (optind + 1 != argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); usage (1); } diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 2d1b31c9a..25358a553 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -51,9 +51,9 @@ usage (int status) { if (status) fprintf (stderr, - "Try ``%s --help'' for more information.\n", program_name); + _("Try ``%s --help'' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [PATH]\n\ \n\ Checks GRUB script configuration file for syntax errors.\n\ @@ -63,7 +63,7 @@ Checks GRUB script configuration file for syntax errors.\n\ -v, --verbose print the script as it is being processed\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -157,7 +157,7 @@ main (int argc, char *argv[]) } else if (optind + 1 != argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); usage (1); } else @@ -193,7 +193,7 @@ main (int argc, char *argv[]) if (found_input && script == 0) { - fprintf (stderr, "error: line no: %u\n", lineno); + fprintf (stderr, _("error: line no: %u\n"), lineno); return 1; } diff --git a/util/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c index ee81457b3..03d47bc99 100644 --- a/util/ieee1275/grub-ofpathname.c +++ b/util/ieee1275/grub-ofpathname.c @@ -36,7 +36,7 @@ int main(int argc, char **argv) if (argc != 2 || strcmp (argv[1], "--help") == 0) { - printf("Usage: %s DEVICE\n", program_name); + printf(_("Usage: %s DEVICE\n"), program_name); return 1; } if (strcmp (argv[1], "--version") == 0) diff --git a/util/resolve.c b/util/resolve.c index 63bd7ccb2..3eb8bfb14 100644 --- a/util/resolve.c +++ b/util/resolve.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Module. */ struct mod_list @@ -87,7 +88,7 @@ read_dep_list (FILE *fp) /* Get the target name. */ p = strchr (buf, ':'); if (! p) - grub_util_error ("invalid line format: %s", buf); + grub_util_error (_("invalid line format: %s"), buf); *p++ = '\0'; @@ -240,7 +241,7 @@ grub_util_resolve_dependencies (const char *prefix, path = grub_util_get_path (prefix, dep_list_file); fp = fopen (path, "r"); if (! fp) - grub_util_error ("cannot open %s", path); + grub_util_error (_("cannot open %s"), path); free (path); dep_list = read_dep_list (fp); From 119d11c8857ce2d354fbbada64cc27f783b57ecb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Nov 2011 22:35:09 +0100 Subject: [PATCH 1390/1414] Replace grub_fatal with normal errors in i386 linux loader. * grub-core/loader/i386/linux.c (find_efi_mmap_size): Return 0 on error. (allocate_pages): Check find_efi_mmap_size return value. (grub_e820_add_region): Return error. (grub_linux_boot): Check mmap return value. --- ChangeLog | 9 +++++++++ grub-core/loader/i386/linux.c | 38 ++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3c0cfe61..490bc693b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-11 Vladimir Serbinenko + + Replace grub_fatal with normal errors in i386 linux loader. + + * grub-core/loader/i386/linux.c (find_efi_mmap_size): Return 0 on error. + (allocate_pages): Check find_efi_mmap_size return value. + (grub_e820_add_region): Return error. + (grub_linux_boot): Check mmap return value. + 2011-11-11 Vladimir Serbinenko * grub-core/commands/acpihalt.c: Gettextized. diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index a6eb95028..c63c6c3ef 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -130,7 +130,10 @@ find_efi_mmap_size (void) grub_free (mmap); if (ret < 0) - grub_fatal ("cannot get memory map"); + { + grub_error (GRUB_ERR_IO, "cannot get memory map"); + return 0; + } else if (ret > 0) break; @@ -198,6 +201,8 @@ allocate_pages (grub_size_t prot_size) #ifdef GRUB_MACHINE_EFI efi_mmap_size = find_efi_mmap_size (); + if (efi_mmap_size == 0) + return grub_errno; #endif grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n", @@ -291,7 +296,7 @@ allocate_pages (grub_size_t prot_size) return err; } -static void +static grub_err_t grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, grub_uint64_t start, grub_uint64_t size, grub_uint32_t type) @@ -299,7 +304,10 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, int n = *e820_num; if (n >= GRUB_E820_MAX_ENTRY) - grub_fatal ("Too many e820 memory map entries"); + { + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "Too many e820 memory map entries"); + } if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) && (e820_map[n - 1].type == type)) @@ -311,6 +319,7 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, e820_map[n].type = type; (*e820_num)++; } + return GRUB_ERR_NONE; } static grub_err_t @@ -446,37 +455,38 @@ grub_linux_boot (void) int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type) { + grub_uint32_t e820_type; switch (type) { case GRUB_MEMORY_AVAILABLE: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_RAM); + e820_type = GRUB_E820_RAM; break; case GRUB_MEMORY_ACPI: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_ACPI); + e820_type = GRUB_E820_ACPI; break; case GRUB_MEMORY_NVS: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_NVS); + e820_type = GRUB_E820_NVS; break; case GRUB_MEMORY_BADRAM: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_BADRAM); + e820_type = GRUB_E820_BADRAM; break; default: - grub_e820_add_region (params->e820_map, &e820_num, - addr, size, GRUB_E820_RESERVED); + e820_type = GRUB_E820_RESERVED; } + if (grub_e820_add_region (params->e820_map, &e820_num, + addr, size, e820_type)) + return 1; + return 0; } e820_num = 0; - grub_mmap_iterate (hook); + if (grub_mmap_iterate (hook)) + return grub_errno; params->mmap_size = e820_num; modevar = grub_env_get ("gfxpayload"); From 566f779bd8a7245f5c867ab276d62a0b54d3c222 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 11 Nov 2011 22:58:18 +0100 Subject: [PATCH 1391/1414] 2011-11-11 Robert Millan * util/getroot.c (grub_util_get_geom_abstraction): Remove __attribute__((unused)) from `os_dev', which *is* being used. --- ChangeLog | 5 +++++ util/getroot.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 490bc693b..6b726987a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-11 Robert Millan + + * util/getroot.c (grub_util_get_geom_abstraction): Remove + __attribute__((unused)) from `os_dev', which *is* being used. + 2011-11-11 Vladimir Serbinenko Replace grub_fatal with normal errors in i386 linux loader. diff --git a/util/getroot.c b/util/getroot.c index 41fbdec10..750773c90 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -826,7 +826,7 @@ grub_util_get_geom_abstraction (const char *dev) #endif int -grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) +grub_util_get_dev_abstraction (const char *os_dev) { #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* User explicitly claims that this drive is visible by BIOS. */ From b50787de091db9e94dc48fe68e3d79d5126d065d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 00:26:04 +0100 Subject: [PATCH 1392/1414] * include/grub/dl.h (GRUB_ARCH_DL_TRAMP_SIZE) [__ia64__]: Add back forgotten define. (GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Redefine in terms of GRUB_IA64_DL_GOT_ALIGN. (GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Redefine in terms of GRUB_IA64_DL_TRAMP_ALIGN. --- ChangeLog | 9 +++++++++ include/grub/dl.h | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b726987a..3970ec293 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,15 @@ * util/getroot.c (grub_util_get_geom_abstraction): Remove __attribute__((unused)) from `os_dev', which *is* being used. +2011-11-11 Vladimir Serbinenko + + * include/grub/dl.h (GRUB_ARCH_DL_TRAMP_SIZE) [__ia64__]: Add back + forgotten define. + (GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Redefine in terms of + GRUB_IA64_DL_GOT_ALIGN. + (GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Redefine in terms of + GRUB_IA64_DL_TRAMP_ALIGN. + 2011-11-11 Vladimir Serbinenko Replace grub_fatal with normal errors in i386 linux loader. diff --git a/include/grub/dl.h b/include/grub/dl.h index 886e966cc..d5f009829 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -178,8 +178,9 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #if defined (__ia64__) -#define GRUB_ARCH_DL_TRAMP_ALIGN 16 -#define GRUB_ARCH_DL_GOT_ALIGN 16 +#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN +#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN +#define GRUB_ARCH_DL_TRAMP_SIZE GRUB_IA64_DL_TRAMP_SIZE #define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size #else void From 10f0117bf93a31cdf952a6379ab33a03e4920993 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 00:34:14 +0100 Subject: [PATCH 1393/1414] * grub-core/commands/efi/fixvideo.c: Gettextize. * grub-core/commands/hashsum.c: Likewise. * grub-core/commands/i386/cmostest.c: Likewise. * grub-core/commands/i386/pc/drivemap.c: Likewise. * grub-core/commands/i386/pc/lsapm.c: Likewise. * grub-core/commands/i386/pc/sendkey.c: Likewise. * grub-core/commands/lsmmap.c: Likewise. * grub-core/commands/menuentry.c: Likewise. * grub-core/commands/mips/loongson/lsspd.c: Likewise. * grub-core/commands/setpci.c: Likewise. * grub-core/loader/i386/bsd.c: Likewise. * grub-core/loader/i386/linux.c: Likewise. * util/getroot.c: Likewise. * util/grub-editenv.c: Likewise. * util/grub-fstest.c: Likewise. * util/grub-mkfont.c: Likewise. * util/grub-mkimage.c: Likewise. * util/grub-mkpasswd-pbkdf2.c: Likewise. * util/grub-pe2elf.c: Likewise. * util/grub-probe.c: Likewise. * util/grub-setup.c: Likewise. * util/ieee1275/ofpath.c: Likewise. * util/misc.c: Likewise. * util/raid.c: Likewise. --- ChangeLog | 27 +++++++++++ grub-core/commands/efi/fixvideo.c | 10 ++-- grub-core/commands/hashsum.c | 10 ++-- grub-core/commands/i386/cmostest.c | 9 ++-- grub-core/commands/i386/pc/drivemap.c | 4 +- grub-core/commands/i386/pc/lsapm.c | 32 ++++++------- grub-core/commands/i386/pc/sendkey.c | 39 ++++++++-------- grub-core/commands/lsmmap.c | 22 ++++----- grub-core/commands/menuentry.c | 8 ++-- grub-core/commands/mips/loongson/lsspd.c | 24 +++++----- grub-core/commands/setpci.c | 14 +++--- grub-core/loader/i386/bsd.c | 10 ++-- grub-core/loader/i386/linux.c | 28 ++++++------ util/getroot.c | 58 ++++++++++++------------ util/grub-editenv.c | 28 ++++++------ util/grub-fstest.c | 10 ++-- util/grub-mkfont.c | 57 +++++++++++------------ util/grub-mkimage.c | 22 ++++----- util/grub-mkpasswd-pbkdf2.c | 35 +++++++------- util/grub-pe2elf.c | 2 + util/grub-probe.c | 29 ++++++------ util/grub-setup.c | 29 ++++++------ util/ieee1275/ofpath.c | 20 ++++---- util/misc.c | 22 ++++----- util/raid.c | 13 +++--- 25 files changed, 302 insertions(+), 260 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3970ec293..23679917c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2011-11-11 Vladimir Serbinenko + + * grub-core/commands/efi/fixvideo.c: Gettextize. + * grub-core/commands/hashsum.c: Likewise. + * grub-core/commands/i386/cmostest.c: Likewise. + * grub-core/commands/i386/pc/drivemap.c: Likewise. + * grub-core/commands/i386/pc/lsapm.c: Likewise. + * grub-core/commands/i386/pc/sendkey.c: Likewise. + * grub-core/commands/lsmmap.c: Likewise. + * grub-core/commands/menuentry.c: Likewise. + * grub-core/commands/mips/loongson/lsspd.c: Likewise. + * grub-core/commands/setpci.c: Likewise. + * grub-core/loader/i386/bsd.c: Likewise. + * grub-core/loader/i386/linux.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-editenv.c: Likewise. + * util/grub-fstest.c: Likewise. + * util/grub-mkfont.c: Likewise. + * util/grub-mkimage.c: Likewise. + * util/grub-mkpasswd-pbkdf2.c: Likewise. + * util/grub-pe2elf.c: Likewise. + * util/grub-probe.c: Likewise. + * util/grub-setup.c: Likewise. + * util/ieee1275/ofpath.c: Likewise. + * util/misc.c: Likewise. + * util/raid.c: Likewise. + 2011-11-11 Robert Millan * util/getroot.c (grub_util_get_geom_abstraction): Remove diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c index c53e47d8a..a58c27916 100644 --- a/grub-core/commands/efi/fixvideo.c +++ b/grub-core/commands/efi/fixvideo.c @@ -56,24 +56,24 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_target_addr_t base; - grub_printf ("Found graphic card: %s\n", p->name); + grub_dprintf ("fixvideo", "Found graphic card: %s\n", p->name); addr += 8 + p->mmio_bar * 4; base = grub_pci_read (addr); if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) || (base & GRUB_PCI_ADDR_MEM_PREFETCH)) - grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar); + grub_dprintf ("fixvideo", "Invalid MMIO bar %d\n", p->mmio_bar); else { base &= GRUB_PCI_ADDR_MEM_MASK; base += p->mmio_reg; if (*((volatile grub_uint32_t *) base) != p->mmio_old) - grub_printf ("Old value don't match\n"); + grub_dprintf ("fixvideo", "Old value doesn't match\n"); else { *((volatile grub_uint32_t *) base) = 0; if (*((volatile grub_uint32_t *) base)) - grub_printf ("Set MMIO fails\n"); + grub_dprintf ("fixvideo", "Setting MMIO fails\n"); } } @@ -82,7 +82,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) p++; } - grub_printf ("Unknown graphic card: %x\n", pciid); + grub_dprintf ("fixvideo", "Unknown graphic card: %x\n", pciid); } return 0; diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index 6825d4811..fb737c2f8 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -141,7 +141,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, grub_file_close (file); if (err) { - grub_printf ("%s: READ ERROR\n", p); + grub_printf_ (N_("%s: READ ERROR\n"), p); if (!keep) { grub_file_close (hashlist); @@ -155,7 +155,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, } if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0) { - grub_printf ("%s: HASH MISMATCH\n", p); + grub_printf_ (N_("%s: HASH MISMATCH\n"), p); if (!keep) { grub_file_close (hashlist); @@ -166,7 +166,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, mismatch++; continue; } - grub_printf ("%s: OK\n", p); + grub_printf_ (N_("%s: OK\n"), p); } if (mismatch || unread) return grub_error (GRUB_ERR_TEST_FAILURE, @@ -257,8 +257,8 @@ static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc; GRUB_MOD_INIT(hashsum) { cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0, - "hashsum -h HASH [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", + N_("-h HASH [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), N_("Compute or check hash checksum."), options); cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0, diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index 6439159bd..6a4290155 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -20,6 +20,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -86,11 +87,11 @@ static grub_command_t cmd, cmd_clean; GRUB_MOD_INIT(cmostest) { cmd = grub_register_command ("cmostest", grub_cmd_cmostest, - "cmostest BYTE:BIT", - "Test bit at BYTE:BIT in CMOS."); + N_("BYTE:BIT"), + N_("Test bit at BYTE:BIT in CMOS.")); cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean, - "cmosclean BYTE:BIT", - "Clean bit at BYTE:BIT in CMOS."); + N_("BYTE:BIT"), + N_("Clean bit at BYTE:BIT in CMOS.")); } GRUB_MOD_FINI(cmostest) diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index 9a89f968c..4f752bed5 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -178,11 +178,11 @@ list_mappings (void) /* Show: list mappings. */ if (! map_head) { - grub_printf ("No drives have been remapped\n"); + grub_puts_ (N_("No drives have been remapped")); return GRUB_ERR_NONE; } - grub_printf ("OS disk #num ------> GRUB/BIOS device\n"); + grub_puts_ (N_("OS disk #num ------> GRUB/BIOS device")); drivemap_node_t *curnode = map_head; while (curnode) { diff --git a/grub-core/commands/i386/pc/lsapm.c b/grub-core/commands/i386/pc/lsapm.c index 17bcfd6eb..45b43b242 100644 --- a/grub-core/commands/i386/pc/lsapm.c +++ b/grub-core/commands/i386/pc/lsapm.c @@ -74,27 +74,27 @@ grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)), if (!grub_apm_get_info (&info)) return grub_error (GRUB_ERR_IO, "no APM found"); - grub_printf ("Vesion %u.%u\n" - "32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n" - "16-bit CS = 0x%x, len = 0x%x\n" - "DS = 0x%x, len = 0x%x\n", - info.version >> 8, info.version & 0xff, - info.cseg, info.cseg_len, info.offset, - info.cseg_16, info.cseg_16_len, - info.dseg, info.dseg_len); + grub_printf_ (N_("Vesion %u.%u\n" + "32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n" + "16-bit CS = 0x%x, len = 0x%x\n" + "DS = 0x%x, len = 0x%x\n"), + info.version >> 8, info.version & 0xff, + info.cseg, info.cseg_len, info.offset, + info.cseg_16, info.cseg_16_len, + info.dseg, info.dseg_len); grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED - ? "16-bit protected interface supported\n" - : "16-bit protected interface unsupported\n"); + ? _("16-bit protected interface supported\n") + : _("16-bit protected interface unsupported\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED - ? "32-bit protected interface supported\n" - : "32-bit protected interface unsupported\n"); + ? _("32-bit protected interface supported\n") + : _("32-bit protected interface unsupported\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN - ? "CPU Idle slows down processor\n" - : "CPU Idle doesn't slow down processor\n"); + ? _("CPU Idle slows down processor\n") + : _("CPU Idle doesn't slow down processor\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED - ? "APM disabled\n" : "APM enabled\n"); + ? _("APM disabled\n") : _("APM enabled\n")); grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED - ? "APM disengaged\n" : "APM engaged\n"); + ? _("APM disengaged\n") : _("APM engaged\n")); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index a55d17bd0..83400c347 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv2+"); @@ -35,23 +36,23 @@ static int keylen = 0; static int noled = 0; static const struct grub_arg_option options[] = { - {"num", 'n', 0, "set numlock mode", "[on|off]", ARG_TYPE_STRING}, - {"caps", 'c', 0, "set capslock mode", "[on|off]", ARG_TYPE_STRING}, - {"scroll", 's', 0, "set scrolllock mode", "[on|off]", ARG_TYPE_STRING}, - {"insert", 0, 0, "set insert mode", "[on|off]", ARG_TYPE_STRING}, - {"pause", 0, 0, "set pause mode", "[on|off]", ARG_TYPE_STRING}, - {"left-shift", 0, 0, "press left shift", "[on|off]", ARG_TYPE_STRING}, - {"right-shift", 0, 0, "press right shift", "[on|off]", ARG_TYPE_STRING}, - {"sysrq", 0, 0, "press SysRq", "[on|off]", ARG_TYPE_STRING}, - {"numkey", 0, 0, "press NumLock key", "[on|off]", ARG_TYPE_STRING}, - {"capskey", 0, 0, "press CapsLock key", "[on|off]", ARG_TYPE_STRING}, - {"scrollkey", 0, 0, "press ScrollLock key", "[on|off]", ARG_TYPE_STRING}, - {"insertkey", 0, 0, "press Insert key", "[on|off]", ARG_TYPE_STRING}, - {"left-alt", 0, 0, "press left alt", "[on|off]", ARG_TYPE_STRING}, - {"right-alt", 0, 0, "press right alt", "[on|off]", ARG_TYPE_STRING}, - {"left-ctrl", 0, 0, "press left ctrl", "[on|off]", ARG_TYPE_STRING}, - {"right-ctrl", 0, 0, "press right ctrl", "[on|off]", ARG_TYPE_STRING}, - {"no-led", 0, 0, "don't update LED state", 0, 0}, + {"num", 'n', 0, N_("set numlock mode"), "[on|off]", ARG_TYPE_STRING}, + {"caps", 'c', 0, N_("set capslock mode"), "[on|off]", ARG_TYPE_STRING}, + {"scroll", 's', 0, N_("set scrolllock mode"), "[on|off]", ARG_TYPE_STRING}, + {"insert", 0, 0, N_("set insert mode"), "[on|off]", ARG_TYPE_STRING}, + {"pause", 0, 0, N_("set pause mode"), "[on|off]", ARG_TYPE_STRING}, + {"left-shift", 0, 0, N_("press left shift"), "[on|off]", ARG_TYPE_STRING}, + {"right-shift", 0, 0, N_("press right shift"), "[on|off]", ARG_TYPE_STRING}, + {"sysrq", 0, 0, N_("press SysRq"), "[on|off]", ARG_TYPE_STRING}, + {"numkey", 0, 0, N_("press NumLock key"), "[on|off]", ARG_TYPE_STRING}, + {"capskey", 0, 0, N_("press CapsLock key"), "[on|off]", ARG_TYPE_STRING}, + {"scrollkey", 0, 0, N_("press ScrollLock key"), "[on|off]", ARG_TYPE_STRING}, + {"insertkey", 0, 0, N_("press Insert key"), "[on|off]", ARG_TYPE_STRING}, + {"left-alt", 0, 0, N_("press left alt"), "[on|off]", ARG_TYPE_STRING}, + {"right-alt", 0, 0, N_("press right alt"), "[on|off]", ARG_TYPE_STRING}, + {"left-ctrl", 0, 0, N_("press left ctrl"), "[on|off]", ARG_TYPE_STRING}, + {"right-ctrl", 0, 0, N_("press right ctrl"), "[on|off]", ARG_TYPE_STRING}, + {"no-led", 0, 0, N_("don't update LED state"), 0, 0}, {0, 0, 0, 0, 0, 0} }; static int simple_flag_offsets[] @@ -369,8 +370,8 @@ static void *preboot_hook; GRUB_MOD_INIT (sendkey) { cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey, 0, - "sendkey [KEYSTROKE1] [KEYSTROKE2] ...", - "Emulate a keystroke", options); + N_("[KEYSTROKE1] [KEYSTROKE2] ..."), + N_("Emulate a keystroke"), options); preboot_hook = grub_loader_register_preboot_hook (grub_sendkey_preboot, diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c index 44598f0df..4815fd174 100644 --- a/grub-core/commands/lsmmap.c +++ b/grub-core/commands/lsmmap.c @@ -26,13 +26,13 @@ GRUB_MOD_LICENSE ("GPLv3+"); static const char *names[] = { - [GRUB_MEMORY_AVAILABLE] = "available", - [GRUB_MEMORY_RESERVED] = "reserved", - [GRUB_MEMORY_ACPI] = "ACPI reclamaible", - [GRUB_MEMORY_NVS] = "NVS", - [GRUB_MEMORY_BADRAM] = "BadRAM", - [GRUB_MEMORY_CODE] = "firmware code", - [GRUB_MEMORY_HOLE] = "hole" + [GRUB_MEMORY_AVAILABLE] = N_("available"), + [GRUB_MEMORY_RESERVED] = N_("reserved"), + [GRUB_MEMORY_ACPI] = N_("ACPI reclamaible"), + [GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage"), + [GRUB_MEMORY_BADRAM] = N_("BadRAM"), + [GRUB_MEMORY_CODE] = N_("firmware code"), + [GRUB_MEMORY_HOLE] = N_("hole") }; static grub_err_t @@ -46,11 +46,11 @@ grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), grub_memory_type_t type) { if (type < ARRAY_SIZE (names) && names[type]) - grub_printf ("base_addr = 0x%llx, length = 0x%llx, %s\n", - (long long) addr, (long long) size, names[type]); + grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"), + (long long) addr, (long long) size, _(names[type])); else - grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n", - (long long) addr, (long long) size, type); + grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"), + (long long) addr, (long long) size, type); return 0; } #ifndef GRUB_MACHINE_EMU diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 4849f8bb8..f5ec60bff 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -28,13 +28,13 @@ static const struct grub_arg_option options[] = { {"class", 1, GRUB_ARG_OPTION_REPEATABLE, - N_("Menu entry type."), "STRING", ARG_TYPE_STRING}, + N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, {"users", 2, 0, - N_("Users allowed to boot this entry."), "USERNAME", ARG_TYPE_STRING}, + N_("Users allowed to boot this entry."), N_("USERNAME"), ARG_TYPE_STRING}, {"hotkey", 3, 0, - N_("Keyboard key for this entry."), "KEY", ARG_TYPE_STRING}, + N_("Keyboard key for this entry."), N_("KEY"), ARG_TYPE_STRING}, {"source", 4, 0, - N_("Menu entry definition as a string."), "STRING", ARG_TYPE_STRING}, + N_("Menu entry definition as a string."), N_("STRING"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; diff --git a/grub-core/commands/mips/loongson/lsspd.c b/grub-core/commands/mips/loongson/lsspd.c index c1c5e2ef7..76999368f 100644 --- a/grub-core/commands/mips/loongson/lsspd.c +++ b/grub-core/commands/mips/loongson/lsspd.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -38,43 +39,44 @@ grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)), if (!grub_cs5536_find (&dev)) { - grub_printf ("No CS5536 found\n"); + grub_puts_ (N_("No CS5536 found")); return GRUB_ERR_NONE; } - grub_printf ("CS5536 at %d:%d.%d\n", grub_pci_get_bus (dev), - grub_pci_get_device (dev), grub_pci_get_function (dev)); + grub_printf_ (N_("CS5536 at %d:%d.%d\n"), grub_pci_get_bus (dev), + grub_pci_get_device (dev), grub_pci_get_function (dev)); err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase); if (err) return err; - grub_printf ("SMB base = 0x%x\n", smbbase); + grub_printf_ (N_("SMB base = 0x%x\n"), smbbase); for (i = GRUB_SMB_RAM_START_ADDR; i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++) { struct grub_smbus_spd spd; grub_memset (&spd, 0, sizeof (spd)); - grub_printf ("Device %d\n", i); + grub_printf_ (N_("Device %d\n"), i); err = grub_cs5536_read_spd (smbbase, i, &spd); if (err) { grub_print_error (); continue; } - grub_printf ("Written SPD bytes: %d B.\n", spd.written_size); - grub_printf ("Total flash size: %d B.\n", 1 << spd.log_total_flash_size); + grub_printf_ (N_("Written SPD bytes: %d B.\n"), spd.written_size); + grub_printf_ (N_("Total flash size: %d B.\n"), + 1 << spd.log_total_flash_size); if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2) { char str[sizeof (spd.ddr2.part_number) + 1]; - grub_printf ("Memory type: DDR2.\n"); + grub_puts_ (N_("Memory type: DDR2.")); grub_memcpy (str, spd.ddr2.part_number, sizeof (spd.ddr2.part_number)); str[sizeof (spd.ddr2.part_number)] = 0; - grub_printf ("Part no: %s.\n", str); + grub_printf_ (N_("Part no: %s.\n"), str); } else - grub_printf ("Memory type: Unknown.\n"); + grub_puts_ (N_("Memory type: Unknown.")); } return GRUB_ERR_NONE; @@ -85,7 +87,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(lsspd) { cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0, - "Print Memory information."); + N_("Print Memory information.")); } GRUB_MOD_FINI(lsspd) diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index 70f5bcdad..81e7f726d 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -66,12 +66,12 @@ static struct pci_register pci_registers[] = static const struct grub_arg_option options[] = { - {0, 'd', 0, "Select device by vendor and device IDs.", - "[vendor]:[device]", ARG_TYPE_STRING}, - {0, 's', 0, "Select device by its position on the bus.", - "[bus]:[slot][.func]", ARG_TYPE_STRING}, - {0, 'v', 0, "Save read value into variable VARNAME.", - "VARNAME", ARG_TYPE_STRING}, + {0, 'd', 0, N_("Select device by vendor and device IDs."), + N_("[vendor]:[device]"), ARG_TYPE_STRING}, + {0, 's', 0, N_("Select device by its position on the bus."), + N_("[bus]:[slot][.func]"), ARG_TYPE_STRING}, + {0, 'v', 0, N_("Save read value into variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -128,7 +128,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (!write_mask) { - grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr, + grub_printf (N_("Register %x of %d:%d.%d is %x\n"), regaddr, grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index f2d0845f8..6746b3853 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -450,7 +450,8 @@ grub_freebsd_list_modules (void) { struct bsd_tag *tag; - grub_printf (" %-18s %-18s%14s%14s\n", "name", "type", "addr", "size"); + grub_printf (" %-18s %-18s%14s%14s\n", _("name"), _("type"), _("addr"), + _("size")); for (tag = tags; tag; tag = tag->next) { @@ -515,7 +516,8 @@ grub_netbsd_list_modules (void) { struct netbsd_module *mod; - grub_printf (" %-18s%14s%14s%14s\n", "name", "type", "addr", "size"); + grub_printf (" %-18s%14s%14s%14s\n", _("name"), _("type"), _("addr"), + _("size")); for (mod = netbsd_mods; mod; mod = mod->next) grub_printf (" %-18s 0x%08x 0x%08x 0x%08x", mod->mod.name, @@ -1050,7 +1052,7 @@ grub_netbsd_boot (void) if (err) { grub_print_error (); - grub_printf ("Booting however\n"); + grub_puts_ (N_("Booting in blind mode")); grub_errno = GRUB_ERR_NONE; } @@ -2061,7 +2063,7 @@ GRUB_MOD_INIT (bsd) cmd_openbsd_ramdisk = grub_register_command ("kopenbsd_ramdisk", grub_cmd_openbsd_ramdisk, 0, - "Load kOpenBSD ramdisk. "); + N_("Load kOpenBSD ramdisk.")); my_mod = mod; } diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index c63c6c3ef..80ad542e3 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -517,7 +517,7 @@ grub_linux_boot (void) if (err) { grub_print_error (); - grub_printf ("Booting however\n"); + grub_puts_ (N_("Booting in blind mode")); grub_errno = GRUB_ERR_NONE; } @@ -793,7 +793,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), vid_mode = GRUB_LINUX_VID_MODE_EXTENDED; else if (grub_strcmp (val, "ask") == 0) { - grub_printf ("Legacy `ask' parameter no longer supported.\n"); + grub_puts_ (N_("Legacy `ask' parameter no longer supported.")); /* We usually would never do this in a loader, but "vga=ask" means user requested interaction, so it can't hurt to request keyboard input. */ @@ -809,9 +809,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), case 0: case GRUB_LINUX_VID_MODE_NORMAL: grub_env_set ("gfxpayload", "text"); - grub_printf ("%s is deprecated. " - "Use set gfxpayload=text before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=text before " + "linux command instead.\n"), argv[i]); break; @@ -819,9 +819,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), case GRUB_LINUX_VID_MODE_EXTENDED: /* FIXME: support 80x50 text. */ grub_env_set ("gfxpayload", "text"); - grub_printf ("%s is deprecated. " - "Use set gfxpayload=text before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=text before " + "linux command instead.\n"), argv[i]); break; default: @@ -830,9 +830,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), vid_mode > GRUB_VESA_MODE_TABLE_END) { grub_env_set ("gfxpayload", "text"); - grub_printf ("%s is deprecated. Mode %d isn't recognized. " - "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. Mode %d isn't recognized. " + "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] " + "before linux command instead.\n"), argv[i], vid_mode); break; } @@ -847,9 +847,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (! buf) goto fail; - grub_printf ("%s is deprecated. " - "Use set gfxpayload=%s before " - "linux command instead.\n", + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), argv[i], buf); err = grub_env_set ("gfxpayload", buf); grub_free (buf); diff --git a/util/getroot.c b/util/getroot.c index 750773c90..f5d6d3f62 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef HAVE_DEVICE_MAPPER # include @@ -454,7 +455,7 @@ grub_find_device (const char *dir, dev_t dev) continue; if (chdir (saved_cwd) < 0) - grub_util_error ("cannot restore the original directory"); + grub_util_error (_("cannot restore the original directory")); free (saved_cwd); closedir (dp); @@ -463,7 +464,7 @@ grub_find_device (const char *dir, dev_t dev) } if (chdir (saved_cwd) < 0) - grub_util_error ("cannot restore the original directory"); + grub_util_error (_("cannot restore the original directory")); free (saved_cwd); closedir (dp); @@ -581,17 +582,17 @@ grub_guess_root_device (const char *dir) &data, &data_len); if (num_ints < 1) - grub_util_error ("Storage info for `%s' does not include type", dir); + grub_util_error (_("Storage info for `%s' does not include type"), dir); if (ints[0] != STORAGE_DEVICE) - grub_util_error ("Filesystem of `%s' is not stored on local disk", dir); + grub_util_error (_("Filesystem of `%s' is not stored on local disk"), dir); if (num_ints < 5) - grub_util_error ("Storage info for `%s' does not include name", dir); + grub_util_error (_("Storage info for `%s' does not include name"), dir); name_len = ints[4]; if (name_len < data_len) - grub_util_error ("Bogus name length for storage info for `%s'", dir); + grub_util_error (_("Bogus name length for storage info for `%s'"), dir); if (data[name_len - 1] != '\0') - grub_util_error ("Storage name for `%s' not NUL-terminated", dir); + grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir); os_dev = xmalloc (strlen ("/dev/") + data_len); memcpy (os_dev, "/dev/", strlen ("/dev/")); @@ -653,7 +654,7 @@ grub_guess_root_device (const char *dir) } if (stat (dir, &st) < 0) - grub_util_error ("cannot stat `%s'", dir); + grub_util_error (_("cannot stat `%s'"), dir); dev = st.st_dev; @@ -692,7 +693,7 @@ grub_util_open_dm (const char *os_dev, struct dm_tree **tree, *tree = dm_tree_create (); if (! *tree) { - grub_printf ("Failed to create tree\n"); + grub_puts_ (N_("Failed to create tree")); grub_dprintf ("hostdisk", "dm_tree_create failed\n"); return 0; } @@ -808,7 +809,7 @@ grub_util_get_geom_abstraction (const char *dev) error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) { @@ -874,13 +875,14 @@ get_mdadm_uuid (const char *os_dev) if (pipe (mdadm_pipe) < 0) { - grub_util_warn ("Unable to create pipe for mdadm: %s", strerror (errno)); + grub_util_warn (_("Unable to create pipe for mdadm: %s"), + strerror (errno)); return NULL; } mdadm_pid = fork (); if (mdadm_pid < 0) - grub_util_warn ("Unable to fork mdadm: %s", strerror (errno)); + grub_util_warn (_("Unable to fork mdadm: %s"), strerror (errno)); else if (mdadm_pid == 0) { /* Child. */ @@ -911,7 +913,7 @@ get_mdadm_uuid (const char *os_dev) mdadm = fdopen (mdadm_pipe[0], "r"); if (! mdadm) { - grub_util_warn ("Unable to open stream from mdadm: %s", + grub_util_warn (_("Unable to open stream from mdadm: %s"), strerror (errno)); goto out; } @@ -971,7 +973,7 @@ grub_util_pull_device (const char *os_dev) error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) { @@ -989,7 +991,7 @@ grub_util_pull_device (const char *os_dev) LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) break; if (!consumer) - grub_util_error ("couldn't find geli consumer"); + grub_util_error (_("couldn't find geli consumer")); fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); grub_util_info ("consumer %s", consumer->lg_provider->lg_name); lastsubdev = consumer->lg_provider->lg_name; @@ -1009,7 +1011,7 @@ grub_util_pull_device (const char *os_dev) grub_err_t err; err = grub_cryptodisk_cheat_mount (grdev, os_dev); if (err) - grub_util_error ("Can't mount crypto: %s", grub_errmsg); + grub_util_error (_("Can't mount crypto: %s"), _(grub_errmsg)); } grub_free (grdev); @@ -1053,7 +1055,7 @@ grub_util_pull_device (const char *os_dev) grub_err_t err; err = grub_cryptodisk_cheat_mount (grdev, os_dev); if (err) - grub_util_error ("Can't mount crypto: %s", grub_errmsg); + grub_util_error (_("Can't mount crypto: %s"), _(grub_errmsg)); } grub_free (grdev); } @@ -1141,7 +1143,7 @@ grub_util_get_grub_dev (const char *os_dev) error = geom_gettree (&mesh); if (error != 0) - grub_util_error ("couldn't open geom"); + grub_util_error (_("couldn't open geom")); LIST_FOREACH (class, &mesh.lg_class, lg_class) { @@ -1159,11 +1161,11 @@ grub_util_get_grub_dev (const char *os_dev) LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) break; if (!consumer) - grub_util_error ("couldn't find geli consumer"); + grub_util_error (_("couldn't find geli consumer")); fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); uuid = grub_util_get_geli_uuid (fname); if (!uuid) - grub_util_error ("couldn't retrieve geli UUID"); + grub_util_error (_("couldn't retrieve geli UUID")); grub_dev = xasprintf ("cryptouuid/%s", uuid); free (fname); free (uuid); @@ -1248,7 +1250,7 @@ grub_util_get_grub_dev (const char *os_dev) free (p); } else - grub_util_error ("unknown kind of RAID device `%s'", os_dev); + grub_util_error (_("unknown kind of RAID device `%s'"), os_dev); { char *mdadm_name = get_mdadm_uuid (os_dev); @@ -1290,7 +1292,7 @@ grub_util_check_block_device (const char *blk_dev) struct stat st; if (stat (blk_dev, &st) < 0) - grub_util_error ("cannot stat `%s'", blk_dev); + grub_util_error (_("cannot stat `%s'"), blk_dev); if (S_ISBLK (st.st_mode)) return (blk_dev); @@ -1304,7 +1306,7 @@ grub_util_check_char_device (const char *blk_dev) struct stat st; if (stat (blk_dev, &st) < 0) - grub_util_error ("cannot stat `%s'", blk_dev); + grub_util_error (_("cannot stat `%s'"), blk_dev); if (S_ISCHR (st.st_mode)) return (blk_dev); @@ -1320,7 +1322,7 @@ get_win32_path (const char *path) { char winpath[PATH_MAX]; if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) - grub_util_error ("cygwin_conv_path() failed"); + grub_util_error (_("cygwin_conv_path() failed")); int len = strlen (winpath); int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); @@ -1438,7 +1440,7 @@ grub_make_system_path_relative_to_its_root (const char *path) /* canonicalize. */ p = canonicalize_file_name (path); if (p == NULL) - grub_util_error ("failed to get canonical path of %s", path); + grub_util_error (_("failed to get canonical path of %s"), path); #if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ @@ -1453,7 +1455,7 @@ grub_make_system_path_relative_to_its_root (const char *path) free (p); if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + grub_util_error (_("cannot stat %s: %s"), buf, strerror (errno)); buf2 = xstrdup (buf); num = st.st_dev; @@ -1465,14 +1467,14 @@ grub_make_system_path_relative_to_its_root (const char *path) p = strrchr (buf, '/'); if (p == NULL) /* This should never happen. */ - grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)"); + grub_util_error (_("FIXME: no / in buf. (make_system_path_relative_to_its_root)")); if (p != buf) *p = 0; else *++p = 0; if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + grub_util_error (_("cannot stat %s: %s"), buf, strerror (errno)); /* buf is another filesystem; we found it. */ if (st.st_dev != num) diff --git a/util/grub-editenv.c b/util/grub-editenv.c index 519945411..2bff80612 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -115,26 +115,26 @@ create_envblk_file (const char *name) buf = malloc (DEFAULT_ENVBLK_SIZE); if (! buf) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); namenew = xasprintf ("%s.new", name); fp = fopen (namenew, "wb"); if (! fp) - grub_util_error ("cannot open the file %s", namenew); + grub_util_error (_("cannot open the file %s"), namenew); memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE) - grub_util_error ("cannot write to the file %s", namenew); + grub_util_error (_("cannot write to the file %s"), namenew); fsync (fileno (fp)); free (buf); fclose (fp); if (rename (namenew, name) < 0) - grub_util_error ("cannot rename the file %s to %s", namenew, name); + grub_util_error (_("cannot rename the file %s to %s"), namenew, name); free (namenew); } @@ -153,29 +153,29 @@ open_envblk_file (const char *name) create_envblk_file (name); fp = fopen (name, "rb"); if (! fp) - grub_util_error ("cannot open the file %s", name); + grub_util_error (_("cannot open the file %s"), name); } if (fseek (fp, 0, SEEK_END) < 0) - grub_util_error ("cannot seek the file %s", name); + grub_util_error (_("cannot seek the file %s"), name); size = (size_t) ftell (fp); if (fseek (fp, 0, SEEK_SET) < 0) - grub_util_error ("cannot seek the file %s", name); + grub_util_error (_("cannot seek the file %s"), name); buf = malloc (size); if (! buf) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); if (fread (buf, 1, size, fp) != size) - grub_util_error ("cannot read the file %s", name); + grub_util_error (_("cannot read the file %s"), name); fclose (fp); envblk = grub_envblk_open (buf, size); if (! envblk) - grub_util_error ("invalid environment block"); + grub_util_error (_("invalid environment block")); return envblk; } @@ -204,11 +204,11 @@ write_envblk (const char *name, grub_envblk_t envblk) fp = fopen (name, "wb"); if (! fp) - grub_util_error ("cannot open the file %s", name); + grub_util_error (_("cannot open the file %s"), name); if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp) != grub_envblk_size (envblk)) - grub_util_error ("cannot write to the file %s", name); + grub_util_error (_("cannot write to the file %s"), name); fsync (fileno (fp)); fclose (fp); @@ -226,12 +226,12 @@ set_variables (const char *name, int argc, char *argv[]) p = strchr (argv[0], '='); if (! p) - grub_util_error ("invalid parameter %s", argv[0]); + grub_util_error (_("invalid parameter %s"), argv[0]); *(p++) = 0; if (! grub_envblk_set (envblk, argv[0], p)) - grub_util_error ("environment block too small"); + grub_util_error (_("environment block too small")); argc--; argv++; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 47b536771..c9f24ff08 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -395,11 +395,11 @@ fstest (int n, char **args) if (!fs) grub_util_error (grub_errmsg); if (!fs->uuid) - grub_util_error ("couldn't retrieve UUID"); + grub_util_error (_("couldn't retrieve UUID")); if (fs->uuid (dev, &uuid)) grub_util_error (grub_errmsg); if (!uuid) - grub_util_error ("couldn't retrieve UUID"); + grub_util_error (_("couldn't retrieve UUID")); argv[1] = uuid; execute_command ("xnu_uuid", 2, argv); grub_free (uuid); @@ -470,7 +470,7 @@ argp_parser (int key, char *arg, struct argp_state *state) if (strcmp (arg, "prompt") == 0) { char buf[1024]; - grub_printf ("Enter ZFS password: "); + grub_puts_ (N_("Enter ZFS password: ")); if (grub_password_get (buf, 1023)) { grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); @@ -484,13 +484,13 @@ argp_parser (int key, char *arg, struct argp_state *state) f = fopen (arg, "rb"); if (!f) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); return 0; } real_size = fread (buf, 1, 1024, f); if (real_size < 0) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); fclose (f); return 0; } diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 3108d4694..1fad15660 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -121,9 +121,10 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS] FONT_FILES\n\ \nOptions:\n\ -o, --output=FILE_NAME set output file name\n\ @@ -143,7 +144,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -188,12 +189,12 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, err = FT_Load_Glyph (face, glyph_idx, flag); if (err) { - printf ("Freetype Error %d loading glyph 0x%x for U+0x%x%s", + printf (_("Freetype Error %d loading glyph 0x%x for U+0x%x%s"), err, glyph_idx, char_code & GRUB_FONT_CODE_CHAR_MASK, char_code & GRUB_FONT_CODE_RIGHT_JOINED - ? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (medial)": - " (leftmost)") - : ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? " (rightmost)": + ? ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? _(" (medial)"): + _(" (leftmost)")) + : ((char_code & GRUB_FONT_CODE_LEFT_JOINED) ? _(" (rightmost)"): "")); if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) @@ -519,7 +520,7 @@ process_cursive (struct gsub_feature *feature, if (substtype == GSUB_SUBSTITUTION_DELTA) add_subst (glyph, glyph + grub_be_to_cpu16 (sub->delta), target); else if (i >= grub_be_to_cpu16 (sub->count)) - printf ("Out of range substitution (%d, %d)\n", i, + printf (_("Out of range substitution (%d, %d)\n"), i, grub_be_to_cpu16 (sub->count)); else add_subst (glyph, grub_be_to_cpu16 (sub->repl[i++]), target); @@ -531,7 +532,7 @@ process_cursive (struct gsub_feature *feature, struct gsub_lookup *lookup; if (lookup_index >= grub_be_to_cpu16 (lookups->count)) { - printf ("Out of range lookup: %d\n", lookup_index); + printf (_("Out of range lookup: %d\n"), lookup_index); continue; } lookup = (struct gsub_lookup *) @@ -539,13 +540,13 @@ process_cursive (struct gsub_feature *feature, + grub_be_to_cpu16 (lookups->offsets[lookup_index])); if (grub_be_to_cpu16 (lookup->type) != GSUB_SINGLE_SUBSTITUTION) { - printf ("Unsupported substitution type: %d\n", + printf (_("Unsupported substitution type: %d\n"), grub_be_to_cpu16 (lookup->type)); continue; } if (grub_be_to_cpu16 (lookup->flag) & ~GSUB_RTL_CHAR) { - printf ("Unsupported substitution flag: 0x%x\n", + printf (_("Unsupported substitution flag: 0x%x\n"), grub_be_to_cpu16 (lookup->flag)); } switch (feattag) @@ -575,7 +576,7 @@ process_cursive (struct gsub_feature *feature, if (substtype != GSUB_SUBSTITUTION_MAP && substtype != GSUB_SUBSTITUTION_DELTA) { - printf ("Unsupported substitution specification: %d\n", + printf (_("Unsupported substitution specification: %d\n"), substtype); continue; } @@ -601,7 +602,7 @@ process_cursive (struct gsub_feature *feature, subst (m); } else - printf ("Unsupported coverage specification: %d\n", covertype); + printf (_("Unsupported coverage specification: %d\n"), covertype); } } } @@ -640,7 +641,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) grub_uint32_t feattag = grub_be_to_cpu32 (features->features[i].feature_tag); if (feature->params) - printf ("WARNING: unsupported feature parameters: %x\n", + printf (_("WARNING: unsupported feature parameters: %x\n"), grub_be_to_cpu16 (feature->params)); switch (feattag) { @@ -670,7 +671,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) for (j = 0; j < 4; j++) if (!grub_isgraph (str[j])) str[j] = '?'; - printf ("Unknown gsub feature 0x%x (%s)\n", feattag, str); + printf (_("Unknown gsub feature 0x%x (%s)\n"), feattag, str); } } } @@ -739,8 +740,8 @@ print_glyphs (struct grub_font_info *font_info) int x, y, xmax, xmin, ymax, ymin; grub_uint8_t *bitmap, mask; - printf ("\nGlyph #%d, U+%04x\n", num, glyph->char_code); - printf ("Width %d, Height %d, X offset %d, Y offset %d, Device width %d\n", + printf (_("\nGlyph #%d, U+%04x\n"), num, glyph->char_code); + printf (_("Width %d, Height %d, X offset %d, Y offset %d, Device width %d\n"), glyph->width, glyph->height, glyph->x_ofs, glyph->y_ofs, glyph->device_width); @@ -807,7 +808,7 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) file = fopen (output_file, "wb"); if (! file) - grub_util_error ("Can\'t write to file %s.", output_file); + grub_util_error (_("Can\'t write to file %s."), output_file); int correct_size; for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs; @@ -843,7 +844,7 @@ write_font_width_spec (struct grub_font_info *font_info, char *output_file) file = fopen (output_file, "wb"); if (! file) - grub_util_error ("Can\'t write to file %s.", output_file); + grub_util_error (_("Can\'t write to file %s."), output_file); for (glyph = font_info->glyphs_sorted; glyph < font_info->glyphs_sorted + font_info->num_glyphs; glyph++) @@ -866,7 +867,7 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) file = fopen (output_file, "wb"); if (! file) - grub_util_error ("can\'t write to file %s.", output_file); + grub_util_error (_("Can\'t write to file %s."), output_file); offset = 0; @@ -1063,7 +1064,7 @@ main (int argc, char *argv[]) a = strtoul (p, &p, 0); if (*p != '-') - grub_util_error ("invalid font range"); + grub_util_error (_("invalid font range")); b = strtoul (p + 1, &p, 0); if ((font_info.num_range & (GRUB_FONT_RANGE_BLOCK - 1)) == 0) font_info.ranges = xrealloc (font_info.ranges, @@ -1078,7 +1079,7 @@ main (int argc, char *argv[]) if (*p) { if (*p != ',') - grub_util_error ("invalid font range"); + grub_util_error (_("invalid font range")); else p++; } @@ -1124,7 +1125,7 @@ main (int argc, char *argv[]) if (file_format == ASCII_BITMAPS && font_info.num_range > 0) { - grub_util_error ("Option --ascii-bitmaps doesn't accept ranges (use ASCII)."); + grub_util_error (_("Option --ascii-bitmaps doesn't accept ranges (use ASCII).")); return 1; } @@ -1140,10 +1141,10 @@ main (int argc, char *argv[]) } if (! output_file) - grub_util_error ("no output file is specified"); + grub_util_error (_("no output file is specified")); if (FT_Init_FreeType (&ft_lib)) - grub_util_error ("FT_Init_FreeType fails"); + grub_util_error (_("FT_Init_FreeType fails")); for (; optind < argc; optind++) { @@ -1154,8 +1155,8 @@ main (int argc, char *argv[]) err = FT_New_Face (ft_lib, argv[optind], font_index, &ft_face); if (err) { - grub_printf ("can't open file %s, index %d: error %d", argv[optind], - font_index, err); + grub_printf (_("can't open file %s, index %d: error %d"), + argv[optind], font_index, err); if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) printf (": %s\n", ft_errmsgs[err]); else @@ -1181,7 +1182,7 @@ main (int argc, char *argv[]) font_info.size = size; if (FT_Set_Pixel_Sizes (ft_face, size, size)) - grub_util_error ("can't set %dx%d font size", 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); } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index fb1c5babe..9369fba3d 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -703,7 +703,7 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS && (comp != COMPRESSION_NONE)) - grub_util_error ("unknown compression %d\n", comp); + grub_util_error (_("unknown compression %d\n"), comp); *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); @@ -945,7 +945,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], name = "none_decompress.img"; break; default: - grub_util_error ("unknown compression %d\n", comp); + grub_util_error (_("unknown compression %d\n"), comp); } decompress_path = grub_util_get_path (dir, name); @@ -1301,7 +1301,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], boot_path = grub_util_get_path (dir, "diskboot.img"); boot_size = grub_util_get_image_size (boot_path); if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); + grub_util_error (_("diskboot.img is not one sector size")); boot_img = grub_util_read_image (boot_path); @@ -1366,11 +1366,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], GRUB_MD_SHA512->final (context); if (grub_memcmp (GRUB_MD_SHA512->read (context), fwstart_good_hash, GRUB_MD_SHA512->mdlen) != 0) - grub_util_warn ("fwstart.img doesn't match the known good version. " - "Proceed at your own risk"); + grub_util_warn (_("fwstart.img doesn't match the known good version. " + "proceed at your own risk")); if (core_size + boot_size > 512 * 1024) - grub_util_error ("firmware image is too big"); + grub_util_error (_("firmware image is too big")); rom_size = 512 * 1024; rom_img = xmalloc (rom_size); @@ -1394,7 +1394,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t rom_size; if (core_size > 512 * 1024) - grub_util_error ("firmware image is too big"); + grub_util_error (_("firmware image is too big")); rom_size = 512 * 1024; rom_img = xmalloc (rom_size); @@ -1762,7 +1762,7 @@ main (int argc, char *argv[]) image_target = &image_targets[i]; if (!image_target) { - printf ("unknown target format %s\n", optarg); + printf (_("unknown target format %s\n"), optarg); usage (1); } break; @@ -1803,14 +1803,14 @@ main (int argc, char *argv[]) #ifdef HAVE_LIBLZMA comp = COMPRESSION_XZ; #else - grub_util_error ("grub-mkimage is compiled without XZ support", + grub_util_error (_("grub-mkimage is compiled without XZ support"), optarg); #endif } else if (grub_strcmp (optarg, "none") == 0) comp = COMPRESSION_NONE; else - grub_util_error ("Unknown compression format %s", optarg); + grub_util_error (_("Unknown compression format %s"), optarg); break; case 'h': @@ -1840,7 +1840,7 @@ main (int argc, char *argv[]) if (!image_target) { - printf ("Target format not specified (use the -O option).\n"); + printf (_("Target format not specified (use the -O option).\n")); usage (1); } diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index f75f27611..9c676a100 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -46,16 +46,17 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTIONS]\n\ \nOptions:\n\ -c number, --iteration-count=number Number of PBKDF2 iterations\n\ -l number, --buflen=number Length of generated hash\n\ -s number, --salt=number Length of salt\n\ \n\ -Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); +Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); exit (status); } @@ -135,12 +136,12 @@ main (int argc, char *argv[]) bufhex = malloc (buflen * 2 + 1); if (!bufhex) - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); buf = malloc (buflen); if (!buf) { free (bufhex); - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); } salt = malloc (saltlen); @@ -148,7 +149,7 @@ main (int argc, char *argv[]) { free (bufhex); free (buf); - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); } salthex = malloc (saltlen * 2 + 1); if (!salthex) @@ -156,26 +157,26 @@ main (int argc, char *argv[]) free (salt); free (bufhex); free (buf); - grub_util_error ("out of memory"); + grub_util_error (_("out of memory")); } - printf ("Enter password: "); + printf ("%s", _("Enter password: ")); if (!grub_password_get (pass1, GRUB_AUTH_MAX_PASSLEN)) { free (buf); free (bufhex); free (salthex); free (salt); - grub_util_error ("failure to read password"); + grub_util_error (_("failure to read password")); } - printf ("\nReenter password: "); + printf ("\n%s", _("Reenter password: ")); if (!grub_password_get (pass2, GRUB_AUTH_MAX_PASSLEN)) { free (buf); free (bufhex); free (salthex); free (salt); - grub_util_error ("failure to read password"); + grub_util_error (_("failure to read password")); } if (strcmp (pass1, pass2) != 0) @@ -186,12 +187,12 @@ main (int argc, char *argv[]) free (bufhex); free (salthex); free (salt); - grub_util_error ("passwords don't match"); + grub_util_error (_("passwords don't match")); } memset (pass2, 0, sizeof (pass2)); #if ! defined (__linux__) && ! defined (__FreeBSD__) - printf ("WARNING: your random generator isn't known to be secure\n"); + printf ("%s", _("WARNING: your random generator isn't known to be secure\n")); #endif { @@ -206,7 +207,7 @@ main (int argc, char *argv[]) free (salthex); free (salt); fclose (f); - grub_util_error ("couldn't retrieve random data for salt"); + grub_util_error (_("couldn't retrieve random data for salt")); } rd = fread (salt, 1, saltlen, f); if (rd != saltlen) @@ -217,7 +218,7 @@ main (int argc, char *argv[]) free (bufhex); free (salthex); free (salt); - grub_util_error ("couldn't retrieve random data for salt"); + grub_util_error (_("couldn't retrieve random data for salt")); } fclose (f); } @@ -238,13 +239,13 @@ main (int argc, char *argv[]) memset (salthex, 0, 2 * saltlen); free (salt); free (salthex); - grub_util_error ("cryptographic error number %d", gcry_err); + grub_util_error (_("cryptographic error number %d"), gcry_err); } hexify (bufhex, buf, buflen); hexify (salthex, salt, saltlen); - printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", + printf (_("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n"), count, salthex, bufhex); memset (buf, 0, buflen); memset (bufhex, 0, 2 * buflen); diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index 4b93faa05..51d41c9f0 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -31,6 +31,8 @@ #include "progname.h" +/* Please don't internationalise this file. It's pointless. */ + static struct option options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, diff --git a/util/grub-probe.c b/util/grub-probe.c index 54b9d03c6..795a9344e 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -173,10 +173,10 @@ probe (const char *path, char *device_name) { #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__sun__) if (! grub_util_check_char_device (device_name)) - grub_util_error ("%s is not a character device", device_name); + grub_util_error (_("%s is not a character device"), device_name); #else if (! grub_util_check_block_device (device_name)) - grub_util_error ("%s is not a block device", device_name); + grub_util_error (_("%s is not a block device"), device_name); #endif } else @@ -186,7 +186,7 @@ probe (const char *path, char *device_name) } if (! device_name) - grub_util_error ("cannot find a device for %s (is /dev mounted?)", path); + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path); if (print == PRINT_DEVICE) { @@ -196,7 +196,8 @@ probe (const char *path, char *device_name) drive_name = grub_util_get_grub_dev (device_name); if (! drive_name) - grub_util_error ("cannot find a GRUB drive for %s. Check your device.map", device_name); + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + device_name); if (print == PRINT_DRIVE) { @@ -207,7 +208,7 @@ probe (const char *path, char *device_name) grub_util_info ("opening %s", drive_name); dev = grub_device_open (drive_name); if (! dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); if (print == PRINT_ABSTRACTION) { @@ -233,7 +234,7 @@ probe (const char *path, char *device_name) fs = grub_fs_probe (dev); if (! fs) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); if (print == PRINT_FS) { @@ -243,7 +244,7 @@ probe (const char *path, char *device_name) { char *uuid; if (! fs->uuid) - grub_util_error ("%s does not support UUIDs", fs->name); + grub_util_error (_("%s does not support UUIDs"), fs->name); if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); @@ -254,10 +255,10 @@ probe (const char *path, char *device_name) { char *label; if (! fs->label) - grub_util_error ("%s does not support labels", fs->name); + grub_util_error (_("%s does not support labels"), fs->name); if (fs->label (dev, &label) != GRUB_ERR_NONE) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); printf ("%s\n", label); } @@ -287,9 +288,9 @@ usage (int status) { if (status) fprintf (stderr, - "Try `%s --help' for more information.\n", program_name); + _("Try `%s --help' for more information.\n"), program_name); else - printf ("\ + printf (_("\ Usage: %s [OPTION]... [PATH|DEVICE]\n\ \n\ Probe device information for a given path (or device, if the -d option is given).\n\ @@ -303,7 +304,7 @@ Probe device information for a given path (or device, if the -d option is given) -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -", program_name, +"), program_name, DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); exit (status); @@ -385,13 +386,13 @@ main (int argc, char *argv[]) /* Obtain ARGUMENT. */ if (optind >= argc) { - fprintf (stderr, "No path or device is specified.\n"); + fprintf (stderr, _("No path or device is specified.\n")); usage (1); } if (optind + 1 != argc) { - fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]); usage (1); } diff --git a/util/grub-setup.c b/util/grub-setup.c index d3f6fe8b8..f185ed747 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -125,8 +125,8 @@ write_rootdev (char *core_img, grub_device_t root_dev, if (root_dev->disk->partition->parent) { if (root_dev->disk->partition->parent->parent) - grub_util_error ("Installing on doubly nested partitions is " - "not supported"); + grub_util_error (_("Installing on doubly nested partitions " + "is not supported")); dos_part = root_dev->disk->partition->parent->number; bsd_part = root_dev->disk->partition->number; } @@ -283,22 +283,22 @@ setup (const char *dir, grub_util_info ("Opening root"); root_dev = grub_device_open (root); if (! root_dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); grub_util_info ("Opening dest"); dest_dev = grub_device_open (dest); if (! dest_dev) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); #ifdef GRUB_MACHINE_PCBIOS /* Read the original sector from the disk. */ tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE); if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); #endif #ifdef GRUB_MACHINE_PCBIOS @@ -421,14 +421,14 @@ setup (const char *dir, if (dest_partmap && !dest_partmap->embed) { - grub_util_warn ("Partition style '%s' doesn't support embeding", + grub_util_warn (_("Partition style '%s' doesn't support embeding"), dest_partmap->name); goto unable_to_embed; } if (fs && !fs->embed) { - grub_util_warn ("File system '%s' doesn't support embeding", + grub_util_warn (_("File system '%s' doesn't support embeding"), fs->name); goto unable_to_embed; } @@ -443,13 +443,13 @@ setup (const char *dir, if (!err && nsec < core_sectors) { err = grub_error (GRUB_ERR_OUT_OF_RANGE, - "Your embedding area is unusually small. " - "core.img won't fit in it."); + N_("Your embedding area is unusually small. " + "core.img won't fit in it.")); } if (err) { - grub_util_warn ("%s", grub_errmsg); + grub_util_warn ("%s", _(grub_errmsg)); grub_errno = GRUB_ERR_NONE; goto unable_to_embed; } @@ -466,7 +466,7 @@ setup (const char *dir, block--; if ((char *) block <= core_img) - grub_util_error ("No terminator in the core image"); + grub_util_error (_("No terminator in the core image")); } save_first_sector (sectors[0] + grub_partition_get_start (container), @@ -626,7 +626,7 @@ unable_to_embed: grub_file_filter_disable_compression (); file = grub_file_open (core_path_dev); if (! file) - grub_util_error ("%s", grub_errmsg); + grub_util_error ("%s", _(grub_errmsg)); file->read_hook = save_first_sector; if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) @@ -687,8 +687,7 @@ unable_to_embed: /* Write the boot image onto the disk. */ if (grub_disk_write (dest_dev->disk, BOOT_SECTOR, 0, GRUB_DISK_SECTOR_SIZE, boot_img)) - grub_util_error ("%s", grub_errmsg); - + grub_util_error ("%s", _(grub_errmsg)); grub_util_biosdisk_flush (root_dev->disk); grub_util_biosdisk_flush (dest_dev->disk); diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index f72bea8a5..20a571191 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -23,6 +23,7 @@ #include #include #include +#include #endif #include @@ -53,6 +54,7 @@ grub_util_error (const char *fmt, ...) exit (1); } +#define _(x) x #endif static void @@ -106,7 +108,7 @@ find_obppath(char *of_path, const char *sysfs_path_orig) { kill_trailing_dir(sysfs_path); if (!strcmp(sysfs_path, "/sys")) - grub_util_error("'obppath' not found in parent dirs of %s", + grub_util_error(_("'obppath' not found in parent dirs of %s"), sysfs_path_orig); continue; } @@ -131,12 +133,12 @@ block_device_get_sysfs_path_and_link(const char *devicenode, snprintf(sysfs_path, sysfs_path_len, "/sys/block/%s", devicenode); if (!realpath (sysfs_path, rpath)) - grub_util_error ("cannot get the real path of `%s'", sysfs_path); + grub_util_error (_("cannot get the real path of `%s'"), sysfs_path); strcat(rpath, "/device"); if (!realpath (rpath, sysfs_path)) - grub_util_error ("cannot get the real path of `%s'", rpath); + grub_util_error (_("cannot get the real path of `%s'"), rpath); free (rpath); } @@ -247,12 +249,12 @@ vendor_is_ATA(const char *path) snprintf(buf, PATH_MAX, "%s/vendor", path); fd = open(buf, O_RDONLY); if (fd < 0) - grub_util_error ("cannot open 'vendor' node of `%s'", path); + grub_util_error (_("cannot open 'vendor' node of `%s'"), path); memset(buf, 0, PATH_MAX); err = read(fd, buf, PATH_MAX); if (err < 0) - grub_util_error ("cannot read 'vendor' node of `%s'", path); + grub_util_error (_("cannot read 'vendor' node of `%s'"), path); close(fd); @@ -288,7 +290,7 @@ check_sas (char *sysfs_path, int *tgt) fd = open(path, O_RDONLY); if (fd < 0) - grub_util_error("cannot open SAS PHY ID `%s'\n", path); + grub_util_error(_("cannot open SAS PHY ID `%s'\n"), path); memset (phy, 0, sizeof (phy)); read (fd, phy, sizeof (phy)); @@ -376,7 +378,7 @@ grub_util_devname_to_ofpath (const char *devname) name_buf = xmalloc (PATH_MAX); name_buf = realpath (devname, name_buf); if (! name_buf) - grub_util_error ("cannot get the real path of `%s'", devname); + grub_util_error (_("cannot get the real path of `%s'"), devname); device = get_basename (name_buf); devnode = strip_trailing_digits (name_buf); @@ -398,7 +400,7 @@ grub_util_devname_to_ofpath (const char *devname) New models have no floppy at all. */ strcpy (ofpath, "floppy"); else - grub_util_error ("unknown device type %s\n", device); + grub_util_error (_("unknown device type %s\n"), device); free (devnode); free (devicenode); @@ -414,7 +416,7 @@ int main(int argc, char **argv) if (argc != 2) { - printf("Usage: grub-ofpathname DEVICE\n"); + printf(_("Usage: %s DEVICE\n"), argv[0]); return 1; } diff --git a/util/misc.c b/util/misc.c index 72bedde0c..6ebaf30bc 100644 --- a/util/misc.c +++ b/util/misc.c @@ -89,10 +89,10 @@ grub_util_get_fp_size (FILE *fp) struct stat st; if (fflush (fp) == EOF) - grub_util_error ("fflush failed"); + grub_util_error (_("fflush failed")); if (fstat (fileno (fp), &st) == -1) - grub_util_error ("fstat failed"); + grub_util_error (_("fstat failed")); return st.st_size; } @@ -105,7 +105,7 @@ grub_util_get_image_size (const char *path) grub_util_info ("getting the size of %s", path); if (stat (path, &st) == -1) - grub_util_error ("cannot stat %s", path); + grub_util_error (_("cannot stat %s"), path); return st.st_size; } @@ -114,10 +114,10 @@ void grub_util_read_at (void *img, size_t size, off_t offset, FILE *fp) { if (fseeko (fp, offset, SEEK_SET) == -1) - grub_util_error ("seek failed"); + grub_util_error (_("seek failed")); if (fread (img, 1, size, fp) != size) - grub_util_error ("read failed"); + grub_util_error (_("read failed")); } char * @@ -134,7 +134,7 @@ grub_util_read_image (const char *path) fp = fopen (path, "rb"); if (! fp) - grub_util_error ("cannot open %s", path); + grub_util_error (_("cannot open %s"), path); grub_util_read_at (img, size, 0, fp); @@ -155,10 +155,10 @@ grub_util_load_image (const char *path, char *buf) fp = fopen (path, "rb"); if (! fp) - grub_util_error ("cannot open %s", path); + grub_util_error (_("cannot open %s"), path); if (fread (buf, 1, size, fp) != size) - grub_util_error ("cannot read %s", path); + grub_util_error (_("cannot read %s"), path); fclose (fp); } @@ -168,9 +168,9 @@ grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out) { grub_util_info ("writing 0x%x bytes at offset 0x%x", size, offset); if (fseeko (out, offset, SEEK_SET) == -1) - grub_util_error ("seek failed"); + grub_util_error (_("seek failed")); if (fwrite (img, 1, size, out) != size) - grub_util_error ("write failed"); + grub_util_error (_("write failed")); } void @@ -178,7 +178,7 @@ grub_util_write_image (const char *img, size_t size, FILE *out) { grub_util_info ("writing 0x%x bytes", size); if (fwrite (img, 1, size, out) != size) - grub_util_error ("write failed"); + grub_util_error (_("write failed")); } char * diff --git a/util/raid.c b/util/raid.c index 1e312491b..8de5fbac0 100644 --- a/util/raid.c +++ b/util/raid.c @@ -33,6 +33,7 @@ #include #include #include +#include char ** grub_util_raid_getmembers (const char *name, int bootable) @@ -46,26 +47,26 @@ grub_util_raid_getmembers (const char *name, int bootable) fd = open (name, O_RDONLY); if (fd == -1) - grub_util_error ("can't open %s: %s", name, strerror (errno)); + grub_util_error (_("can't open %s: %s"), name, strerror (errno)); ret = ioctl (fd, RAID_VERSION, &version); if (ret != 0) - grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno)); + grub_util_error (_("ioctl RAID_VERSION error: %s"), strerror (errno)); if ((version.major != 0 || version.minor != 90) && (version.major != 1 || version.minor != 0) && (version.major != 1 || version.minor != 1) && (version.major != 1 || version.minor != 2)) - grub_util_error ("unsupported RAID version: %d.%d", + grub_util_error (_("unsupported RAID version: %d.%d"), version.major, version.minor); if (bootable && (version.major != 0 || version.minor != 90)) - grub_util_error ("unsupported RAID version: %d.%d", + grub_util_error (_("unsupported RAID version: %d.%d"), version.major, version.minor); ret = ioctl (fd, GET_ARRAY_INFO, &info); if (ret != 0) - grub_util_error ("ioctl GET_ARRAY_INFO error: %s", strerror (errno)); + grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno)); devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *)); @@ -74,7 +75,7 @@ grub_util_raid_getmembers (const char *name, int bootable) disk.number = i; ret = ioctl (fd, GET_DISK_INFO, &disk); if (ret != 0) - grub_util_error ("ioctl GET_DISK_INFO error: %s", strerror (errno)); + grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); if (disk.state & (1 << MD_DISK_ACTIVE)) { From f1f233ba430c27cbc6a327751bd3da53798cdf2f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 00:56:20 +0100 Subject: [PATCH 1394/1414] Add crypto support to grub-mount --- Makefile.util.def | 1 + util/grub-mount.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/Makefile.util.def b/Makefile.util.def index 567747fc7..5f655b73d 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -246,6 +246,7 @@ program = { common = grub-core/disk/host.c; ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse'; diff --git a/util/grub-mount.c b/util/grub-mount.c index 434772eec..7c75acd15 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ static char *debug_str = NULL; static char **fuse_args = NULL; static int fuse_argc = 0; static int num_disks = 0; +static int mount_crypt = 0; static grub_err_t execute_command (char *name, int n, char **args) @@ -333,6 +335,13 @@ fuse_init (void) grub_free (host_file); } + if (mount_crypt) + { + char *argv[2] = { "-a", NULL}; + if (execute_command ("cryptomount", 1, argv)) + grub_util_error (_("cryptomount command fails: %s"), grub_errmsg); + } + grub_lvm_fini (); grub_mdraid09_fini (); grub_mdraid1x_fini (); @@ -378,6 +387,8 @@ fuse_init (void) static struct argp_option options[] = { {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"debug", 'd', "S", 0, N_("Set debug environment variable."), 2}, + {"crypto", 'C', NULL, OPTION_ARG_OPTIONAL, N_("Mount crypto devices."), 2}, + {"zfs-key", 'K', N_("FILE|prompt"), 0, N_("Load zfs crypto key."), 2}, {"verbose", 'v', NULL, OPTION_ARG_OPTIONAL, N_("Print verbose messages."), 2}, {0, 0, 0, 0, 0, 0} }; @@ -401,6 +412,42 @@ argp_parser (int key, char *arg, struct argp_state *state) root = arg; return 0; + case 'K': + if (strcmp (arg, "prompt") == 0) + { + char buf[1024]; + grub_printf ("Enter ZFS password: "); + if (grub_password_get (buf, 1023)) + { + grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); + } + } + else + { + FILE *f; + ssize_t real_size; + grub_uint8_t buf[1024]; + f = fopen (arg, "rb"); + if (!f) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + return 0; + } + real_size = fread (buf, 1, 1024, f); + if (real_size < 0) + { + printf ("Error loading file %s: %s\n", arg, strerror (errno)); + fclose (f); + return 0; + } + grub_zfs_add_key (buf, real_size, 0); + } + return 0; + + case 'C': + mount_crypt = 1; + return 0; + case 'd': debug_str = arg; return 0; From d8e62bbeb95c357ac597db5ce28df20f7a9d9823 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 01:19:06 +0100 Subject: [PATCH 1395/1414] gettextize --- util/grub-mount.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index 7c75acd15..f084fbf98 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -416,7 +416,7 @@ argp_parser (int key, char *arg, struct argp_state *state) if (strcmp (arg, "prompt") == 0) { char buf[1024]; - grub_printf ("Enter ZFS password: "); + grub_printf ("%s", _("Enter ZFS password: ")); if (grub_password_get (buf, 1023)) { grub_zfs_add_key ((grub_uint8_t *) buf, grub_strlen (buf), 1); @@ -430,13 +430,13 @@ argp_parser (int key, char *arg, struct argp_state *state) f = fopen (arg, "rb"); if (!f) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); return 0; } real_size = fread (buf, 1, 1024, f); if (real_size < 0) { - printf ("Error loading file %s: %s\n", arg, strerror (errno)); + printf (_("Error loading file %s: %s\n"), arg, strerror (errno)); fclose (f); return 0; } @@ -507,7 +507,7 @@ main (int argc, char *argv[]) argp_parse (&argp, argc, argv, 0, 0, 0); if (num_disks < 2) - grub_util_error ("need an image and mountpoint"); + grub_util_error (_("need an image and mountpoint")); fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); fuse_args[fuse_argc] = images[num_disks - 1]; fuse_argc++; From ae60d685fad88cb461b6479ee28115c1d5251293 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 01:20:23 +0100 Subject: [PATCH 1396/1414] fill attr on readdir --- util/grub-mount.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/util/grub-mount.c b/util/grub-mount.c index f084fbf98..a4be21738 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -281,7 +281,26 @@ fuse_readdir (const char *path, void *buf, const struct grub_dirhook_info *info); int call_fill (const char *filename, const struct grub_dirhook_info *info) { - fill (buf, filename, NULL, 0); + struct stat st; + grub_memset (&st, 0, sizeof (st)); + st.st_mode = info->dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); + if (!info->dir) + { + grub_file_t file; + char *tmp; + tmp = xasprintf ("%s/%s", path, filename); + file = grub_file_open (tmp); + free (tmp); + if (! file) + return translate_error (); + st.st_size = file->size; + grub_file_close (file); + } + st.st_blksize = 512; + st.st_blocks = (st.st_size + 511) >> 9; + st.st_atime = st.st_mtime = st.st_ctime + = info->mtimeset ? info->mtime : 0; + fill (buf, filename, &st, 0); return 0; } From 2b23074a0c082219fe4490fa05b13a481b34b41e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 16:29:04 +0100 Subject: [PATCH 1397/1414] Move assembly code to C by using intwrap. It increases core size by 88 bytes but improves compatibility and maintainability. * grub-core/kern/i386/pc/startup.S (grub_console_putchar): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_putchar_real): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_getkey): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_getxy): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_getxy): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_gotoxy): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_gotoxy): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_cls): Moved to ... * grub-core/term/i386/pc/console.c (grub_console_cls): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Moved to .. * grub-core/term/i386/pc/console.c (grub_console_setcursor): ... here. Translated to C. * grub-core/kern/i386/pc/startup.S (grub_get_rtc): Moved to .. * grub-core/kern/i386/pc/init.c (grub_get_rtc): ... here. Translated to C. * grub-core/term/i386/pc/console.c (int10_9): New function. (grub_console_putchar): Likewise. * include/grub/i386/pc/console.h: Removed the not anymore shared functions. --- ChangeLog | 31 +++ grub-core/kern/i386/pc/init.c | 16 ++ grub-core/kern/i386/pc/startup.S | 365 ------------------------------- grub-core/term/i386/pc/console.c | 219 +++++++++++++++++++ include/grub/i386/pc/console.h | 10 - 5 files changed, 266 insertions(+), 375 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7743aa2d4..3d8bd25e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2011-11-12 Vladimir Serbinenko + + Move assembly code to C by using intwrap. It increases core size + by 88 bytes but improves compatibility and maintainability. + + * grub-core/kern/i386/pc/startup.S (grub_console_putchar): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_putchar_real): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_getkey): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_getxy): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_getxy): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_gotoxy): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_gotoxy): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_cls): Moved to ... + * grub-core/term/i386/pc/console.c (grub_console_cls): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Moved to .. + * grub-core/term/i386/pc/console.c (grub_console_setcursor): + ... here. Translated to C. + * grub-core/kern/i386/pc/startup.S (grub_get_rtc): Moved to .. + * grub-core/kern/i386/pc/init.c (grub_get_rtc): ... here. + Translated to C. + * grub-core/term/i386/pc/console.c (int10_9): New function. + (grub_console_putchar): Likewise. + * include/grub/i386/pc/console.h: Removed the not anymore shared + functions. + 2011-11-12 Vladimir Serbinenko Move grub_chainloader_real_boot out of the kernel. diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index be26fdea1..6fbfab3b8 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -47,6 +47,22 @@ static int num_regions; void (*grub_pc_net_config) (char **device, char **path); +/* + * return the real time in ticks, of which there are about + * 18-20 per second + */ +grub_uint32_t +grub_get_rtc (void) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x1a, ®s); + + return (regs.ecx << 16) | (regs.edx & 0xffff); +} + void grub_machine_get_bootlocation (char **device, char **path) { diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index df8992278..94d4f02ee 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -464,371 +464,6 @@ FUNCTION(grub_exit) ljmp $0xf000, $0xfff0 .code32 -/* - * void grub_console_putchar (int c) - * - * Put the character C on the console. Because GRUB wants to write a - * character with an attribute, this implementation is a bit tricky. - * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh - * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, - * save the current position, restore the original position, write the - * character and the attribute, and restore the current position. - * - * The reason why this is so complicated is that there is no easy way to - * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't - * support setting a background attribute. - */ -FUNCTION(grub_console_putchar) - /* Retrieve the base character. */ - movl 0(%edx), %edx - pusha - movb EXT_C(grub_console_cur_color), %bl - - call prot_to_real - .code16 - movb %dl, %al - xorb %bh, %bh - - /* use teletype output if control character */ - cmpb $0x7, %al - je 1f - cmpb $0x8, %al - je 1f - cmpb $0xa, %al - je 1f - cmpb $0xd, %al - je 1f - - /* save the character and the attribute on the stack */ - pushw %ax - pushw %bx - - /* get the current position */ - movb $0x3, %ah - int $0x10 - - /* check the column with the width */ - cmpb $79, %dl - jl 2f - - /* print CR and LF, if next write will exceed the width */ - movw $0x0e0d, %ax - int $0x10 - movb $0x0a, %al - int $0x10 - - /* get the current position */ - movb $0x3, %ah - int $0x10 - -2: - /* restore the character and the attribute */ - popw %bx - popw %ax - - /* write the character with the attribute */ - movb $0x9, %ah - movw $1, %cx - int $0x10 - - /* move the cursor forward */ - incb %dl - movb $0x2, %ah - int $0x10 - - jmp 3f - -1: movw $1, %bx - movb $0xe, %ah - int $0x10 - -3: DATA32 call real_to_prot - .code32 - - popa - ret - - -LOCAL(bypass_table): - .word 0x011b, 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r' - .word 0x1c00 | '\n' -LOCAL(bypass_table_end): - -/* - * int grub_console_getkey (void) - * if there is a character pending, return it; otherwise return -1 - * BIOS call "INT 16H Function 01H" to check whether a character is pending - * Call with %ah = 0x1 - * Return: - * If key waiting to be input: - * %ah = keyboard scan code - * %al = ASCII character - * Zero flag = clear - * else - * Zero flag = set - * BIOS call "INT 16H Function 00H" to read character from keyboard - * Call with %ah = 0x0 - * Return: %ah = keyboard scan code - * %al = ASCII character - */ - -FUNCTION(grub_console_getkey) - pushl %ebp - pushl %edi - - call prot_to_real - .code16 - - /* - * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would - * cause the machine to hang at the second keystroke. However, we can - * work around this problem by ensuring the presence of keystroke with - * INT 16/AH = 1 before calling INT 16/AH = 0. - */ - - movb $1, %ah - int $0x16 - jz notpending - - movb $0, %ah - int $0x16 - - xorl %edx, %edx - movw %ax, %dx /* real_to_prot uses %eax */ - - DATA32 call real_to_prot - .code32 - - movl $0xff, %eax - testl %eax, %edx - jz 1f - - andl %edx, %eax - cmpl $0x20, %eax - jae 2f - movl %edx, %eax - leal LOCAL(bypass_table), %edi - movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) >> 1), %ecx - repne scasw - jz 3f - - andl $0xff, %eax - addl $(('a' - 1) | GRUB_TERM_CTRL), %eax - jmp 2f -3: - andl $0xff, %eax - jmp 2f - -1: movl %edx, %eax - shrl $8, %eax - orl $GRUB_TERM_EXTENDED, %eax -2: - popl %edi - popl %ebp - ret - -notpending: - .code16 - DATA32 call real_to_prot - .code32 -#if GRUB_TERM_NO_KEY != 0 -#error Fix this asm code -#endif - jmp 2b - - -/* - * grub_uint16_t grub_console_getxy (void) - * BIOS call "INT 10H Function 03h" to get cursor position - * Call with %ah = 0x03 - * %bh = page - * Returns %ch = starting scan line - * %cl = ending scan line - * %dh = row (0 is top) - * %dl = column (0 is left) - */ - - -FUNCTION(grub_console_getxy) - pushl %ebp - pushl %ebx /* save EBX */ - - call prot_to_real - .code16 - - xorb %bh, %bh /* set page to 0 */ - movb $0x3, %ah - int $0x10 /* get cursor position */ - - DATA32 call real_to_prot - .code32 - - movb %dl, %ah - movb %dh, %al - - popl %ebx - popl %ebp - ret - - -/* - * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y) - * BIOS call "INT 10H Function 02h" to set cursor position - * Call with %ah = 0x02 - * %bh = page - * %dh = row (0 is top) - * %dl = column (0 is left) - */ - - -FUNCTION(grub_console_gotoxy) - pushl %ebp - pushl %ebx /* save EBX */ - - movb %cl, %dh /* %dh = y */ - /* %dl = x */ - - call prot_to_real - .code16 - - xorb %bh, %bh /* set page to 0 */ - movb $0x2, %ah - int $0x10 /* set cursor position */ - - DATA32 call real_to_prot - .code32 - - popl %ebx - popl %ebp - ret - - -/* - * void grub_console_cls (void) - * BIOS call "INT 10H Function 09h" to write character and attribute - * Call with %ah = 0x09 - * %al = (character) - * %bh = (page number) - * %bl = (attribute) - * %cx = (number of times) - */ - -FUNCTION(grub_console_cls) - pushl %ebp - pushl %ebx /* save EBX */ - - call prot_to_real - .code16 - - /* move the cursor to the beginning */ - movb $0x02, %ah - xorb %bh, %bh - xorw %dx, %dx - int $0x10 - - /* write spaces to the entire screen */ - movw $0x0920, %ax - movw $0x07, %bx - movw $(80 * 25), %cx - int $0x10 - - /* move back the cursor */ - movb $0x02, %ah - int $0x10 - - DATA32 call real_to_prot - .code32 - - popl %ebx - popl %ebp - ret - - -/* - * void grub_console_setcursor (int on) - * BIOS call "INT 10H Function 01h" to set cursor type - * Call with %ah = 0x01 - * %ch = cursor starting scanline - * %cl = cursor ending scanline - */ - -console_cursor_state: - .byte 1 -console_cursor_shape: - .word 0 - -FUNCTION(grub_console_setcursor) - pushl %ebp - pushl %ebx - - /* push ON */ - pushl %edx - - /* check if the standard cursor shape has already been saved */ - movw console_cursor_shape, %ax - testw %ax, %ax - jne 1f - - call prot_to_real - .code16 - - movb $0x03, %ah - xorb %bh, %bh - int $0x10 - - DATA32 call real_to_prot - .code32 - - cmp %cl, %ch - jb 3f - movw $0x0d0e, %cx -3: - movw %cx, console_cursor_shape -1: - /* set %cx to the designated cursor shape */ - movw $0x2000, %cx - popl %eax - testl %eax, %eax - jz 2f - movw console_cursor_shape, %cx -2: - call prot_to_real - .code16 - - movb $0x1, %ah - int $0x10 - - DATA32 call real_to_prot - .code32 - - popl %ebx - popl %ebp - ret - -/* - * grub_get_rtc() - * return the real time in ticks, of which there are about - * 18-20 per second - */ -FUNCTION(grub_get_rtc) - pushl %ebp - - call prot_to_real /* enter real mode */ - .code16 - - /* %ax is already zero */ - int $0x1a - - DATA32 call real_to_prot - .code32 - - movl %ecx, %eax - shll $16, %eax - movw %dx, %ax - - popl %ebp - ret - /* * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry); */ diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c index 0efeafe4e..7cf5ffc5f 100644 --- a/grub-core/term/i386/pc/console.c +++ b/grub-core/term/i386/pc/console.c @@ -20,6 +20,225 @@ #include #include #include +#include + +static void +int10_9 (grub_uint8_t ch, grub_uint16_t n) +{ + struct grub_bios_int_registers regs; + + regs.eax = ch | 0x0900; + regs.ebx = grub_console_cur_color & 0xff; + regs.ecx = n; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); +} + +/* + * BIOS call "INT 10H Function 03h" to get cursor position + * Call with %ah = 0x03 + * %bh = page + * Returns %ch = starting scan line + * %cl = ending scan line + * %dh = row (0 is top) + * %dl = column (0 is left) + */ + + +static grub_uint16_t +grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x0300; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + + return ((regs.edx & 0xff) << 8) | ((regs.edx & 0xff00) >> 8); +} + +/* + * BIOS call "INT 10H Function 02h" to set cursor position + * Call with %ah = 0x02 + * %bh = page + * %dh = row (0 is top) + * %dl = column (0 is left) + */ +static void +grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + grub_uint8_t x, grub_uint8_t y) +{ + struct grub_bios_int_registers regs; + + /* set page to 0 */ + regs.ebx = 0; + regs.eax = 0x0200; + regs.edx = (y << 8) | x; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); +} + +/* + * + * Put the character C on the console. Because GRUB wants to write a + * character with an attribute, this implementation is a bit tricky. + * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh + * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, + * save the current position, restore the original position, write the + * character and the attribute, and restore the current position. + * + * The reason why this is so complicated is that there is no easy way to + * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't + * support setting a background attribute. + */ +static void +grub_console_putchar_real (grub_uint8_t c) +{ + struct grub_bios_int_registers regs; + grub_uint16_t pos; + + if (c == 7 || c == 8 || c == 0xa || c == 0xd) + { + regs.eax = c | 0x0e00; + regs.ebx = 0x0001; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + return; + } + + /* get the current position */ + pos = grub_console_getxy (NULL); + + /* check the column with the width */ + if ((pos & 0xff00) >= (79 << 8)) + { + grub_console_putchar_real (0x0d); + grub_console_putchar_real (0x0a); + /* get the current position */ + pos = grub_console_getxy (NULL); + } + + /* write the character with the attribute */ + int10_9 (c, 1); + + grub_console_gotoxy (NULL, ((pos & 0xff00) >> 8) + 1, (pos & 0xff)); +} + +static void +grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), + const struct grub_unicode_glyph *c) +{ + grub_console_putchar_real (c->base); +} + +/* + * BIOS call "INT 10H Function 09h" to write character and attribute + * Call with %ah = 0x09 + * %al = (character) + * %bh = (page number) + * %bl = (attribute) + * %cx = (number of times) + */ +static void +grub_console_cls (struct grub_term_output *term) +{ + /* move the cursor to the beginning */ + grub_console_gotoxy (term, 0, 0); + + /* write spaces to the entire screen */ + int10_9 (' ', 80 * 25); + + /* move back the cursor */ + grub_console_gotoxy (term, 0, 0); +} + +/* + * void grub_console_setcursor (int on) + * BIOS call "INT 10H Function 01h" to set cursor type + * Call with %ah = 0x01 + * %ch = cursor starting scanline + * %cl = cursor ending scanline + */ +static void +grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) +{ + static grub_uint16_t console_cursor_shape = 0; + struct grub_bios_int_registers regs; + + /* check if the standard cursor shape has already been saved */ + if (!console_cursor_shape) + { + regs.eax = 0x0300; + regs.ebx = 0; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + console_cursor_shape = regs.ecx; + if ((console_cursor_shape >> 8) >= (console_cursor_shape & 0xff)) + console_cursor_shape = 0x0d0e; + } + /* set %cx to the designated cursor shape */ + regs.ecx = on ? console_cursor_shape : 0x2000; + regs.eax = 0x0100; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); +} + +/* + * if there is a character pending, return it; otherwise return -1 + * BIOS call "INT 16H Function 01H" to check whether a character is pending + * Call with %ah = 0x1 + * Return: + * If key waiting to be input: + * %ah = keyboard scan code + * %al = ASCII character + * Zero flag = clear + * else + * Zero flag = set + * BIOS call "INT 16H Function 00H" to read character from keyboard + * Call with %ah = 0x0 + * Return: %ah = keyboard scan code + * %al = ASCII character + */ + +static int +grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) +{ + const grub_uint16_t bypass_table[] = { + 0x0100 | '\e', 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r', 0x1c00 | '\n' + }; + struct grub_bios_int_registers regs; + unsigned i; + + /* + * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would + * cause the machine to hang at the second keystroke. However, we can + * work around this problem by ensuring the presence of keystroke with + * INT 16/AH = 1 before calling INT 16/AH = 0. + */ + + regs.eax = 0x0100; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x16, ®s); + if (regs.flags & GRUB_CPU_INT_FLAGS_ZERO) + return GRUB_TERM_NO_KEY; + + regs.eax = 0x0000; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x16, ®s); + if (!(regs.eax & 0xff)) + return ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED; + + if ((regs.eax & 0xff) >= ' ') + return regs.eax & 0xff; + + for (i = 0; i < ARRAY_SIZE (bypass_table); i++) + if (bypass_table[i] == (regs.eax & 0xffff)) + return regs.eax & 0xff; + + return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); +} static const struct grub_machine_bios_data_area *bios_data_area = (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index 1631a40ad..f752b9a25 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -26,16 +26,6 @@ #include #include -/* These are global to share code between C and asm. */ -int grub_console_getkey (struct grub_term_input *term); -grub_uint16_t grub_console_getxy (struct grub_term_output *term); -void grub_console_gotoxy (struct grub_term_output *term, - grub_uint8_t x, grub_uint8_t y); -void grub_console_cls (struct grub_term_output *term); -void grub_console_setcursor (struct grub_term_output *term, int on); -void grub_console_putchar (struct grub_term_output *term, - const struct grub_unicode_glyph *c); - /* Initialize the console system. */ void grub_console_init (void); From e9d3421c050df3f3b77b5f9bceb758d663fb229d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 19:18:42 +0100 Subject: [PATCH 1398/1414] * configure.ac: Add -fno-asynchronous-unwind-tables. --- ChangeLog | 4 ++++ configure.ac | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3d8bd25e7..409a41ca5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * configure.ac: Add -fno-asynchronous-unwind-tables. + 2011-11-12 Vladimir Serbinenko Move assembly code to C by using intwrap. It increases core size diff --git a/configure.ac b/configure.ac index 3d6cc9a9e..7699e8330 100644 --- a/configure.ac +++ b/configure.ac @@ -413,6 +413,23 @@ if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" fi +# By default, GCC 4.6 generates .eh_frame sections containing unwind +# information in some cases where it previously did not. GRUB doesn't need +# these and they just use up vital space. Restore the old compiler +# behaviour. +AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [ + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_asynchronous_unwind_tables=yes], + [grub_cv_cc_fno_asynchronous_unwind_tables=no]) + CFLAGS="$SAVE_CFLAGS" +]) + +if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" +fi + grub_apple_target_cc if test x$grub_cv_apple_target_cc = xyes ; then TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1" From 60240b8bc1a501951944c9e07d094c9e5e5e7084 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 19:53:25 +0100 Subject: [PATCH 1399/1414] Use decompressors framework on i386-pc. It increases core size by 46 bytes but improves compatibility and maintainability. * grub-core/Makefile.core.def (lzma_decompress): New image. (kernel): Add i386_pc_ldflags. * grub-core/kern/i386/pc/startup.S: Move intial part to .. * grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers to real_to_prot, prot_to_real and device info. * include/grub/offsets.h: Renamed decompressor offsets. * util/grub-mkimage.c (grub_compression_t): New cmpression lzma. (image_target_desc): Remove raw_size and rename decompressor fields. (compress_kernel): Handle lzma. (generate_image): Handle decompressors on i386-pc. --- ChangeLog | 16 + grub-core/Makefile.core.def | 11 +- grub-core/boot/i386/pc/lnxboot.S | 8 +- .../{kern => boot}/i386/pc/lzma_decode.S | 0 grub-core/boot/i386/pc/startup_raw.S | 369 +++++++++++++++++ grub-core/boot/mips/startup_raw.S | 6 +- grub-core/kern/i386/int.S | 4 +- grub-core/kern/i386/pc/init.c | 3 +- grub-core/kern/i386/pc/startup.S | 392 ++---------------- grub-core/kern/i386/realmode.S | 27 ++ include/grub/offsets.h | 16 +- util/grub-mkimage.c | 235 ++++++----- 12 files changed, 601 insertions(+), 486 deletions(-) rename grub-core/{kern => boot}/i386/pc/lzma_decode.S (100%) create mode 100644 grub-core/boot/i386/pc/startup_raw.S diff --git a/ChangeLog b/ChangeLog index 409a41ca5..eeb9bda57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2011-11-12 Vladimir Serbinenko + + Use decompressors framework on i386-pc. It increases core size + by 46 bytes but improves compatibility and maintainability. + + * grub-core/Makefile.core.def (lzma_decompress): New image. + (kernel): Add i386_pc_ldflags. + * grub-core/kern/i386/pc/startup.S: Move intial part to .. + * grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers + to real_to_prot, prot_to_real and device info. + * include/grub/offsets.h: Renamed decompressor offsets. + * util/grub-mkimage.c (grub_compression_t): New cmpression lzma. + (image_target_desc): Remove raw_size and rename decompressor fields. + (compress_kernel): Handle lzma. + (generate_image): Handle decompressors on i386-pc. + 2011-11-12 Vladimir Serbinenko * configure.ac: Add -fno-asynchronous-unwind-tables. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 9590188fb..18264f98f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -34,7 +34,7 @@ kernel = { 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'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; @@ -356,6 +356,15 @@ image = { enable = mips; }; +image = { + name = lzma_decompress; + i386_pc = boot/i386/pc/startup_raw.S; + + objcopyflags = '-O binary'; + ldflags = '-Wl,-Ttext,0x8200'; + enable = i386_pc; +}; + image = { name = fwstart; mips_loongson = boot/mips/loongson/fwstart.S; diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index bb43ed73c..e5227d174 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -199,12 +199,8 @@ real_code_2: 1: - movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx -#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200 - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx -#else - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx -#endif + movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx + addl $((0x9000 - 0x8200) - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx 2: call LOCAL(move_memory) diff --git a/grub-core/kern/i386/pc/lzma_decode.S b/grub-core/boot/i386/pc/lzma_decode.S similarity index 100% rename from grub-core/kern/i386/pc/lzma_decode.S rename to grub-core/boot/i386/pc/lzma_decode.S diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S new file mode 100644 index 000000000..4820e3442 --- /dev/null +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -0,0 +1,369 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,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 + * 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 ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) + + .file "startup_raw.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + + .globl start, _start +start: +_start: +LOCAL (base): + /* + * Guarantee that "main" is loaded at 0x0:0x8200. + */ +#ifdef __APPLE__ + ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000) +#else + ljmp $0, $ABS(LOCAL (codestart)) +#endif + + /* + * This is a special data area. + */ + + . = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE +LOCAL(compressed_size): + .long 0 + . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE +LOCAL(uncompressed_size): + .long 0 + + . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART +LOCAL(dos_part): + .long 0xFFFFFFFF + . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART +LOCAL(bsd_part): + .long 0xFFFFFFFF + + . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY +reed_solomon_redundancy: + .long 0 + +/* + * This is the area for all of the special variables. + */ + +LOCAL(boot_drive): + .byte 0 + +/* the real mode code continues... */ +LOCAL (codestart): + cli /* we're not safe here! */ + + /* set up %ds, %ss, and %es */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw %ax, %es + + /* set up the real mode/BIOS stack */ + movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp + movl %ebp, %esp + + sti /* we're safe again */ + + /* save the boot drive */ + ADDR32 movb %dl, LOCAL(boot_drive) + + /* reset disk system (%ah = 0) */ + int $0x13 + + /* transition to protected mode */ + DATA32 call real_to_prot + + /* The ".code32" directive takes GAS out of 16-bit mode. */ + .code32 + + incl %eax + call grub_gate_a20 + + movl LOCAL(compressed_size), %edx + addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx + movl reed_solomon_redundancy, %ecx + leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax + call EXT_C (grub_reed_solomon_recover) + jmp post_reed_solomon + +#include + + .text + + . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART +/* + * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). + * This uses the a.out kludge to load raw binary to the area starting at 1MB, + * and relocates itself after loaded. + */ + .p2align 2 /* force 4-byte alignment */ +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long (1 << 16) + /* checksum */ + .long -0x1BADB002 - (1 << 16) + /* header addr */ + .long multiboot_header - _start + 0x100000 + 0x200 + /* load addr */ + .long 0x100000 + /* load end addr */ + .long 0 + /* bss end addr */ + .long 0 + /* entry addr */ + .long multiboot_entry - _start + 0x100000 + 0x200 + +multiboot_entry: + .code32 + /* obtain the boot device */ + movl 12(%ebx), %edx + + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp + movl %ebp, %esp + + /* relocate the code */ + movl $(LOCAL(decompressor_end) + 0x200), %ecx + addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx + movl $0x100000, %esi + movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi + cld + rep + movsb + /* jump to the real address */ + movl $multiboot_trampoline, %eax + jmp *%eax + +multiboot_trampoline: + /* fill the boot information */ + movl %edx, %eax + shrl $8, %eax + xorl %ebx, %ebx + cmpb $0xFF, %ah + je 1f + movb %ah, %bl + movl %ebx, LOCAL(dos_part) +1: + cmpb $0xFF, %al + je 2f + movb %al, %bl + movl %ebx, LOCAL(bsd_part) +2: + shrl $24, %edx + movb %dl, LOCAL(boot_drive) + movb $0xFF, %dh + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp + /* enter the usual booting */ + call prot_to_real + .code16 + jmp LOCAL (codestart) + + .code32 + +post_reed_solomon: + +#ifdef ENABLE_LZMA + movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi + movl $LOCAL(decompressor_end), %esi + pushl %edi + movl LOCAL (uncompressed_size), %ecx + leal (%edi, %ecx), %ebx + call _LzmaDecodeA + /* _LzmaDecodeA clears DF, so no need to run cld */ + popl %esi +#endif + + movb LOCAL(boot_drive), %dl + movl LOCAL(dos_part), %eax + movl LOCAL(bsd_part), %ebx + movl $prot_to_real, %edi + movl $real_to_prot, %ecx + jmp *%esi + +#include "../../../kern/i386/realmode.S" + +/* + * grub_gate_a20(int on) + * + * Gate address-line 20 for high memory. + * + * This routine is probably overconservative in what it does, but so what? + * + * It also eats any keystrokes in the keyboard buffer. :-( + */ + +grub_gate_a20: + movl %eax, %edx + +gate_a20_test_current_state: + /* first of all, test if already in a good state */ + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_bios + ret + +gate_a20_try_bios: + /* second, try a BIOS call */ + pushl %ebp + call prot_to_real + + .code16 + movw $0x2400, %ax + testb %dl, %dl + jz 1f + incw %ax +1: int $0x15 + + DATA32 call real_to_prot + .code32 + + popl %ebp + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_system_control_port_a + ret + +gate_a20_try_system_control_port_a: + /* + * In macbook, the keyboard test would hang the machine, so we move + * this forward. + */ + /* fourth, try the system control port A */ + inb $0x92 + andb $(~0x03), %al + testb %dl, %dl + jz 6f + orb $0x02, %al +6: outb $0x92 + + /* When turning off Gate A20, do not check the state strictly, + because a failure is not fatal usually, and Gate A20 is always + on some modern machines. */ + testb %dl, %dl + jz 7f + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_keyboard_controller +7: ret + +gate_a20_flush_keyboard_buffer: + inb $0x64 + andb $0x02, %al + jnz gate_a20_flush_keyboard_buffer +2: + inb $0x64 + andb $0x01, %al + jz 3f + inb $0x60 + jmp 2b +3: + ret + +gate_a20_try_keyboard_controller: + /* third, try the keyboard controller */ + call gate_a20_flush_keyboard_buffer + + movb $0xd1, %al + outb $0x64 +4: + inb $0x64 + andb $0x02, %al + jnz 4b + + movb $0xdd, %al + testb %dl, %dl + jz 5f + orb $0x02, %al +5: outb $0x60 + call gate_a20_flush_keyboard_buffer + + /* output a dummy command (USB keyboard hack) */ + movb $0xff, %al + outb $0x64 + call gate_a20_flush_keyboard_buffer + + call gate_a20_check_state + cmpb %al, %dl + /* everything failed, so restart from the beginning */ + jnz gate_a20_try_bios + ret + +gate_a20_check_state: + /* iterate the checking for a while */ + movl $100, %ecx +1: + call 3f + cmpb %al, %dl + jz 2f + loop 1b +2: + ret +3: + pushl %ebx + pushl %ecx + xorl %eax, %eax + /* compare the byte at 0x8000 with that at 0x108000 */ + movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx + pushl %ebx + /* save the original byte in CL */ + movb (%ebx), %cl + /* store the value at 0x108000 in AL */ + addl $0x100000, %ebx + movb (%ebx), %al + /* try to set one less value at 0x8000 */ + popl %ebx + movb %al, %ch + decb %ch + movb %ch, (%ebx) + /* serialize */ + outb %al, $0x80 + outb %al, $0x80 + /* obtain the value at 0x108000 in CH */ + pushl %ebx + addl $0x100000, %ebx + movb (%ebx), %ch + /* this result is 1 if A20 is on or 0 if it is off */ + subb %ch, %al + xorb $1, %al + /* restore the original */ + popl %ebx + movb %cl, (%ebx) + popl %ecx + popl %ebx + ret + +#ifdef ENABLE_LZMA +#include "lzma_decode.S" +#endif + + .p2align 2 + +LOCAL(decompressor_end): diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index aefd387b6..e76926677 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -38,13 +38,13 @@ start: bal codestart nop base: - . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE + . = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE compressed_size: .long 0 - . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE + . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE uncompressed_size: .long 0 - . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR + . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR uncompressed_addr: .long 0 codestart: diff --git a/grub-core/kern/i386/int.S b/grub-core/kern/i386/int.S index 58ccfdaab..7a2b7808a 100644 --- a/grub-core/kern/i386/int.S +++ b/grub-core/kern/i386/int.S @@ -47,7 +47,7 @@ FUNCTION(grub_bios_interrupt) movl 24(%edx), %esi movl 28(%edx), %edx - call prot_to_real + PROT_TO_REAL .code16 pushf cli @@ -98,7 +98,7 @@ intno: movw %ax, LOCAL(bios_register_es) popf - DATA32 call real_to_prot + REAL_TO_PROT .code32 popl %eax diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 6fbfab3b8..da7230c33 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -156,8 +156,7 @@ grub_machine_init (void) int grub_lower_mem; #endif - grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR - + ((_edata - _start) - GRUB_KERNEL_MACHINE_RAW_SIZE); + grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); /* Initialize the console as early as possible. */ grub_console_init (); diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 94d4f02ee..058f9efa7 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2005,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 @@ -43,203 +43,30 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include - -#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) .file "startup.S" .text - /* Tell GAS to generate 16-bit instructions so that this code works - in real mode. */ - .code16 - .globl start, _start start: _start: -LOCAL (base): - /* - * Guarantee that "main" is loaded at 0x0:0x8200. - */ -#ifdef __APPLE__ - ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000) -#else - ljmp $0, $ABS(LOCAL (codestart)) -#endif - - /* - * This is a special data area. - */ - - . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE -VARIABLE(grub_total_module_size) - .long 0 - . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE -VARIABLE(grub_compressed_size) - .long 0 - . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART -VARIABLE(grub_install_dos_part) - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART -VARIABLE(grub_install_bsd_part) - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY -reed_solomon_redundancy: - .long 0 - -#ifdef APPLE_CC -bss_start: - .long 0 -bss_end: - .long 0 -#endif -/* - * This is the area for all of the special variables. - */ - -VARIABLE(grub_boot_drive) - .byte 0 - -/* the real mode code continues... */ -LOCAL (codestart): - cli /* we're not safe here! */ - - /* set up %ds, %ss, and %es */ - xorw %ax, %ax - movw %ax, %ds - movw %ax, %ss - movw %ax, %es - - /* set up the real mode/BIOS stack */ - movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp - movl %ebp, %esp - - sti /* we're safe again */ - - /* save the boot drive */ - ADDR32 movb %dl, EXT_C(grub_boot_drive) - - /* reset disk system (%ah = 0) */ - int $0x13 - - /* transition to protected mode */ - DATA32 call real_to_prot - - /* The ".code32" directive takes GAS out of 16-bit mode. */ .code32 - incl %eax - call grub_gate_a20 - - movl EXT_C(grub_compressed_size), %edx - addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx - movl reed_solomon_redundancy, %ecx - leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax - call EXT_C (grub_reed_solomon_recover) - jmp post_reed_solomon - -#include - - .text - - . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART -/* - * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). - * This uses the a.out kludge to load raw binary to the area starting at 1MB, - * and relocates itself after loaded. - */ - .p2align 2 /* force 4-byte alignment */ -multiboot_header: - /* magic */ - .long 0x1BADB002 - /* flags */ - .long (1 << 16) - /* checksum */ - .long -0x1BADB002 - (1 << 16) - /* header addr */ - .long multiboot_header - _start + 0x100000 + 0x200 - /* load addr */ - .long 0x100000 - /* load end addr */ - .long 0 - /* bss end addr */ - .long 0 - /* entry addr */ - .long multiboot_entry - _start + 0x100000 + 0x200 - -multiboot_entry: - .code32 - /* obtain the boot device */ - movl 12(%ebx), %edx - - movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp - movl %ebp, %esp - - /* relocate the code */ - movl $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx - addl EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx - movl $0x100000, %esi - movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi - cld - rep - movsb - /* jump to the real address */ - movl $multiboot_trampoline, %eax - jmp *%eax - -multiboot_trampoline: - /* fill the boot information */ - movl %edx, %eax - shrl $8, %eax - xorl %ebx, %ebx - cmpb $0xFF, %ah - je 1f - movb %ah, %bl - movl %ebx, EXT_C(grub_install_dos_part) -1: - cmpb $0xFF, %al - je 2f - movb %al, %bl - movl %ebx, EXT_C(grub_install_bsd_part) -2: - shrl $24, %edx - movb $0xFF, %dh - /* enter the usual booting */ - call prot_to_real - jmp LOCAL (codestart) - -post_reed_solomon: - -#ifdef ENABLE_LZMA - movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi - movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi - pushl %edi - pushl %esi - movl $(BSS_START_SYMBOL - _start), %ecx - addl EXT_C(grub_total_module_size), %ecx - subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx - pushl %ecx - leal (%edi, %ecx), %ebx - call _LzmaDecodeA - /* _LzmaDecodeA clears DF, so no need to run cld */ - popl %ecx - popl %edi - popl %esi -#endif + movl %ecx, (LOCAL(real_to_prot_addr) - _start) (%esi) + movl %edi, (LOCAL(prot_to_real_addr) - _start) (%esi) /* copy back the decompressed part (except the modules) */ - subl EXT_C(grub_total_module_size), %ecx + movl $(_edata - _start), %ecx + movl $(_start), %edi rep movsb + movl $LOCAL (cont), %esi + jmp *%esi +LOCAL(cont): + #if 0 /* copy modules before cleaning out the bss */ movl EXT_C(grub_total_module_size), %ecx @@ -255,24 +82,14 @@ post_reed_solomon: movsb #endif -#ifdef APPLE_CC - /* clean out the bss */ - bss_start_abs = ABS (bss_start) - bss_end_abs = ABS (bss_end) + movl %eax, %esi - movl bss_start_abs, %edi - - /* compute the bss length */ - movl bss_end_abs, %ecx - subl %edi, %ecx -#else /* clean out the bss */ movl $BSS_START_SYMBOL, %edi /* compute the bss length */ movl $END_SYMBOL, %ecx subl %edi, %ecx -#endif /* clean out */ xorl %eax, %eax @@ -280,172 +97,29 @@ post_reed_solomon: rep stosb + movl %esi, EXT_C(grub_install_dos_part) + movb %dl, EXT_C(grub_boot_drive) + movl %ebx, EXT_C(grub_install_bsd_part) + /* * Call the start of main body of C code. */ call EXT_C(grub_main) -#include "../realmode.S" +LOCAL(real_to_prot_addr): + .long 0 +LOCAL(prot_to_real_addr): + .long 0 -/* - * grub_gate_a20(int on) - * - * Gate address-line 20 for high memory. - * - * This routine is probably overconservative in what it does, but so what? - * - * It also eats any keystrokes in the keyboard buffer. :-( - */ + .macro PROT_TO_REAL + movl LOCAL(prot_to_real_addr), %eax + call *%eax + .endm -grub_gate_a20: - movl %eax, %edx - -gate_a20_test_current_state: - /* first of all, test if already in a good state */ - call gate_a20_check_state - cmpb %al, %dl - jnz gate_a20_try_bios - ret - -gate_a20_try_bios: - /* second, try a BIOS call */ - pushl %ebp - call prot_to_real - - .code16 - movw $0x2400, %ax - testb %dl, %dl - jz 1f - incw %ax -1: int $0x15 - - DATA32 call real_to_prot - .code32 - - popl %ebp - call gate_a20_check_state - cmpb %al, %dl - jnz gate_a20_try_system_control_port_a - ret - -gate_a20_try_system_control_port_a: - /* - * In macbook, the keyboard test would hang the machine, so we move - * this forward. - */ - /* fourth, try the system control port A */ - inb $0x92 - andb $(~0x03), %al - testb %dl, %dl - jz 6f - orb $0x02, %al -6: outb $0x92 - - /* When turning off Gate A20, do not check the state strictly, - because a failure is not fatal usually, and Gate A20 is always - on some modern machines. */ - testb %dl, %dl - jz 7f - call gate_a20_check_state - cmpb %al, %dl - jnz gate_a20_try_keyboard_controller -7: ret - -gate_a20_flush_keyboard_buffer: - inb $0x64 - andb $0x02, %al - jnz gate_a20_flush_keyboard_buffer -2: - inb $0x64 - andb $0x01, %al - jz 3f - inb $0x60 - jmp 2b -3: - ret - -gate_a20_try_keyboard_controller: - /* third, try the keyboard controller */ - call gate_a20_flush_keyboard_buffer - - movb $0xd1, %al - outb $0x64 -4: - inb $0x64 - andb $0x02, %al - jnz 4b - - movb $0xdd, %al - testb %dl, %dl - jz 5f - orb $0x02, %al -5: outb $0x60 - call gate_a20_flush_keyboard_buffer - - /* output a dummy command (USB keyboard hack) */ - movb $0xff, %al - outb $0x64 - call gate_a20_flush_keyboard_buffer - - call gate_a20_check_state - cmpb %al, %dl - /* everything failed, so restart from the beginning */ - jnz gate_a20_try_bios - ret - -gate_a20_check_state: - /* iterate the checking for a while */ - movl $100, %ecx -1: - call 3f - cmpb %al, %dl - jz 2f - loop 1b -2: - ret -3: - pushl %ebx - pushl %ecx - xorl %eax, %eax - /* compare the byte at 0x8000 with that at 0x108000 */ - movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx - pushl %ebx - /* save the original byte in CL */ - movb (%ebx), %cl - /* store the value at 0x108000 in AL */ - addl $0x100000, %ebx - movb (%ebx), %al - /* try to set one less value at 0x8000 */ - popl %ebx - movb %al, %ch - decb %ch - movb %ch, (%ebx) - /* serialize */ - outb %al, $0x80 - outb %al, $0x80 - /* obtain the value at 0x108000 in CH */ - pushl %ebx - addl $0x100000, %ebx - movb (%ebx), %ch - /* this result is 1 if A20 is on or 0 if it is off */ - subb %ch, %al - xorb $1, %al - /* restore the original */ - popl %ebx - movb %cl, (%ebx) - popl %ecx - popl %ebx - ret - -#ifdef ENABLE_LZMA -#include "lzma_decode.S" -#endif - -/* - * The code beyond this point is compressed. Assert that the uncompressed - * code fits GRUB_KERNEL_MACHINE_RAW_SIZE. - */ - . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE + .macro REAL_TO_PROT + movl LOCAL(real_to_prot_addr), %eax + DATA32 call *%ax + .endm /* * grub_exit() @@ -453,7 +127,7 @@ gate_a20_check_state: * Exit the system. */ FUNCTION(grub_exit) - call prot_to_real + PROT_TO_REAL .code16 /* Tell the BIOS a boot failure. If this does not work, reboot. */ int $0x18 @@ -482,7 +156,7 @@ FUNCTION(grub_pxe_call) shll $16, %edx addl %eax, %edx - call prot_to_real + PROT_TO_REAL .code16 pushl %ebx @@ -494,7 +168,7 @@ FUNCTION(grub_pxe_call) addw $10, %sp movw %ax, %cx - DATA32 call real_to_prot + REAL_TO_PROT .code32 movzwl %cx, %eax @@ -506,3 +180,11 @@ FUNCTION(grub_pxe_call) ret #include "../int.S" + + .bss +VARIABLE(grub_boot_drive) + .byte 0 +VARIABLE(grub_install_dos_part) + .long 0xFFFFFFFF +VARIABLE(grub_install_bsd_part) + .long 0xFFFFFFFF diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 3e8a13892..2e16847c8 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -51,6 +51,14 @@ protstack: .long GRUB_MEMORY_MACHINE_PROT_STACK + .macro PROT_TO_REAL + call prot_to_real + .endm + + .macro REAL_TO_PROT + DATA32 call real_to_prot + .endm + /* * This is the Global Descriptor Table * @@ -162,6 +170,25 @@ protcseg: /* return on the old (or initialized) stack! */ ret +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,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 prot_to_real: /* just in case, set GDT */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 92354f700..e3b9a377c 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -19,11 +19,11 @@ #ifndef OFFSETS_HEADER #define OFFSETS_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE 0x08 /* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x0c +#define GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE 0x0c /* The offset of GRUB_INSTALL_DOS_PART. */ #define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10 @@ -34,15 +34,12 @@ /* Offset of reed_solomon_redundancy. */ #define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 -/* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc70 - #define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 -#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200 +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000 /* The upper memory area (starting at 640 kiB). */ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000 @@ -62,7 +59,6 @@ #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 -#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 @@ -133,10 +129,12 @@ #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _RAW_SIZE) #define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_BSD_PART) #define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_DOS_PART) #define GRUB_MACHINE_LINK_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _LINK_ADDR) + +#define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) +#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) #endif #ifndef ASM_FILE diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 9369fba3d..9da72f6c9 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -54,7 +54,7 @@ #define TARGET_NO_FIELD 0xffffffff typedef enum { - COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ + COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ, COMPRESSION_LZMA } grub_compression_t; struct image_target_desc @@ -73,13 +73,13 @@ struct image_target_desc enum { PLATFORM_FLAGS_NONE = 0, - PLATFORM_FLAGS_LZMA = 1, PLATFORM_FLAGS_DECOMPRESSORS = 2, PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4, } flags; - unsigned raw_size; unsigned total_module_size; - unsigned compressed_size; + unsigned decompressor_compressed_size; + unsigned decompressor_uncompressed_size; + unsigned decompressor_uncompressed_addr; unsigned link_align; grub_uint16_t elf_target; unsigned section_align; @@ -107,9 +107,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -127,9 +128,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -146,10 +148,11 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_PC, - .flags = PLATFORM_FLAGS_LZMA, - .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, - .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, @@ -162,10 +165,11 @@ struct image_target_desc image_targets[] = .voidp_sizeof = 4, .bigendian = 0, .id = IMAGE_I386_PC_PXE, - .flags = PLATFORM_FLAGS_LZMA, - .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, - .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, @@ -179,9 +183,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE @@ -201,9 +206,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -221,9 +227,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -237,9 +244,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, .install_dos_part = TARGET_NO_FIELD, @@ -254,9 +262,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -273,9 +282,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -294,9 +304,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -313,9 +324,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -333,9 +345,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_RAW, .flags = PLATFORM_FLAGS_NONE, - .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -349,9 +362,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_SPARC64_AOUT, .flags = PLATFORM_FLAGS_NONE, - .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -365,9 +379,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, - .raw_size = 0, .total_module_size = TARGET_NO_FIELD, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = EFI64_HEADER_SIZE, .install_dos_part = TARGET_NO_FIELD, @@ -383,9 +398,10 @@ struct image_target_desc image_targets[] = .id = IMAGE_MIPS_ARC, .flags = (PLATFORM_FLAGS_DECOMPRESSORS | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -402,9 +418,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -421,9 +438,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -440,9 +458,10 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -459,9 +478,10 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, - .raw_size = 0, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .compressed_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, @@ -593,7 +613,7 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree }; static void compress_kernel_lzma (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size, size_t raw_size) + char **core_img, size_t *core_size) { CLzmaEncProps props; unsigned char out_props[5]; @@ -606,27 +626,21 @@ compress_kernel_lzma (char *kernel_img, size_t kernel_size, props.pb = 2; props.numThreads = 1; - if (kernel_size < raw_size) - grub_util_error (_("the core image is too small")); - *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - raw_size; - if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, - (unsigned char *) kernel_img + raw_size, - kernel_size - raw_size, + *core_size = kernel_size; + if (LzmaEncode ((unsigned char *) *core_img, core_size, + (unsigned char *) kernel_img, + kernel_size, &props, out_props, &out_props_size, 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) grub_util_error (_("cannot compress the kernel image")); - - *core_size += raw_size; } #ifdef HAVE_LIBLZMA static void compress_kernel_xz (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size, size_t raw_size) + char **core_img, size_t *core_size) { lzma_stream strm = LZMA_STREAM_INIT; lzma_ret xzret; @@ -647,20 +661,16 @@ compress_kernel_xz (char *kernel_img, size_t kernel_size, { .id = LZMA_VLI_UNKNOWN, .options = NULL} }; - if (kernel_size < raw_size) - grub_util_error (_("the core image is too small")); - xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); if (xzret != LZMA_OK) grub_util_error (_("cannot compress the kernel image")); *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - raw_size; - strm.next_in = (unsigned char *) kernel_img + raw_size; - strm.avail_in = kernel_size - raw_size; - strm.next_out = (unsigned char *) *core_img + raw_size; + *core_size = kernel_size; + strm.next_in = (unsigned char *) kernel_img; + strm.avail_in = kernel_size; + strm.next_out = (unsigned char *) *core_img; strm.avail_out = *core_size; while (1) @@ -674,8 +684,6 @@ compress_kernel_xz (char *kernel_img, size_t kernel_size, } *core_size -= strm.avail_out; - - *core_size += raw_size; } #endif @@ -684,19 +692,20 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, size_t kernel_size, char **core_img, size_t *core_size, grub_compression_t comp) { - if (image_target->flags & PLATFORM_FLAGS_LZMA) - { - compress_kernel_lzma (kernel_img, kernel_size, core_img, - core_size, image_target->raw_size); - return; - } + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == COMPRESSION_LZMA)) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size); + return; + } #ifdef HAVE_LIBLZMA if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS && (comp == COMPRESSION_XZ)) { compress_kernel_xz (kernel_img, kernel_size, core_img, - core_size, image_target->raw_size); + core_size); return; } #endif @@ -747,6 +756,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (comp == COMPRESSION_AUTO) comp = image_target->default_compression; + if (image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE) + comp = COMPRESSION_LZMA; + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -903,31 +916,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], &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 *) (kernel_img + image_target->total_module_size)) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) = grub_host_to_target32 (total_module_size); - if (image_target->compressed_size != TARGET_NO_FIELD) - *((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 - prepend the drive told by BIOS. */ - if (image_target->install_dos_part != TARGET_NO_FIELD - && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') - { - *((grub_int32_t *) (kernel_img + image_target->install_dos_part)) - = grub_host_to_target32 (-2); - *((grub_int32_t *) (kernel_img + image_target->install_bsd_part)) - = grub_host_to_target32 (-2); - } if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) { @@ -941,6 +935,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], case COMPRESSION_XZ: name = "xz_decompress.img"; break; + case COMPRESSION_LZMA: + name = "lzma_decompress.img"; + break; case COMPRESSION_NONE: name = "none_decompress.img"; break; @@ -952,19 +949,30 @@ 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_LOONGSON_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size); + if ((image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE) + && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) + grub_util_error (_("Decompressor is too big")); - *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE)) - = grub_host_to_target32 (kernel_size + total_module_size); + if (image_target->decompressor_compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_compressed_size)) + = grub_host_to_target32 (core_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); + if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_uncompressed_size)) + = grub_host_to_target32 (kernel_size + total_module_size); + if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD) + { + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr - total_module_size); + else + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr); + } full_size = core_size + decompress_size; full_img = xmalloc (full_size); @@ -982,6 +990,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = full_size; } + /* If we included a drive in our prefix, let GRUB know it doesn't have to + prepend the drive told by BIOS. */ + 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_host_to_target32 (-2); + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) + = grub_host_to_target32 (-2); + } + switch (image_target->id) { case IMAGE_I386_PC: @@ -1249,7 +1268,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 *) (kernel_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) = grub_host_to_target32 ((grub_uint32_t) -rom_size); memcpy (rom_img, core_img, core_size); From 691cbb58163628d7244b66997e713f443b8af8e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 20:53:46 +0100 Subject: [PATCH 1400/1414] Fix bug introduced by previous commit. * grub-core/boot/i386/pc/startup_raw.S: Compute RS start correctly. --- ChangeLog | 6 ++++++ grub-core/boot/i386/pc/startup_raw.S | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eeb9bda57..70db75379 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-12 Vladimir Serbinenko + + Fix bug introduced by previous commit. + + * grub-core/boot/i386/pc/startup_raw.S: Compute RS start correctly. + 2011-11-12 Vladimir Serbinenko Use decompressors framework on i386-pc. It increases core size diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 4820e3442..09b6fed76 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -107,7 +107,7 @@ LOCAL (codestart): call grub_gate_a20 movl LOCAL(compressed_size), %edx - addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx + addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - _start), %edx movl reed_solomon_redundancy, %ecx leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax call EXT_C (grub_reed_solomon_recover) From 5fbdac149b05ce50a3de0dfb6ef6d37e29bc8575 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 21:12:52 +0100 Subject: [PATCH 1401/1414] Defer multiboot device parsing until we're in compressed part. * grub-core/boot/i386/pc/lnxboot.S: Remove setting dos_part and bsd_part. setdevice has fallen into disuse. * grub-core/boot/i386/pc/startup_raw.S (dos_part): Removed. (bsd_part): Likewise. (boot_dev): New variable. (multiboot_trampoline): Don't parse multiboot device. Pass multiboot device in %edx. * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Parse grub_boot_device. * grub-core/kern/i386/pc/init.c (grub_machine_get_bootlocation): Likewise. * grub-core/kern/i386/pc/startup.S: Save edx. (grub_boot_drive): Removed. (grub_install_dos_part): Likewise. (grub_install_bsd_part): Likewise. (grub_boot_device): New variable. * include/grub/i386/pc/kernel.h (grub_install_dos_part): Removed. (grub_install_bsd_part): Likewise. (grub_boot_drive): Likewise. (grub_boot_device): New variable. * include/grub/offsets.h (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Removed. (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Moved lower. (GRUB_KERNEL_MACHINE_INSTALL_BSD_PART): Removed. (GRUB_KERNEL_MACHINE_INSTALL_DOS_PART): Likewise. * util/grub-install.in: Remove redundant condition. --- ChangeLog | 32 +++++++++++++++++ grub-core/boot/i386/pc/lnxboot.S | 5 --- grub-core/boot/i386/pc/startup_raw.S | 33 +++--------------- grub-core/disk/i386/pc/biosdisk.c | 14 ++++---- grub-core/kern/i386/pc/init.c | 19 ++++++---- grub-core/kern/i386/pc/startup.S | 14 ++------ include/grub/i386/pc/kernel.h | 9 +---- include/grub/offsets.h | 10 +----- util/grub-install.in | 2 +- util/grub-mkimage.c | 52 ---------------------------- util/grub-setup.c | 44 ----------------------- 11 files changed, 63 insertions(+), 171 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70db75379..b5124c18a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2011-11-12 Vladimir Serbinenko + + Defer multiboot device parsing until we're in compressed part. + + * grub-core/boot/i386/pc/lnxboot.S: Remove setting dos_part and + bsd_part. setdevice has fallen into disuse. + * grub-core/boot/i386/pc/startup_raw.S (dos_part): Removed. + (bsd_part): Likewise. + (boot_dev): New variable. + (multiboot_trampoline): Don't parse multiboot device. + Pass multiboot device in %edx. + * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Parse + grub_boot_device. + * grub-core/kern/i386/pc/init.c (grub_machine_get_bootlocation): + Likewise. + * grub-core/kern/i386/pc/startup.S: Save edx. + (grub_boot_drive): Removed. + (grub_install_dos_part): Likewise. + (grub_install_bsd_part): Likewise. + (grub_boot_device): New variable. + * include/grub/i386/pc/kernel.h (grub_install_dos_part): Removed. + (grub_install_bsd_part): Likewise. + (grub_boot_drive): Likewise. + (grub_boot_device): New variable. + * include/grub/offsets.h (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): + Removed. + (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. + (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Moved lower. + (GRUB_KERNEL_MACHINE_INSTALL_BSD_PART): Removed. + (GRUB_KERNEL_MACHINE_INSTALL_DOS_PART): Likewise. + * util/grub-install.in: Remove redundant condition. + 2011-11-12 Vladimir Serbinenko Fix bug introduced by previous commit. diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index e5227d174..4fe0df139 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -205,11 +205,6 @@ real_code_2: 2: call LOCAL(move_memory) - movsbl %dh, %eax - movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) - movsbl (reg_edx + 2 - start), %eax - movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) - movb $0xFF, %dh ljmp $(DATA_ADDR >> 4), $0 diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 09b6fed76..9e0f23d71 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -57,13 +57,6 @@ LOCAL(compressed_size): LOCAL(uncompressed_size): .long 0 - . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART -LOCAL(dos_part): - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART -LOCAL(bsd_part): - .long 0xFFFFFFFF - . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY reed_solomon_redundancy: .long 0 @@ -72,8 +65,10 @@ reed_solomon_redundancy: * This is the area for all of the special variables. */ +LOCAL(boot_dev): + .byte 0xFF, 0xFF, 0xFF LOCAL(boot_drive): - .byte 0 + .byte 0x00 /* the real mode code continues... */ LOCAL (codestart): @@ -164,28 +159,12 @@ multiboot_entry: multiboot_trampoline: /* fill the boot information */ - movl %edx, %eax - shrl $8, %eax - xorl %ebx, %ebx - cmpb $0xFF, %ah - je 1f - movb %ah, %bl - movl %ebx, LOCAL(dos_part) -1: - cmpb $0xFF, %al - je 2f - movb %al, %bl - movl %ebx, LOCAL(bsd_part) -2: + movl %edx, LOCAL(boot_dev) shrl $24, %edx - movb %dl, LOCAL(boot_drive) - movb $0xFF, %dh - movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp /* enter the usual booting */ call prot_to_real .code16 jmp LOCAL (codestart) - .code32 post_reed_solomon: @@ -201,9 +180,7 @@ post_reed_solomon: popl %esi #endif - movb LOCAL(boot_drive), %dl - movl LOCAL(dos_part), %eax - movl LOCAL(bsd_part), %ebx + movl LOCAL(boot_dev), %edx movl $prot_to_real, %edi movl $real_to_prot, %ecx jmp *%esi diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 25f683fd1..173e734d8 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -622,7 +622,8 @@ grub_disk_biosdisk_fini (void) GRUB_MOD_INIT(biosdisk) { struct grub_biosdisk_cdrp *cdrp - = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_uint8_t boot_drive; if (grub_disk_firmware_is_tainted) { @@ -634,15 +635,16 @@ GRUB_MOD_INIT(biosdisk) grub_memset (cdrp, 0, sizeof (*cdrp)); cdrp->size = sizeof (*cdrp); cdrp->media_type = 0xFF; - if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) && - ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) - == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) + boot_drive = (grub_boot_device >> 24); + if ((! grub_biosdisk_get_cdinfo_int13_extensions (boot_drive, cdrp)) + && ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) + == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) cd_drive = cdrp->drive_no; /* Since diskboot.S rejects devices over 0x90 it must be a CD booted with cdboot.S */ - if (grub_boot_drive >= 0x90) - cd_drive = grub_boot_drive; + if (boot_drive >= 0x90) + cd_drive = boot_drive; grub_disk_dev_register (&grub_biosdisk_dev); } diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index da7230c33..c6492619f 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -67,10 +67,15 @@ void grub_machine_get_bootlocation (char **device, char **path) { char *ptr; + grub_uint8_t boot_drive, dos_part, bsd_part; + + boot_drive = (grub_boot_device >> 24); + dos_part = (grub_boot_device >> 16); + bsd_part = (grub_boot_device >> 8); /* No hardcoded root partition - make it from the boot drive and the partition number encoded at the install time. */ - if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL) + if (boot_drive == GRUB_BOOT_MACHINE_PXE_DL) { if (grub_pc_net_config) grub_pc_net_config (device, path); @@ -82,18 +87,18 @@ grub_machine_get_bootlocation (char **device, char **path) *device = grub_malloc (DEV_SIZE); ptr = *device; grub_snprintf (*device, DEV_SIZE, - "%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', - grub_boot_drive & 0x7f); + "%cd%u", (boot_drive & 0x80) ? 'h' : 'f', + boot_drive & 0x7f); ptr += grub_strlen (ptr); - if (grub_install_dos_part >= 0) + if (dos_part != 0xff) grub_snprintf (ptr, DEV_SIZE - (ptr - *device), - ",%u", grub_install_dos_part + 1); + ",%u", dos_part + 1); ptr += grub_strlen (ptr); - if (grub_install_bsd_part >= 0) + if (bsd_part != 0xff) grub_snprintf (ptr, DEV_SIZE - (ptr - *device), ",%u", - grub_install_bsd_part + 1); + bsd_part + 1); ptr += grub_strlen (ptr); *ptr = 0; } diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index 058f9efa7..51e19b7f0 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -82,8 +82,6 @@ LOCAL(cont): movsb #endif - movl %eax, %esi - /* clean out the bss */ movl $BSS_START_SYMBOL, %edi @@ -97,9 +95,7 @@ LOCAL(cont): rep stosb - movl %esi, EXT_C(grub_install_dos_part) - movb %dl, EXT_C(grub_boot_drive) - movl %ebx, EXT_C(grub_install_bsd_part) + movl %edx, EXT_C(grub_boot_device) /* * Call the start of main body of C code. @@ -182,9 +178,5 @@ FUNCTION(grub_pxe_call) #include "../int.S" .bss -VARIABLE(grub_boot_drive) - .byte 0 -VARIABLE(grub_install_dos_part) - .long 0xFFFFFFFF -VARIABLE(grub_install_bsd_part) - .long 0xFFFFFFFF +VARIABLE(grub_boot_device) + .long 0 diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 2dcdbb7a6..4f05b74e3 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -32,14 +32,7 @@ /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The DOS partition number of the installed partition. */ -extern grub_int32_t grub_install_dos_part; - -/* The BSD partition number of the installed partition. */ -extern grub_int32_t grub_install_bsd_part; - -/* The boot BIOS drive number. */ -extern grub_uint8_t EXPORT_VAR(grub_boot_drive); +extern grub_uint32_t EXPORT_VAR(grub_boot_device); extern void (*EXPORT_VAR(grub_pc_net_config)) (char **device, char **path); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index e3b9a377c..1269c865d 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -25,14 +25,8 @@ /* The offset of GRUB_COMPRESSED_SIZE. */ #define GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE 0x0c -/* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10 - -/* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x14 - /* Offset of reed_solomon_redundancy. */ -#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18 +#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x10 #define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0 @@ -129,8 +123,6 @@ #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_BSD_PART) -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_DOS_PART) #define GRUB_MACHINE_LINK_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _LINK_ADDR) #define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) diff --git a/util/grub-install.in b/util/grub-install.in index 26a2523f8..ea8699a44 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -564,7 +564,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg" config_opt="-c ${grubdir}/load.cfg " modules="$modules search_fs_uuid" - elif [ "x$platform" = xefi ] || [ "x$platform" = xpc ] || [ "x$platform" = xieee1275 ]; then + else # we need to hardcode the partition number in the core image's prefix. if [ x"$grub_partition" = x ]; then prefix_drive="()" diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 9da72f6c9..3912ad7b2 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -84,7 +84,6 @@ struct image_target_desc grub_uint16_t elf_target; unsigned section_align; signed vaddr_offset; - unsigned install_dos_part, install_bsd_part; grub_uint64_t link_addr; unsigned mod_gap, mod_align; grub_compression_t default_compression; @@ -113,8 +112,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_I386_COREBOOT_LINK_ADDR, .elf_target = EM_386, .link_align = 4, @@ -134,8 +131,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_I386_COREBOOT_LINK_ADDR, .elf_target = EM_386, .link_align = 4, @@ -155,8 +150,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, - .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, { @@ -172,8 +165,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, - .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, { @@ -194,8 +185,6 @@ struct image_target_desc image_targets[] = + sizeof (struct grub_pe32_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_I386, .elf_target = EM_386, }, @@ -212,8 +201,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_I386_IEEE1275_LINK_ADDR, .elf_target = EM_386, .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, @@ -233,8 +220,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_I386_QEMU_LINK_ADDR }, { @@ -250,8 +235,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 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, .elf_target = EM_X86_64, }, @@ -268,8 +251,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, @@ -288,8 +269,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, @@ -310,8 +289,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, - .install_dos_part = TARGET_NO_FIELD, - .install_bsd_part = TARGET_NO_FIELD, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, .elf_target = EM_MIPS, .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, @@ -330,8 +307,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_POWERPC_IEEE1275_LINK_ADDR, .elf_target = EM_PPC, .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, @@ -351,8 +326,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_SPARC64_IEEE1275_LINK_ADDR }, { @@ -368,8 +341,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = 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_SPARC64_IEEE1275_LINK_ADDR }, { @@ -385,8 +356,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 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, .elf_target = EM_IA_64, }, @@ -404,8 +373,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .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, @@ -424,8 +391,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .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, @@ -444,8 +409,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .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, @@ -464,8 +427,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .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, @@ -484,8 +445,6 @@ struct image_target_desc image_targets[] = .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .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, @@ -990,17 +949,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_size = full_size; } - /* If we included a drive in our prefix, let GRUB know it doesn't have to - prepend the drive told by BIOS. */ - 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_host_to_target32 (-2); - *((grub_int32_t *) (core_img + image_target->install_bsd_part)) - = grub_host_to_target32 (-2); - } - switch (image_target->id) { case IMAGE_I386_PC: diff --git a/util/grub-setup.c b/util/grub-setup.c index f185ed747..055543f2d 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -101,56 +101,12 @@ write_rootdev (char *core_img, grub_device_t root_dev, { #ifdef GRUB_MACHINE_PCBIOS { - grub_int32_t *install_dos_part, *install_bsd_part; - grub_int32_t dos_part, bsd_part; grub_uint8_t *boot_drive; grub_disk_addr_t *kernel_sector; boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE); kernel_sector = (grub_disk_addr_t *) (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); - - install_dos_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); - install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE - + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); - - /* If we hardcoded drive as part of prefix, we don't want to - override the current setting. */ - if (*install_dos_part != -2) - { - /* Embed information about the installed location. */ - if (root_dev->disk->partition) - { - if (root_dev->disk->partition->parent) - { - if (root_dev->disk->partition->parent->parent) - grub_util_error (_("Installing on doubly nested partitions " - "is not supported")); - dos_part = root_dev->disk->partition->parent->number; - bsd_part = root_dev->disk->partition->number; - } - else - { - dos_part = root_dev->disk->partition->number; - bsd_part = -1; - } - } - else - dos_part = bsd_part = -1; - } - else - { - dos_part = grub_le_to_cpu32 (*install_dos_part); - bsd_part = grub_le_to_cpu32 (*install_bsd_part); - } - - grub_util_info ("dos partition is %d, bsd partition is %d", - dos_part, bsd_part); - - *install_dos_part = grub_cpu_to_le32 (dos_part); - *install_bsd_part = grub_cpu_to_le32 (bsd_part); - /* FIXME: can this be skipped? */ *boot_drive = 0xFF; From aa94b87027857472aba93d6c7e39abaa10103d96 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 21:38:04 +0100 Subject: [PATCH 1402/1414] Fix MIPS compilation. * grub-core/boot/mips/startup_raw.S: Use GRUB_DECOMPRESSOR_* * include/grub/offsets.h: Rename decompressor fields from GRUB_KERNEL_* to GRUB_DECOMPRESSOR_*. * util/grub-mkimage.c (image_targets): Use new names. --- ChangeLog | 9 ++++++ grub-core/boot/mips/startup_raw.S | 6 ++-- include/grub/offsets.h | 23 +++++++-------- util/grub-mkimage.c | 48 +++++++++++++++---------------- 4 files changed, 46 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5124c18a..15389a335 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-12 Vladimir Serbinenko + + Fix MIPS compilation. + + * grub-core/boot/mips/startup_raw.S: Use GRUB_DECOMPRESSOR_* + * include/grub/offsets.h: Rename decompressor fields from + GRUB_KERNEL_* to GRUB_DECOMPRESSOR_*. + * util/grub-mkimage.c (image_targets): Use new names. + 2011-11-12 Vladimir Serbinenko Defer multiboot device parsing until we're in compressed part. diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index e76926677..bbbc1dbec 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -240,9 +240,9 @@ cmdlinedone: subu $a0, $a0, $t0 addu $a0, $a0, $s0 - 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) + lw $a1, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0) + lw $a2, (GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a3, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 1269c865d..68ed084cb 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -62,26 +62,26 @@ #define GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN 32 -#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_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE 0x8 +#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE 0xc +#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 #define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR 0x80200000 #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_DECOMPRESSOR_MIPS_QEMU_MIPS_COMPRESSED_SIZE 0x8 +#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE 0xc +#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE 0x08 #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_DECOMPRESSOR_MIPS_ARC_COMPRESSED_SIZE 0x8 +#define GRUB_DECOMPRESSOR_MIPS_ARC_UNCOMPRESSED_SIZE 0xc +#define GRUB_DECOMPRESSOR_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 @@ -116,10 +116,6 @@ #define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_ALIGN) #define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_GAP) #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _TOTAL_MODULE_SIZE) -#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_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) @@ -127,6 +123,7 @@ #define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) #define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) +#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_ADDR) #endif #ifndef ASM_FILE diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 3912ad7b2..0ffeb909e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -246,9 +246,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, @@ -264,9 +264,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_FULOONG2F_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, @@ -284,9 +284,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, @@ -368,9 +368,9 @@ struct image_target_desc image_targets[] = .flags = (PLATFORM_FLAGS_DECOMPRESSORS | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR, @@ -386,9 +386,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, @@ -404,9 +404,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, @@ -422,9 +422,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_QEMU_MIPS_FLASH, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, @@ -440,9 +440,9 @@ struct image_target_desc image_targets[] = .id = IMAGE_LOONGSON_ELF, .flags = PLATFORM_FLAGS_DECOMPRESSORS, .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, - .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE, - .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE, - .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, .section_align = 1, .vaddr_offset = 0, .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, From ba102053ce9943a7cf77e9d85f95d5f4bfa8ae1c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 21:46:52 +0100 Subject: [PATCH 1403/1414] Support ZFS embedding. * grub-core/fs/zfs/zfs.c (grub_zfs_embed): New function. (grub_zfs_fs): Register grub_zfs_embed. --- ChangeLog | 7 +++++++ grub-core/fs/zfs/zfs.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/ChangeLog b/ChangeLog index 15389a335..c12f19951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-12 Vladimir Serbinenko + + Support ZFS embedding. + + * grub-core/fs/zfs/zfs.c (grub_zfs_embed): New function. + (grub_zfs_fs): Register grub_zfs_embed. + 2011-11-12 Vladimir Serbinenko Fix MIPS compilation. diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 20cba3509..83a067237 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -3806,6 +3806,35 @@ grub_zfs_dir (grub_device_t device, const char *path, return grub_errno; } +#ifdef GRUB_UTIL +static grub_err_t +grub_zfs_embed (grub_device_t device __attribute__ ((unused)), + unsigned int *nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) +{ + unsigned i; + + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ZFS currently supports only PC-BIOS embedding"); + + if ((VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS) < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "Your core.img is unusually large. " + "It won't fit in the embedding area."); + + *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS); + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) + (*sectors)[i] = i + (VDEV_BOOT_OFFSET >> GRUB_DISK_SECTOR_BITS); + + return GRUB_ERR_NONE; +} +#endif + static struct grub_fs grub_zfs_fs = { .name = "zfs", .dir = grub_zfs_dir, @@ -3815,6 +3844,10 @@ static struct grub_fs grub_zfs_fs = { .label = zfs_label, .uuid = zfs_uuid, .mtime = zfs_mtime, +#ifdef GRUB_UTIL + .embed = grub_zfs_embed, + .reserved_first_sector = 1, +#endif .next = 0 }; From 9edd7be26aef4fe4293835bb9dce3f49e7aff007 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:14:51 +0100 Subject: [PATCH 1404/1414] Fix spaces handling in proc/self/mountinfo. * util/getroot.c (unescape): New function. (grub_find_root_device_from_mountinfo): Use unescape. --- ChangeLog | 7 +++++++ util/getroot.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/ChangeLog b/ChangeLog index c12f19951..ab253ddfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-12 Vladimir Serbinenko + + Fix spaces handling in proc/self/mountinfo. + + * util/getroot.c (unescape): New function. + (grub_find_root_device_from_mountinfo): Use unescape. + 2011-11-12 Vladimir Serbinenko Support ZFS embedding. diff --git a/util/getroot.c b/util/getroot.c index f5d6d3f62..96879f545 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -129,6 +129,27 @@ struct mountinfo_entry can't deal with the multiple-device case yet, but in the meantime, we can at least cope with the single-device case by scanning /proc/self/mountinfo. */ +static void +unescape (char *str) +{ + char *optr; + const char *iptr; + for (iptr = optr = str; *iptr; optr++) + { + if (iptr[0] == '\\' && iptr[1] >= '0' && iptr[1] < '8' + && iptr[2] >= '0' && iptr[2] < '8' + && iptr[3] >= '0' && iptr[3] < '8') + { + *optr = (((iptr[1] - '0') << 6) | ((iptr[2] - '0') << 3) + | (iptr[3] - '0')); + iptr += 4; + } + else + *optr = *iptr++; + } + *optr = 0; +} + char * grub_find_root_device_from_mountinfo (const char *dir, char **relroot) { @@ -165,6 +186,9 @@ grub_find_root_device_from_mountinfo (const char *dir, char **relroot) entry.enc_root, entry.enc_path, &count) < 6) continue; + unescape (entry.enc_root); + unescape (entry.enc_path); + enc_path_len = strlen (entry.enc_path); /* Check that enc_path is a prefix of dir. The prefix must either be the entire string, or end with a slash, or be immediately followed From 0cddeb0360d60b518b721996d0dd5d0e5eff476a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:16:48 +0100 Subject: [PATCH 1405/1414] Add copyright year. --- grub-core/disk/lvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index 388c7f173..2fd736439 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -1,7 +1,7 @@ /* lvm.c - module to read Logical Volumes. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 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 From 91e5a33da510d7e48e35c76f54f8ff3b53c19c0e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:35:20 +0100 Subject: [PATCH 1406/1414] * include/grub/lvm.h (grub_lvm_pv): Correct start type. --- ChangeLog | 4 ++++ include/grub/lvm.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ab253ddfd..9f5b71fe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * include/grub/lvm.h (grub_lvm_pv): Correct start type. + 2011-11-12 Vladimir Serbinenko Fix spaces handling in proc/self/mountinfo. diff --git a/include/grub/lvm.h b/include/grub/lvm.h index b5352c75c..d77b88ff5 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -38,7 +38,7 @@ struct grub_lvm_pv { char id[GRUB_LVM_ID_STRLEN+1]; char *name; grub_disk_t disk; - int start; /* Sector number where the data area starts. */ + grub_disk_addr_t start; /* Sector number where the data area starts. */ struct grub_lvm_pv *next; }; From 91ee7b6d737fdba31e052fbe44349d94895df99f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:42:49 +0100 Subject: [PATCH 1407/1414] * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. --- ChangeLog | 4 ++++ grub-core/kern/emu/hostdisk.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9f5b71fe4..1ce25663d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. + 2011-11-12 Vladimir Serbinenko * include/grub/lvm.h (grub_lvm_pv): Correct start type. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index f537b2759..ede765d83 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1751,7 +1751,10 @@ find_system_device (const char *os_dev, struct stat *st, int convert, int add) } if (!add) - return -1; + { + free (os_disk); + return -1; + } if (i == ARRAY_SIZE (map)) grub_util_error (_("device count exceeds limit")); From d89ee4141a1bc3ad1dd5bdacedbd2a2b2409f09b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Nov 2011 23:46:47 +0100 Subject: [PATCH 1408/1414] * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Fix a memory leak. (grub_util_biosdisk_get_grub_dev): Add a useful debug info. --- ChangeLog | 6 ++++++ grub-core/kern/emu/hostdisk.c | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1ce25663d..230eb0cec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): + Fix a memory leak. + (grub_util_biosdisk_get_grub_dev): Add a useful debug info. + 2011-11-12 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index ede765d83..da2cc6aa2 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -1781,6 +1781,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { struct stat st; int drive; + char *sys_disk; grub_util_info ("Looking for %s", os_dev); @@ -1800,9 +1801,13 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (grub_strcmp (os_dev, - convert_system_partition_to_system_disk (os_dev, &st)) == 0) - return make_device_name (drive, -1, -1); + sys_disk = convert_system_partition_to_system_disk (os_dev, &st); + if (grub_strcmp (os_dev, sys_disk) == 0) + { + free (sys_disk); + return make_device_name (drive, -1, -1); + } + free (sys_disk); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) if (! S_ISCHR (st.st_mode)) @@ -1914,6 +1919,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (partname == NULL) { grub_disk_close (disk); + grub_util_info ("cannot find the partition of `%s'", os_dev); grub_error (GRUB_ERR_BAD_DEVICE, "cannot find the partition of `%s'", os_dev); return 0; From a346b81c7d9e3c0ebca495f6b4f0bc49baa72712 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 00:01:06 +0100 Subject: [PATCH 1409/1414] * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore disk->partiton for safety. --- ChangeLog | 5 +++++ grub-core/partmap/gpt.c | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 230eb0cec..95aed126c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore + disk->partiton for safety. + 2011-11-12 Vladimir Serbinenko * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 73a1c3b19..c8bc52609 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -140,11 +140,17 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, const grub_partition_t p) { struct grub_gpt_partentry gptdata; + grub_partition_t p2; + p2 = disk->partition; disk->partition = p->parent; if (grub_disk_read (disk, p->offset, p->index, sizeof (gptdata), &gptdata)) - return 0; + { + disk->partition = p2; + return 0; + } + disk->partition = p2; /* If there's an embed region, it is in a dedicated partition. */ if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) From fa5aeffcc279dc7ac6a6c75c7151651c87d02322 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 00:07:08 +0100 Subject: [PATCH 1410/1414] * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. --- ChangeLog | 4 ++++ grub-core/partmap/gpt.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 95aed126c..623313b3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-12 Vladimir Serbinenko + + * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. + 2011-11-12 Vladimir Serbinenko * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index c8bc52609..049fda850 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -165,7 +165,7 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (embed_type != GRUB_EMBED_PCBIOS) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "GPT curently supports only PC-BIOS embedding"); + "GPT currently supports only PC-BIOS embedding"); err = gpt_partition_map_iterate (disk, find_usable_region); if (err) From 383ceaf0609040610c7ebc8279d958971ca96084 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 12:52:21 +0100 Subject: [PATCH 1411/1414] Fix a mismerge --- grub-core/loader/i386/pc/plan9.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 73d4eed38..6e49a34b6 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -78,8 +78,7 @@ grub_plan9_boot (void) .edi = 0, .esp = 0, .ebp = 0, - .esi = 0, - .a20 = 1 + .esi = 0 }; grub_video_set_mode ("text", 0, 0); From c30be3b694dbc95c38df9212d1f01b68c8ecdd26 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 14:48:19 +0100 Subject: [PATCH 1412/1414] Make Reed-Solomon faster by using power of generator representation of GF(256)*. * grub-core/lib/reed_solomon.c (grub_uint16_t) [TEST]: Removed. (gf_double_t): Likewise. (gf_invert): Removed. (gf_powx): New array. (gf_powx_inv): Likewise. (scratch): Move higher. (gf_reduce): Removed. (gf_mul): Use powx. (gf_invert): Likewise. (init_inverts): Replaced with ... (init_powx): ...this. All users updated. (pol_evaluate): Replace multiplications with additions. (rs_encode): Likewise. (gauss_eliminate): Call gf_invert. (grub_reed_solomon_add_redundancy): Call init_powx. (grub_reed_solomon_recover): Call init_powx unconditionally. --- ChangeLog | 22 ++++++++ grub-core/lib/reed_solomon.c | 105 +++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 623313b3c..229567014 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2011-11-13 Vladimir Serbinenko + + Make Reed-Solomon faster by using power of generator representation of + GF(256)*. + + * grub-core/lib/reed_solomon.c (grub_uint16_t) [TEST]: Removed. + (gf_double_t): Likewise. + (gf_invert): Removed. + (gf_powx): New array. + (gf_powx_inv): Likewise. + (scratch): Move higher. + (gf_reduce): Removed. + (gf_mul): Use powx. + (gf_invert): Likewise. + (init_inverts): Replaced with ... + (init_powx): ...this. All users updated. + (pol_evaluate): Replace multiplications with additions. + (rs_encode): Likewise. + (gauss_eliminate): Call gf_invert. + (grub_reed_solomon_add_redundancy): Call init_powx. + (grub_reed_solomon_recover): Call init_powx unconditionally. + 2011-11-12 Vladimir Serbinenko * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index 78d249c2f..7da5f204c 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -29,7 +29,6 @@ #ifdef TEST typedef unsigned int grub_size_t; typedef unsigned char grub_uint8_t; -typedef unsigned short grub_uint16_t; #else #include #include @@ -42,7 +41,6 @@ typedef unsigned short grub_uint16_t; #ifdef TEST typedef unsigned int grub_size_t; typedef unsigned char grub_uint8_t; -typedef unsigned short grub_uint16_t; #else #include #include @@ -53,65 +51,72 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs); #define GF_SIZE 8 typedef grub_uint8_t gf_single_t; -typedef grub_uint16_t gf_double_t; #define GF_POLYNOMIAL 0x1d #define GF_INVERT2 0x8e #if defined (STANDALONE) && !defined (TEST) -static gf_single_t * const gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000; -static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100; +static gf_single_t * const gf_powx __attribute__ ((section(".text"))) = (void *) 0x100000; +static gf_single_t * const gf_powx_inv __attribute__ ((section(".text"))) = (void *) 0x100200; + +static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100300; #else #if defined (STANDALONE) static char *scratch; #endif -static gf_single_t gf_invert[256]; +static gf_single_t gf_powx[255 * 2]; +static gf_single_t gf_powx_inv[256]; #endif #define SECTOR_SIZE 512 #define MAX_BLOCK_SIZE (200 * SECTOR_SIZE) -static gf_single_t -gf_reduce (gf_double_t a) -{ - int i; - for (i = GF_SIZE - 1; i >= 0; i--) - if (a & (1ULL << (i + GF_SIZE))) - a ^= (((gf_double_t) GF_POLYNOMIAL) << i); - return a & ((1ULL << GF_SIZE) - 1); -} - static gf_single_t gf_mul (gf_single_t a, gf_single_t b) { - gf_double_t res = 0; - int i; - for (i = 0; i < GF_SIZE; i++) - if (b & (1 << i)) - res ^= ((gf_double_t) a) << i; - return gf_reduce (res); + if (a == 0 || b == 0) + return 0; + return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]]; +} + +static inline gf_single_t +gf_invert (gf_single_t a) +{ + return gf_powx[255 - (int) gf_powx_inv[a]]; } static void -init_inverts (void) +init_powx (void) { - gf_single_t a = 1, ai = 1; - do + int i; + grub_uint8_t cur = 1; + + for (i = 0; i < 255; i++) { - a = gf_mul (a, 2); - ai = gf_mul (ai, GF_INVERT2); - gf_invert[a] = ai; + gf_powx[i] = cur; + gf_powx[i + 255] = cur; + gf_powx_inv[cur] = i; + if (cur & (1ULL << (GF_SIZE - 1))) + cur = (cur << 1) ^ GF_POLYNOMIAL; + else + cur <<= 1; } - while (a != 1); } static gf_single_t pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) { int i; - gf_single_t xn = 1, s = 0; + gf_single_t s = 0; + int log_xn = 0, log_x; + if (x == 0) + return pol[0]; + log_x = gf_powx_inv[x]; for (i = degree; i >= 0; i--) { - s ^= gf_mul (pol[i], xn); - xn = gf_mul (x, xn); + if (pol[i]) + s ^= gf_powx[(int) gf_powx_inv[pol[i]] + log_xn]; + log_xn += log_x; + if (log_xn >= ((1 << GF_SIZE) - 1)) + log_xn -= ((1 << GF_SIZE) - 1); } return s; } @@ -120,7 +125,7 @@ pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x) static void rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) { - gf_single_t *rs_polynomial, a = 1; + gf_single_t *rs_polynomial; int i, j; gf_single_t *m; m = xmalloc ((s + rs) * sizeof (gf_single_t)); @@ -132,16 +137,14 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) /* Multiply with X - a^r */ for (j = 0; j < rs; j++) { - if (a & (1 << (GF_SIZE - 1))) - { - a <<= 1; - a ^= GF_POLYNOMIAL; - } - else - a <<= 1; for (i = 0; i < rs; i++) - rs_polynomial[i] = rs_polynomial[i + 1] ^ gf_mul (a, rs_polynomial[i]); - rs_polynomial[rs] = gf_mul (a, rs_polynomial[rs]); + if (rs_polynomial[i]) + rs_polynomial[i] = (rs_polynomial[i + 1] + ^ gf_powx[j + (int) gf_powx_inv[rs_polynomial[i]]]); + else + rs_polynomial[i] = rs_polynomial[i + 1]; + if (rs_polynomial[rs]) + rs_polynomial[rs] = gf_powx[j + (int) gf_powx_inv[rs_polynomial[rs]]]; } for (j = 0; j < s; j++) if (m[j]) @@ -190,7 +193,7 @@ gauss_eliminate (gf_single_t *eq, int n, int m, int *chosen) if (nzidx == m) continue; chosen[i] = nzidx; - r = gf_invert [eq[i * (m + 1) + nzidx]]; + r = gf_invert (eq[i * (m + 1) + nzidx]); for (j = 0; j < m + 1; j++) eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r); for (j = i + 1; j < n; j++) @@ -437,6 +440,8 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, if (!rs) return; + init_powx (); + while (s > 0) { grub_size_t tt; @@ -468,9 +473,7 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) if (!rs) return; -#if defined (STANDALONE) - init_inverts (); -#endif + init_powx (); while (s > 0) { @@ -500,12 +503,15 @@ main (int argc, char **argv) grub_size_t s, rs; char *buf; + grub_memset (gf_powx, 0xee, sizeof (gf_powx)); + grub_memset (gf_powx_inv, 0xdd, sizeof (gf_powx_inv)); + #ifdef STANDALONE scratch = xmalloc (1048576); #endif #ifndef STANDALONE - init_inverts (); + init_powx (); #endif in = fopen ("tst.bin", "rb"); @@ -514,7 +520,7 @@ main (int argc, char **argv) fseek (in, 0, SEEK_END); s = ftell (in); fseek (in, 0, SEEK_SET); - rs = s / 3; + rs = 0x7007; buf = xmalloc (s + rs + SECTOR_SIZE); fread (buf, 1, s, in); fclose (in); @@ -524,8 +530,9 @@ main (int argc, char **argv) out = fopen ("tst_rs.bin", "wb"); fwrite (buf, 1, s + rs, out); fclose (out); - +#if 0 grub_memset (buf + 512 * 15, 0, 512); +#endif out = fopen ("tst_dam.bin", "wb"); fwrite (buf, 1, s + rs, out); From bc108a4a8a4d20dd122cee786befc99bcbe48735 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 13 Nov 2011 19:53:12 +0100 Subject: [PATCH 1413/1414] * util/grub-mount.c (argp_parser): Accept relative pathes. * util/grub-fstest.c (argp_parser): Likewise. --- ChangeLog | 5 +++++ util/grub-fstest.c | 7 +------ util/grub-mount.c | 7 +------ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c3ccb631..d3c48339e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-13 Vladimir Serbinenko + + * util/grub-mount.c (argp_parser): Accept relative pathes. + * util/grub-fstest.c (argp_parser): Likewise. + 2011-11-13 Vladimir Serbinenko Plan9 support. diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c9f24ff08..886155fe2 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -562,14 +562,9 @@ argp_parser (int key, char *arg, struct argp_state *state) if (args_count < num_disks) { - if (arg[0] != '/') - { - fprintf (stderr, "%s", _("Must use absolute path.\n")); - argp_usage (state); - } if (args_count == 0) images = xmalloc (num_disks * sizeof (images[0])); - images[args_count] = xstrdup (arg); + images[args_count] = canonicalize_file_name (arg); args_count++; return 0; } diff --git a/util/grub-mount.c b/util/grub-mount.c index a4be21738..da7d604a2 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -489,13 +489,8 @@ argp_parser (int key, char *arg, struct argp_state *state) return 0; } - if (arg[0] != '/') - { - fprintf (stderr, "%s", _("Must use absolute path.\n")); - argp_usage (state); - } images = xrealloc (images, (num_disks + 1) * sizeof (images[0])); - images[num_disks] = xstrdup (arg); + images[num_disks] = canonicalize_file_name (arg); num_disks++; return 0; From 2536cf64633e7334d1c04bc865907feee5128fdb Mon Sep 17 00:00:00 2001 From: Lubomir Kundrak Date: Sun, 13 Nov 2011 22:59:46 +0100 Subject: [PATCH 1414/1414] Add facility to debug GRUB with gdb under qemu. * grub-core/gdb_grub.in: New file. * grub-core/gmodule.pl.in: Likewise. * grub-core/Makefile.core.def (gmodule.pl): New script. (gdb_grub): Likewise. --- ChangeLog | 9 ++++ grub-core/Makefile.core.def | 12 ++++++ grub-core/gdb_grub.in | 82 +++++++++++++++++++++++++++++++++++++ grub-core/gmodule.pl.in | 30 ++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 grub-core/gdb_grub.in create mode 100644 grub-core/gmodule.pl.in diff --git a/ChangeLog b/ChangeLog index d3c48339e..22421a715 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-11-13 Lubomir Kundrak + + Add facility to debug GRUB with gdb under qemu. + + * grub-core/gdb_grub.in: New file. + * grub-core/gmodule.pl.in: Likewise. + * grub-core/Makefile.core.def (gmodule.pl): New script. + (gdb_grub): Likewise. + 2011-11-13 Vladimir Serbinenko * util/grub-mount.c (argp_parser): Accept relative pathes. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index fc0472d32..cae79b381 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -18,6 +18,18 @@ script = { common = modinfo.sh.in; }; +script = { + installdir = noinst; + name = gmodule.pl; + common = gmodule.pl.in; +}; + +script = { + installdir = noinst; + name = gdb_grub; + common = gdb_grub.in; +}; + kernel = { name = kernel; diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in new file mode 100644 index 000000000..4a55233da --- /dev/null +++ b/grub-core/gdb_grub.in @@ -0,0 +1,82 @@ +### +### Load debuging information about GNU GRUB 2 modules into GDB +### automatically. Needs readelf, Perl and gmodule.pl script +### +### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $ +### Lubomir Kundrak +### + +# Add section numbers and addresses to .segments.tmp +define dump_module_sections + set $mod = $arg0 + + # FIXME: save logging status + set logging file .segments.tmp + set logging redirect on + set logging overwrite off + set logging on + + printf "%s", $mod->name + set $segment = $mod->segment + while ($segment) + printf " %i 0x%x", $segment->section, $segment->addr + set $segment = $segment->next + end + printf "\n" + + set logging off + # FIXME: restore logging status +end +document dump_module_sections + Gather information about module whose mod structure was + given for use with match_and_load_symbols +end + +# Generate and execute GDB commands and delete temporary files +# afterwards +define match_and_load_symbols + shell perl gmodule.pl <.segments.tmp >.loadsym.gdb + source .loadsym.gdb + shell rm -f .segments.tmp .loadsym.gdb +end +document match_and_load_symbols + Launch script, that matches section names with information + generated by dump_module_sections and load debugging info + apropriately +end + +### + +define load_module + dump_module_sections $arg0 + match_and_load_symbols +end +document load_module + Load debugging information for module given as argument. +end + +define load_all_modules + set $this = grub_dl_head + while ($this != 0) + dump_module_sections $this->mod + set $this = $this->next + end + match_and_load_symbols +end +document load_all_modules + Load debugging information for all loaded modules. +end + +### + +set confirm off +file kernel.exec +target remote :1234 + +# inform when module is loaded +break grub_dl_add +commands + silent + load_module mod + cont +end diff --git a/grub-core/gmodule.pl.in b/grub-core/gmodule.pl.in new file mode 100644 index 000000000..6739a6f1c --- /dev/null +++ b/grub-core/gmodule.pl.in @@ -0,0 +1,30 @@ +### +### Generate GDB commands, that load symbols for specified module, +### with proper section relocations. See .gdbinit +### +### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $ +### Lubomir Kundrak +### + +use strict; + +while (<>) { + my ($name, %sections) = split; + + print "add-symbol-file $name.module"; + + open (READELF, "readelf -S $name.mod |") or die; + while () { + /\[\s*(\d+)\]\s+(\.\S+)/ or next; + + if ($2 eq '.text') { + print " $sections{$1}"; + next; + } + + print " -s $2 $sections{$1}" + if ($sections{$1} ne '0x0'); + }; + close (READELF); + print "\n"; +}